我有一个node应用程序,我想使用标准的ES6模块格式(即package.json中的"type": "module",并使用import和export),而不需要向下编译到ES 5。但是我想利用一些旧的库,如express和socket.io,它们使用CommonJS /require。在将CommonJS模块组合到ES6应用程序中时,我有哪些选择(截至2020年5月,Node 12.16.3)?
package.json
"type": "module"
import
export
require
ddrv8njm1#
使用CommonJS模块非常简单。您只能从CommonJS模块进行default导出。
default
import packageMain from 'commonjs-package'; // Works import { method } from 'commonjs-package'; // Errors
字符串这意味着所有commonjs导出都将存在于packageMain对象上,您需要 dot 到packageMain对象中以获取您需要的内容。
packageMain
packageMain.method1()
型更多信息请参阅官方nodejs文档
ix0qys7i2#
自节点13.10以来,还有另一个选择,最具前瞻性的选择:在您想要使用的CommonJS库的repo中提交一个问题,persuading the maintainers发布dual packages(ESM + CommonJS),使用条件导出。对于用TypeScript编写的库,生成双包很容易,不需要Babel或Rollup或任何其他工具。下面是我在local-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 can't yet generate .mjs output directly和--outFile不适用于ES模块。exports块具有“条件导出,允许使用ES模块编译TypeScript代码,以使用命名导入。TypeScript doesn't directly support .mjs input files。这个简单的模块不需要tsconfig.json。
prepublishOnly:esm
.mjs
--outFile
exports
tsconfig.json
8i9zcol23#
Ivan的回答很有帮助,但我还应该注意,因为我使用的是node 12.16.3,所以我还需要将--experimental-modules标志添加到package.json中的开始脚本中:
--experimental-modules
"type": "module", "scripts": { "start": "node --experimental-modules --experimental-json-modules server.mjs", }
字符串
--experimental-json-modules
然后我就可以做像import express from 'express';(express 4.17.1是一个CommonJS模块)这样的事情了,它工作得很好。
import express from 'express';
u5i3ibmn4#
确保有问题的模块有一个index.js,可以将您想要的代码导出到import或require。在package.json中,在dependencies属性下添加:
index.js
dependencies
"myCustomModule":"file:./path/to/myCustomModule"
字符串完成此操作后,运行npm install。完成后,查看项目的node_modules/,您将看到一个名为myCustomModule的目录。现在,在任何项目文件中,您都可以像编写任何其他mode_module一样编写import或require
npm install
node_modules/
myCustomModule
mode_module
4条答案
按热度按时间ddrv8njm1#
使用CommonJS模块非常简单。您只能从CommonJS模块进行
default
导出。字符串
这意味着所有commonjs导出都将存在于
packageMain
对象上,您需要 dot 到packageMain对象中以获取您需要的内容。型
更多信息请参阅官方nodejs文档
ix0qys7i2#
自节点13.10以来,还有另一个选择,最具前瞻性的选择:
在您想要使用的CommonJS库的repo中提交一个问题,persuading the maintainers发布dual packages(ESM + CommonJS),使用条件导出。
对于用TypeScript编写的库,生成双包很容易,不需要Babel或Rollup或任何其他工具。下面是我在local-iso-dt中的操作:
package.json相关部分:
字符串
prepublishOnly:esm
手动重命名输出,因为TypeScript can't yet generate.mjs
output directly和--outFile
不适用于ES模块。exports
块具有“条件导出,允许使用ES模块编译TypeScript代码,以使用命名导入。TypeScript doesn't directly support .mjs input files。这个简单的模块不需要
tsconfig.json
。8i9zcol23#
Ivan的回答很有帮助,但我还应该注意,因为我使用的是node 12.16.3,所以我还需要将
--experimental-modules
标志添加到package.json
中的开始脚本中:字符串
"type": "module"
告诉node您应该使用ES6模块.mjs
进一步表明我们正在使用一个模块JavaScript文件--experimental-modules
和--experimental-json-modules
允许您在节点版本12中使用import
。然后我就可以做像
import express from 'express';
(express 4.17.1是一个CommonJS模块)这样的事情了,它工作得很好。u5i3ibmn4#
确保有问题的模块有一个
index.js
,可以将您想要的代码导出到import
或require
。在
package.json
中,在dependencies
属性下添加:字符串
完成此操作后,运行
npm install
。完成后,查看项目的
node_modules/
,您将看到一个名为myCustomModule
的目录。现在,在任何项目文件中,您都可以像编写任何其他
mode_module
一样编写import
或require