admin管理员组

文章数量:1624797

之前一直以为浏览器和 Node.js 都是不支持 ES Module 的,所以需要借助 Webpack 打包。

浏览器中的 ESM

随着 Snowpack 、Vite 为代表的 bundless 构建工具的兴起,浏览器 ESM 开始被越来越多人熟知。Chrome 63 开始就支持了浏览器原生 ESM :


使用浏览器原生 ESM ,需要在 script 标签上加 type="module" 即可开启:

<script type="module">
import { logger } from "./utils.js";

logger("2333");
</script>

utils.js 内容如下:

export function logger(param) {
  console.log(param);
}

Node.js 中的 ESM

现在很多人写 Node.js 还在用 CommonJS ,实际上 Node.js 也是支持 ESM 的。如果你看过一些 npm 包的源码,你可能会看到一些 .mjs.cjs 的文件,这实际上就和 Node.js 的模块规范有关,下面来解释下。

Node.js 默认支持 CommonJS ,如果要使用 ES6 模块则需要将文件后缀名改为 .mjs ,可以在里面放心使用 ESM 。如果不希望将后缀改为 .mjs ,则需要在项目的 package.json 中指定 type 字段为 module

{
	"type": "module",
}

在修改 package.json 之后,如果还要使用 CommonJS 模块,则需要将文件后缀名改为 .cjs

总结为一句话:.mjs 文件总是以 ES6 模块加载,.cjs 文件总是以 CommonJS 模块加载,.js 文件的加载取决于 package.json 里面 type 字段的设置。如果没有 type 字段,或者的 type 字段为 commonjs ,则 .js 脚本会被解释成 CommonJS 模块。

另外在 Node.js 中使用 ESM ,引入的模块一定要带上文件后缀,这点不是很友好:

import { logger } from "./utils.js";

logger("2333");

在 Webpack 等打包构建工具中可以省略后缀

本人用 Node.js 写了一个简单的 http 服务,无论内置模块还是自定义模块,都可以使用 ESM :

import http from "http";
import { logger } from "./utils.js";

const app = http.createServer((req, res) => {
  req.pipe(res);
});

app.listen(3000, () => {
  logger("Server running on: http://localhost:3000");
});

参考:

Node.js 如何处理 ES6 模块

本文标签: 浏览器nodejsesModule