JavaScript模块化
ES Modules
ES6 模块是一种在JavaScript中定义和导出可重用代码的标准化方法。
- 使用
import
和export
关键字来定义和导出代码。 - 可以在应用程序中按需加载。
- 提供了一种在应用程序中管理依赖项的方式,使代码更易维护和扩展。
注意,模块的功能被引入单一脚本的作用域,它们非全局作用域可见。
语法
现代浏览器原生支持模块功能。一个.js文件即一个 module。
在一个文件中,可以有多个 export、import,但只能有一个 export default
。
通过 export
方式导出,在 import
导入时,要加 {}
且以逗号分隔引入需要的功能。export default
导出则不需要。
export default向外暴露的成员,可以使用任意变量来接收。
// app.js
export function myLogger(msg) {
console.log('myLogger:', msg);
}
export class MyClass {
constructor() {
...
}
}
// MyDefaultExport.js
export default function myFunction() {
...
}
// main.js
import { myLogger, MyClass } from 'app.js';
import MyDefaultComponent from './MyDefaultExport';
const MyComponent = () => {};
export default MyComponent;
实例
通过以下方式在 html 中引入模块文件。
<script type="module" src="main.js"></script>
- top-level作用域独立同样适用于
<script type="module">
- modules 自动使用 strict mode
- 无需在
<script>
上加 defer 属性,modules 执行是自动 deferred 推迟的。(即不 block HTML processing,与其他资源同时加载,在整个 page is loaded 后,根据 script 标签书写顺序执行 - Module 代码只 executed 一次,Exports 也只创建一次 shared between importers.实践:在第一个 import 处 configure 模块(设置属性),在其他 imports 处共享此设置。
- top-level 模块代码常用于初始化、创建内部数据结构
- 每个 module 只能有一个 default 导出
// square.js
export default randomSquare;
// main.js
import randomSquare from './square.js ';
// 等价于
import {default as randomSquare} from './square.js';
- 可使用
as
关键词在 export 和 import 环节 rename 模块功能,避免命名冲突 - 也可以通过创建 module 对象,抓取导入模块里所有 exports(使他们成为 module 对象的成员),相当于给定模块命名空间
import * as Circle from './modules/circle.js';
import * as Square from './modules/square.js';
Circle.draw()
Circle.reportArea()
Square.draw()
Square.reportArea()
- 此外还可以使用 class 来避免命名冲突,如果已经使用了 object-oriented 风格来书写模块代码
- 聚合模块:将子模块 export 聚合到共同的父模块,简化代码
- 动态模块加载:返回 Promise 包含一个 module 对象,用法同上
import('./modules/myModule.js')
.then((module) => {
// Do something with the module.
});
- 顶层 await,让模块变成一个异步函数,代码在被父模块使用前 evaluated,而不 block 同级模块的加载
// fetch request
const colors = fetch('../data/colors.json')
.then(response => response.json());
export default await colors;
- 模块内部
this
是 undefined
CommonJS(Node.js)
RequireJS(基于AMD模块系统)
RequireJS 是一个非常小巧的JavaScript模块载入框架(防止js加载阻塞页面渲染),是AMD规范最好的实现者之一,同时可以和其他的框架协同工作。