JS模块化 AMD、CMD、CommonJS、ES6 module
# 模块化的优点
- 可维护性
- 减少全局污染
- 可复用性
- 方便管理依赖关系
- 分治思想的实践
# 几种规范介绍
AMD
- 异步模块定义 -- require.js
- 提前执行,推崇依赖前置。(默认一开始就载入全部依赖模块)
- API默认多功能(全局require和局部require)
- requireJS核心原理:每个模块所依赖模块都会比本模块预先加载
- 示例
define(['./a', './b'], function(a, b) { a.doSomething(); b.doSomething(); });
1
2
3
4CMD
- 通用模块定义 -- sea.js
- 延迟执行,推崇依赖就近。(依赖模块在用到时才就近载入)
- API推崇职责单一纯粹(没有全局require)
- 示例
define(function(require, exports, module) { var a = require('./a'); a.doSomething(); var b = require('./b'); b.doSomething(); })
1
2
3
4
5
6CommonJS
- 使用场景主要用在服务器端 nodejs
- CommonJS 模块加载过程是同步阻塞性地加载,在模块代码被运行前就已经写入了 cache,同一个模块被多次 require 时只会执行一次,重复的 require 得到的是相同的 exports 引用。
- 示例
// 模块输出 module.exports={} // 方式一 exports.count=1 // 方式二 // 模块引入 var math = require('./math'); math.add(2,3);
1
2
3
4
5
6ES6 module
- ES6 模块会在程序开始前先根据模块关系查找到所有模块,生成一个无环关系图,并将所有模块实例都创建好,这种方式天然地避免了循环引用的问题,当然也有模块加载缓存,重复 import 同一个模块,只会执行一次代码。
- 示例
// 模块输出 export const count=1 // 方式一 import {xx} from 'path' / import * as math from 'path' export default {} // 方式二 import xx from 'path' // 模块引入 import {math} from './math'; math.add(2, 3);
1
2
3
4
5
6
# ES Module与CommonJS的差异
- 语法
import/export
require/module
CommonJS
模块输出的是一个值的拷贝(不会随原始值变化),ES6
模块输出的是值的引用(会随着原始值变化)。CommonJS
模块是运行时加载,ES6
模块是编译时输出接口。
CommonJS
与ES6 module
互不兼容,一般会通过Bable
进行编译处理生成CommonJS
。- 使用
Node
原生ES6
模块需要将js
文件后缀改成mjs
,或者package.json
"type
" 字段改为 "module
",通过这种形式告知Node
使用ES Module
的形式加载模块。
上次更新: 2024/04/15, 14:35:14