在 Nodejs 中 ES Modules 使用入门讲解

本周 2020-05-26,Nodejs v12.17.0 LTS 版发布,去掉 --experimental-modules 标志。

虽然已在最新的 LTS v12.17.0 中支持,但是目前仍处于  Stability: 1 - Experimental 实验阶段,如果是在生产环境使用该功能,还应保持谨慎,如果在测试环境可以安装 n install v12.17.0 进行尝试。

删除标志也是将 ESM 变为稳定性而迈出的重要一步,根据 Nodejs 官方的发布说明,有望在今年下半年(10 月左右)删除 Nodejs 12 中的警告,届时 Node 14 将会成为 LTS

ES Modules 基本使用

通过声明 .mjs 后缀的文件或在 package.json 里指定 type 为 module 两种方式使用 ES Modules,下面分别看下两种的使用方式:

使用方式一

构建如下目录结构

├── caculator.js
├── index.js
└── package.json

package.json

重点是将 type 设置为 module 来支持 ES Modules

{
  "name": "esm-project",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",
  ...
}

caculator.js

export function add (a, b) {
  return a + b;
};

index.js

import { add } from './caculator.js';

console.log(add(4, 2)); // 6

运行

与当前的 v14.3.0 不同的是在 v12.17.0 中使用 ESM 运行时仍然会触发一个 experimental 警告信息。

$ n run v12.17.0 index.js
(node:6827) ExperimentalWarning: The ESM module loader is experimental.
6

$ n run v14.3.0 index.js
6

使用方式二

通过指定文件扩展名为 .mjs 与 CommonJS 模块进行区分,这样是不需要在 package.json 中指定 type 为 module。

在上述例子基础上修改文件扩展名即可。

├── caculator.mjs
├── index.mjs

运行

$ n run v12.17.0 index.mjs
(node:6827) ExperimentalWarning: The ESM module loader is experimental.
6

模块导入导出的几种方式

export 导出

export 用于对外输出模块,可导出常量、函数、文件等,相当于定义了对外的接口,两种导出方式:

  • export: 使用 export 方式导出的,导入时要加上 {} 需预先知道要加载的变量名,在一个文件中可以使用多次。

  • export default: 为模块指定默认输出,这样加载时就不需要知道所加载的模块变量名,一个文件中仅可使用一次。

// caculator.js
export function add (a, b) {
  return a + b;
};

export function subtract (a, b) {
  return a - b;
}

const caculator = {
  add,
  subtract,
}

export default caculator;

import 导入

import 语句用于导入另一个模块导出的绑定,三种导入方式:

  • 导入默认值:导入在 export default 定义的默认接口。

  • as 别名导入:在导入时可以重命名在 export 中定义的接口。

  • 单个或多个导入:根据需要导入 export 定一个的一个或多个接口。

import { add } from './caculator.js';
import caculator from './caculator.js';
import * as caculatorAs from './caculator.js';

add(4, 2)
caculator.subtract(4, 2);
caculatorAs.subtract(4, 2);

import 的动态导入

可以像调用函数一样动态的导入模块,它将返回一个 Promise,但是这种方式需要 Top-Level await 支持,如果你不知道 Top-Level await 是什么可以看下这篇文章 Nodejs v14.3.0 发布支持顶级 Await 和 REPL 增强功能

现在我们有如下导出模块 my-module.js:

const sleep = (value, ms) => new Promise(resolve => setTimeout(() => resolve(value), ms));

export const hello = await sleep('Hello', 1000);
export const node = await sleep('Nodejs', 2000);
export default function() {
  return 'this is a module';
}

在 index.js 中可以像如下形式进行动态导入:

console.log('Start loading module...')
const myModule = await import('./my-module.js');
console.log('Output after 3000 ms.')
console.log(myModule.hello);
console.log(myModule.node);
console.log(myModule.default());

运行

$ n run v14.3.0 --experimental_top_level_await index.js
Start loading module...
Output after 3000 ms.
Hello
Nodejs
this is a module

本周 Nodejs v12.17.0 LTS 版发布,在这之前如果我们使用 ES Modules 还需要加上标志 --experimental-modules,而在本次版本发布取消了这个标志,本文也是对在 Nodejs 中使用 ES Modules 进行了入门讲解,后续也会进行更深入的研究分享,希望看完你能有所收获。

Reference

  • nodejs.org/en/blog/release/v12.17.0/

  • nodejs.org/dist/latest-v14.x/docs/api/esm.html

作者简介:五月君,Nodejs Developer,慕课网认证作者,热爱技术、喜欢分享的 90 后青年,欢迎关注 Github 开源项目 https://www.nodejs.red

敬请关注「Nodejs技术栈」微信公众号,获取优质文章

往期精彩回顾

Nodejs v14.3.0 发布支持顶级 Await 和 REPL 增强功能

Nodejs Stream pipe 的使用与实现原理分析

Nodejs 中基于 Stream 的多文件合并实现

Node.js util.promisify 实现源码解析

深入 Nodejs 源码探究 CPU 信息的获取与利用率计算

Nodejs 进阶:解答 Cluster 模块的几个疑问

多维度分析 Express、Koa 之间的区别

Node.js 服务 Docker 容器化应用实践

JavaScript 浮点数之迷:大数危机

Node.js 是什么?我为什么选择它?

TypeScript 面向对象程序设计(OOP)

不容错过的 Node.js 项目架构

Node.js 内存管理和 V8 垃圾回收机制

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值