如何在ES6模块节点应用程序中包含commonjs模块



我有一个节点应用程序,我想在标准ES6模块格式中使用它(即package.json中的"type": "module",并始终使用importexport(,而无需向下转换到ES5。但我想利用一些较旧的库,如使用CommonJS/require格式的express和socket.io。我有什么选择(截至2020年5月,节点12.16.3(将CommonJS模块组合到ES6应用程序中?

使用CommonJS模块非常简单。您只能从CommonJS模块进行default导出。

import packageMain from 'commonjs-package'; // Works
import { method } from 'commonjs-package'; // Errors

这意味着所有commonjs导出都将存在于packageMain对象上,并且您需要dot进入packageMain对象以获取所需内容。

packageMain.method1()

更多信息在官方nodejs文档

自节点13.10以来,还有另一个选项,最具前瞻性的选项:

在您想要使用的CommonJS库的repo中提交一个问题,说服维护人员使用条件导出发布双包(ESM+CommonJS(。

对于用TypeScript编写的库,生成双包很容易,不需要Babel或rollup或任何其他工具。以下是我在当地iso dt:中的做法

package.json:的相关部分

{
"name": "local-iso-dt",
"version": "3.1.0",
"description": "...",
"type": "commonjs",
"exports": {
"node": {
"import": "./index.mjs",
"require": "./index.js"
},
"default": "./index.mjs"
},
"main": "index.js",
"files": [
"index.ts",
"index.mjs",
"index.js"
],
"scripts": {
"clean": "rm index*.js index.mjs",
"prepublishOnly:cjs": "tsc index.ts --esModuleInterop --removeComments",
"prepublishOnly:esm": "tsc index.ts -t ES2015 --types node && mv index.js index.mjs",
"prepublishOnly": "npm run prepublishOnly:esm; npm run prepublishOnly:cjs"
},
"devDependencies": {
"typescript": "^4.0.2"
},
}

prepublishOnly:esm手动重命名输出,因为TypeScript还不能直接生成.mjs输出,并且--outFile不能与ES模块一起工作。

CCD_ 11块具有";条件导出,使使用ES模块传输的TypeScript代码能够使用命名导入。TypeScript不直接支持.mjs输入文件。

这个简单的模块不需要tsconfig.json

Ivan的回答很有帮助,但我也应该注意,因为我使用的是节点12.16.3,所以我还需要在package.json:中将--experimental-modules标志添加到我的启动脚本中

"type": "module",
"scripts": {
"start": "node --experimental-modules --experimental-json-modules server.mjs",
}
  • "type": "module"告诉节点您应该使用ES6模块
  • .mjs的文件名进一步表明我们正在使用一个模块JavaScript文件
  • --experimental-modules--experimental-json-modules允许您在节点版本12中使用import

然后我可以做import express from 'express';之类的事情(其中expression 4.17.1是一个CommonJS模块(,它运行得很好。

确保有问题的模块有一个index.js,它将您想要的代码导出到importrequire

package.json中,在dependencies属性下添加:

"myCustomModule":"file:./path/to/myCustomModule"

完成此操作后,运行npm install

完成后,查看项目的node_modules/,您将看到一个名为myCustomModule的目录。

现在,在任何项目文件中,您都可以像使用任何其他mode_module一样使用importrequire代码