node支持ES module (import) 的三种方式

3,515 阅读3分钟

作为前端开发者,在日常开发中,常常会使用 import 语法引入模块。但是在大多人前端开发者印象中, Node 默认是不支持 importexport 的,更多是使用requiremodule.exportsexports.xxx 来进行文件导入导出。


注意:

本次实验过程中,运行 test.js (入口文件)文件并不是直接使用 node test.js,而是使用自定义命令 use-import-in-node.

具体如下:

  1. 目录结构

image.png

  1. package.json 中添加 bin属性 image.png

  2. test.js 第一行添加 #!/usr/bin/env node 参考文章image.png

  3. 运行 npm link

  4. 就可以全局使用 use-import-in-node 命令了,和直接使用 npm 一样。直接运行 use-import-in-node 就等同于 node test.js参考文章

image.png 关于自定义命令为什么可以直接执行,不理解的可以看我的另一篇文章,从操作系统命令的使用层次来理解脚手架(vue-cli)命令(vue) 如果不想使用这种方式,全程使用node(babel-node)执行 test.js文件也可


一、通过 babel-node

1. 安装 babel-node

babel-node 命令并非独立安装,在 Babel 7.0 以前,通过安装 babel-cli 包获得。而在 Babel 7.0 以后,babel 的模块被被拆分,需要安装 @babel/core @babel/node 两个包来获取。

  • babel 7.x 以前的写法
 npm i -g babel-cli
  • babel 7.x 以后的写法
 npm i -g @babel/core @babel/node

2. 安装 presets 并配置 .babelrc 文件

npm i @babel/preset-env -g

image.png

提示:由于我babel有关的包都是全局安装的,所以.babelrc所在目录下没有package.json 文件

3. 文件结构和代码

image.png

4. 修改test.js执行环境

image.png 从图中可以看到,运行 use-import-in-nodebabel-node test.js 效果一样


二、使用webpack

1. 安装webpack相关包

npm i webpack  webpack-cli -g

2. 配置webpack

(1)配置打包命令

image.png 我们最终需要的是打包后的代码。

(2)配置webpack.config.js

  1. package.json 同级目录下新建 webpack.config.js 文件

  2. 具体配置很简单,如下图 image.png 提示:target默认值是 web , 如果你要用import导入node内置库,比如path、fs等,需要设置为node

  3. 运行 npm run build 生成打包文件

image.png 注意在哪里执行的打包命令

3. 修改test.js执行环境并执行

image.png 从图中可以看到,运行 use-import-in-nodenode test.js 效果一样 注意:这里require的文件是打包后的文件/dist


三、node原生支持

其实 node 原生也是支持 es module ,就是 importexport 来导入导出的。其中有几个需要注意的点:

  • 所有的文件名后缀需要改成.mjs
  • 导入文件路径的时候需要输入完整的文件名,不能省略.mjs。(省略.mjs后缀名后默认导入js文件,这是会报找不到文件的错误)
  • 所有的导入导出都必须用ES module规范,使用 ComonJs会报错
  • 有些东西,例如__dirname__filename无法使用(这是在调用require的时候注入的)

但是在node版本v12.0.0 之前,是不支持直接用node执行.mjs 文件的,需要加上·--experimental-modules 选项,因为这时还是一个实验性的功能,所以还会爆出提示信息;在node版本v12.0.0 之后,可以直接用node执行.mjs 文件。(具体见下方截图)

1. demo代码

image.png

2. 运行 test.mjs文件

(1)node版本大于等于v12.0.0

image.png

(2)node版本小于v12.0.0

image.png


附上源码链接

github的master分支