支持情况

8 或 10版本的 Node.js 对 ES Modules 的支持还是处于实验阶段,要在 Node 环境下使用 ES Modules 需要做一些步骤。

  1. 将文件的扩展名由 .js 改为 .mjs。
  2. 启动时需要额外添加 --experimental-modules 参数。 ```javascript // module.mjs 文件 export const foo = ‘hello’ export const bar = ‘world’

// index.mjs 文件 import { foo, bar } from ‘./module.mjs’

console.log(foo, bar)

// 此时我们也可以通过 esm 加载内置模块了 import fs from ‘fs’ fs.writeFileSync(‘./foo.txt’, ‘es module working’)

// // 也可以直接提取模块内的成员,内置模块兼容了 ESM 的提取成员方式 import { writeFileSync } from ‘fs’ writeFileSync(‘./bar.txt’, ‘es module working’)

// 对于第三方的 NPM 模块也可以通过 esm 加载 import from ‘lodash’ console.info(.camelCase(‘ES Module’))

// 不支持,因为第三方模块都是导出默认成员 import { camelCase } from ‘lodash’ console.log(camelCase(‘ES Module’))

  1. <a name="vF4gP"></a>
  2. # 与 CommonJS 交互
  3. - ES Modules 可以导入 CommonJS 模块。
  4. - 原生 Node 环境下,CommonJS 不可以导入 ES Modules 模块。
  5. - 在 ES Modules 引用时,CommonJS 始终只会导出一个默认成员。
  6. - ES Modules 中 import 不是解构导出对象。
  7. <a name="XMQxw"></a>
  8. # 与 CommonJS 的差异
  9. ESM 没有 CommonJS 的那些模块全局成员了。
  10. ```javascript
  11. // CommonJS
  12. // 加载模块函数
  13. console.log(require)
  14. // 模块对象
  15. console.log(module)
  16. // 导出对象别名
  17. console.log(exports)
  18. // 当前文件的绝对路径
  19. console.log(__filename)
  20. // 当前文件所在目录
  21. console.log(__dirname)
  22. // ESM 中,import 和 export 可以代替 require、module、exports
  23. // __filename 和 __dirname 通过 import 对象的 meta 属性获取
  24. // 通过 url 模块的 fileURLToPath 方法转换为路径
  25. import { fileURLToPath } from 'url'
  26. import { dirname } from 'path'
  27. const __filename = fileURLToPath(import.meta.url)
  28. const __dirname = dirname(__filename)
  29. console.log(__filename)
  30. console.log(__dirname)

v12

node.js v12可以通过在 package.json 中将 “type” 字段 设置为 “module”,此时就不需要修改文件扩展名为 .mjs。但是这时如果需要继续使用 CommonJS,则需要把文件扩展名改为 .cjs。

Babel 兼容方案

在早期 Node 版本中, 可以在运行时通过 Babel 的插件将 ESM 转换成 CommonJS。
安装以下依赖:

  1. {
  2. "devDependencies": {
  3. "@babel/core": "^7.6.0",
  4. "@babel/node": "^7.6.1",
  5. "@babel/plugin-transform-modules-commonjs": "^7.6.0"
  6. }
  7. }

在 .babelrc 中加载转换插件:

  1. {
  2. "plugins": [
  3. "@babel/plugin-transform-modules-commonjs"
  4. ]
  5. }
  1. 通过 "yarn babel-node 文件名.js" 即可使用 ESM 标准。