如何将 TS 模块导入或要求到 CommonJS 文件中?

Posted

技术标签:

【中文标题】如何将 TS 模块导入或要求到 CommonJS 文件中?【英文标题】:How to import or require a TS-module into CommonJS file? 【发布时间】:2018-09-25 20:29:03 【问题描述】:

由于某种原因,我的一些模块必须是js 文件。

我将import ts 模块放入我的js 文件中,如下所示:

resolver.js:

import  Message  from '../../connectors/message';

// console.log('Message: ', Message);

const resolver = 
  Query: 
    sendMessage: (root, args, ctx) => 
      console.log(args, ctx);
      return Message.send('1', 'message');
    
  
;

export  resolver ;

message.ts

const Message = 
  send(id, type) 
    return Promise.resolve(
      recipient_id: '123',
      message_id: '122'
    );
  
;

export  Message ;

我使用webpackawesome-typescript-loader 来编译我的.ts 文件。

这是我的tsconfig.json


  "compilerOptions": 
    "target": "es6",
    "lib": ["es6", "esnext"],
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "declaration": false,
    "outDir": "dist",
    "typeRoots": ["node_modules/@types"]
  ,
  "files": ["src/main.ts"],
  "exclude": ["node_modules"]

webpack.config.js

var nodeExternals = require('webpack-node-externals');
var webpack = require('webpack');
var path = require('path');
var fs = require('fs');

/* helper function to get into build directory */
var distPath = function(name) 
  if (undefined === name) 
    return path.join('dist');
  

  return path.join('dist', name);
;

var webpack_opts = 
  entry: './src/main.ts',
  target: 'node',
  output: 
    filename: distPath('main.js'),
    libraryTarget: 'commonjs2'
  ,
  resolve: 
    extensions: ['.ts', '.js'],
    modules: ['node_modules', 'src']
  ,
  plugins: [
    new webpack.LoaderOptionsPlugin(
      options: 
        test: /\.ts$/,
        ts: 
          compiler: 'typescript',
          configFileName: 'tsconfig.json'
        ,
        tslint: 
          emitErrors: true,
          failOnHint: true
        
      
    )
  ],
  devtool: 'source-map',
  module: 
    loaders: [
      
        test: /\.ts$/,
        loaders: 'awesome-typescript-loader'
      
    ]
  ,
  externals: [nodeExternals()]
;

module.exports = webpack_opts;

但我得到了这个错误:

(function (exports, require, module, __filename, __dirname)  import  Message  from '../../connectors/message';
                                                              ^^^^^^

SyntaxError: Unexpected token import
    at new Script (vm.js:51:7)
    at createScript (vm.js:136:10)
    at Object.runInThisContext (vm.js:197:10)
    at Module._compile (internal/modules/cjs/loader.js:618:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)

如何解决?

-- 更新 v1--

我尝试将它与require一起使用

// import  Message  from '../../connectors/message';

const  Message  = require('../../connectors/message');

console.log('Message: ', Message);

const resolver = 
  Query: 
    sendMessage: (root, args, ctx) => 
      console.log(args, ctx);
      return Message.send('1', 'message');
    
  
;

export  resolver ;

但我还是报错:

internal/modules/cjs/loader.js:550
    throw err;
    ^

Error: Cannot find module '../../connectors/message'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:548:15)
    at Function.Module._load (internal/modules/cjs/loader.js:475:25)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)
    at Object.<anonymous> (/Users/ldu020/workspace/workplace-adapter-graphql/src/graphql/modules/messages/resolver.js:3:21)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)

-- 更新 v2--

我将.ts文件扩展名添加到路径:

const  Message  = require('../../connectors/message.ts');

还是报错:

    export  Message ;
^^^^^^

SyntaxError: Unexpected token export
    at new Script (vm.js:51:7)
    at createScript (vm.js:136:10)
    at Object.runInThisContext (vm.js:197:10)
    at Module._compile (internal/modules/cjs/loader.js:618:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)

更新3:添加package.json

"devDependencies": 
    "@types/faker": "^4.1.4",
    "@types/jest": "^19.2.4",
    "@types/node": "^7.10.0",
    "babel-cli": "^6.26.0",
    "faker": "^4.1.0",
    "jest": "^20.0.4",
    "ts-jest": "^20.0.6",
    "ts-node": "^3.2.0",
    "tslint": "^5.11.0",
    "typescript": "^2.9.2"
  ,

【问题讨论】:

只有const Message = require('../../connectors/message')(而不是const Message)怎么样? @JeremyThille 的错误与 update v1 相同 我无法测试这个,因为我没有旧的节点版本,所以我不会写答案。但我很确定你只需要将你的 js 编译成你的节点版本可以用 babel-loader 理解的东西。无需更改您的代码。 (或者只是更新节点)github.com/babel/babel-loader 你怎么知道这是旧版本? @novaline 实际上是的,你的 Node 版本是什么? @JeremyThille node -v v9.11.1 【参考方案1】:

尝试使用require('../../connectors/message')

【讨论】:

【参考方案2】:

您的节点版本不支持import。使用 require 代替:

var Message = require('./path').Message;

--更新-- 由于您正在尝试导入 .ts 文件,因此您需要将其写入路径中。像这样:require('./path.ts');

【讨论】:

我更新了问题,请再看看。谢谢。 @slideshowp2 你有没有得到解决方案。我有同样的问题。请分享解决方案。谢谢

以上是关于如何将 TS 模块导入或要求到 CommonJS 文件中?的主要内容,如果未能解决你的问题,请参考以下文章

TS模块化

如何在浏览器中“要求”CommonJS 模块? [关闭]

Jest,ts-jest,带有 ES 模块导入的打字稿:找不到模块

将 CommonJS 默认导出导入为命名导出/无法加载 ES 模块

lodash如何允许导入单个模块?

AMDCMD和CommonJS规范(转)