ES Modules
ES Modules
浏览器
目前主流浏览器中默认支持
<script type="module" scr="PATH/file.js" />
这里的 module
关键字就告诉浏览器该脚本中包含了对于其他脚本的导入语句,需要进行预先处理;不过问题来了,那么
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
<script type="module" src="main.js"></script>
</head>
<body></body>
</html>
// main.js
import utils from "./utils.js";
utils.alert(`
JavaScript modules work in this browser:
https://blog.whatwg.org/js-modules
`);
待导入的模块如下:
// utils.js
export default {
alert: (msg)=>{
alert(msg);
}
};
我们可以发现,在 import
语句中我们提供了 .js
扩展名,这也是区别于打包工具的重要特性之一,往往打包工具中并不需要我们提供扩展名。此外,在浏览器中进行模块的动态加载,也要求待加载文件具有正确的
https://example.com/apples.js
http:example.com\pears.mjs (becomes http://example.com/pears.mjs as step 1 parses with no base URL)
//example.com/bananas
./strawberries.js.cgi
../lychees
/limes.jsx
data:text/javascript,export default ‘grapes’;
blob:https://whatwg.org/d0360e2f-caee-469f-9a2f-87d5b0456f6f
不过笔者觉得有个不错的特性在于浏览器中支持use strict
声明其也默认处于严格模式下:
const x = 1;
alert(x === window.x);//false
alert(this === undefined);// true
浏览器对于模块的加载默认是异步延迟进行的,即模块脚本的加载并不会阻塞浏览器的解析行为,而是并发加载并在页面加载完毕后进行解析,也就是所有的模块脚本具有 defer
属性。我们也可以为脚本添加 async
属性,即指明该脚本会在加载完毕后立刻执行。这一点与传统的非模块脚本相比很大不同,传统的脚本会阻塞浏览器解析直到抓取完毕,在抓取之后也会立刻进行执行操作。整个加载流程如下所示:

Node.js
- 利用
std/esm 在Node.js 开发中使用ES Modules 整理自ES Modules in Node Today!,从属于笔者的现代JavaScript 开发:语法基础与实践技巧系列中的模块化与构建章节。本文主要介绍了如何利用std/esm 第三方库在Node.js 应用中顺滑地使用ES Modules 语法。
利用std/esm 在Node.js 开发中使用ES Modules
随着主流浏览器逐步开始支持
// CJS
const a = require("./a")
module.exports = { a, b: 2 }
// ESM
import a from "./a"
export default { a, b: 2 }
鉴于.mjs
.json
格式文件,JSON.parse
方法。
而近日正式发布的 @std/esm 为我们提供了高性能的
> require('@std/esm')
@std/esm enabled
> import path from 'path';
undefined
> path.join("Hello","World");
'Hello/World'
.mjs
扩展的文件之外,它还支持任何包含 import/export
、Dynamic import、
// 首先安装依赖
// npm i --save @std/esm
// index.js
import hello from "./main.js";
hello();
// main.js
import thing from "./constants.js";
export default function hello() {
console.log(thing);
}
// constants.js
export default "Hello World!";
// 运行文件
// node -r @std/esm index.js
// Hello World!
笔者在自己尝试的时候发现
- Loading CJS equivs was ~0.28 milliseconds per module
- Loading built-in ESM was ~0.51 milliseconds per module
- First
@std/esm
no cache run* *was ~1.56 milliseconds per module - Secondary
@std/esm
cached runs were ~0.54 milliseconds per module