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

Luk*_*uke 17 javascript commonjs node.js ecmascript-6 es6-modules

我有一个节点应用程序,我想以标准 ES6 模块格式(即,"type": "module"package.json, 和 using中)使用它importexport而无需转换为 ES5。但是我想利用一些较旧的库,例如使用 CommonJS /require格式的 express 和 socket.io 。将 CommonJS 模块组合到 ES6 应用程序中的选项是什么(截至 5/2020,Node 12.16.3)?

Iva*_* V. 15

Working with CommonJS modules is pretty straight forward. You can only do default exports from CommonJS modules.

import packageMain from 'commonjs-package'; // Works
import { method } from 'commonjs-package'; // Errors
Run Code Online (Sandbox Code Playgroud)

This means that all commonjs exports will live on the packageMain object, and you need to dot in to the packageMain object to pickup what you need.

packageMain.method1()
Run Code Online (Sandbox Code Playgroud)

More info in the official nodejs docs

  • 从nodejs `v14.13.0` 开始,[可以使用](https://github.com/nodejs/node/pull/35249) 合格的 CJS 模块导入。 (5认同)

Dan*_*scu 10

从 Node 13.10 开始,还有另一种选择,也是最有前瞻性的一种:

在您想要使用的 CommonJS 库的 repo 中提出问题,说服维护者发布双包(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"
  },
}
Run Code Online (Sandbox Code Playgroud)

prepublishOnly:esm手动重命名输出,因为TypeScript 还不能.mjs直接生成输出并且--outFile不适用于 ES 模块。

exports块具有“条件导出,允许使用 ES 模块转译 TypeScript 代码,以使用命名导入。TypeScript 不直接支持 .mjs 输入文件

没有tsconfig.json必要为这个简单的模块。


Cli*_*rar 1

确保相关模块具有index.js导出您想要的代码的importrequire

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

"myCustomModule":"file:./path/to/myCustomModule"
Run Code Online (Sandbox Code Playgroud)

完成此操作后npm install

完成后,查看项目内部node_modules/,您将看到一个名为myCustomModule.

现在,在任何项目文件中,您都可以像其他任何项目一样import编写代码requiremode_module