1.模块化的优点
减少命名污染,提高复用性、可维护性,减少耦合
2.立即执行函数
利用函数的块级作用域,立即执行。实现最简单的模块化
(function() {
// 拥有独立作用域
})()
const module1 = (() => {
let count = 0;
return {
increase: () => ++count;
}
})();
module1.increase();
有额外的依赖时,以参数的传入
const module = ((moduleA, moduleB) => {
})(moduleA, moduleB)
3.AMD
通过异步加载+允许制定回调函数 通过define来定义模块,通过require来加载。 define(id?, [depends]?, callback) define 参数分别是 模块名,依赖模块,工厂方法; require([module], callback);
define('myModule', ['moduleA', 'moduleB'], (moduleA, moduleB) => {
// 使用moduleA
// 使用moduleB
})
require(['myModule'], (myModule) => {
// 使用myModule
})
4.CMD
依赖就近原则,按需加载,在使用的时候才去引入
define('module', (require, exports, module) => {
let $ = require('jquery');
// 需要使用jquery相关逻辑
let myModule = require('./myModule');
// 需要使用myModule相关逻辑
})
缺点:依赖于打包,加载逻辑存在于每个模块中,扩大模块体积,打包体积变大 与AMD区别:AMD 推崇依赖前置、提前执行,CMD推崇依赖就近、延迟执行
5.CJS
commonjs规范,nodejs使用的规范;在运行时加载,值拷贝
- 通过module + exports 对外暴露接口
- 通过require来引入其他模块
// 引入部分
const moduleA = require(./moduleA);
const moduleA = require(./moduleA);
let count = 0;
const increase = () => ++count;
// 需要使用引用的相关逻辑……
// 暴露接口部分
exports.increase = increase;
// 或者
module.exports = {
increase,
}
注: 1.exports 是指向的 module.exports 的引用。类似于 var exports = module.exports。 require() 返回的是 module.exports 而不是 exports,所以当 module.exports和exports指向的不是同一块内存时,exports的内容就会失效
2.使用 require() 导入模块,导入后会缓存该模块,下次再加载该模块会直接从缓存中取出。所有缓存保存在 require.cache 中,可以使用 delete require.cache[moduleName] 方法删除缓存
// moduleA
export.name = 'A'
//引用
require('./moduleA.js')
console.log(require('./moduleA.js').name) // A
delete require.cache[require.resolve('./moduleA.js')]
console.log(require('./moduleA.js').name) //undefined
6.EMS
es6模块化通常被称为ES Module(或ES6 Module)。
使用上和CommonJS类似:
- 使用
export或export default导出; - 使用
import导入;
// 引入
import moduleA from './moduleA.js';
let count = 0;
//导出
const increase = () => ++count;
export { increase }
// 默认导出
// export default increase
模板引入的时候
<script type="module" src="esModule.js"></script>
还有一个动态导入的方法 import() ,调用时将返回一个 Promise 。使用方式可以如下:
import('./module.mjs').then((module) => {
// TODO
});
commonjs和esmodule的区别
- commonjs是运行时加载模块,ES6是在静态编译期间就确定模块的依赖
- commonjs是同步加载模块,ES6是异步加载
- commonjs是一个值拷贝,会对加载结果进行缓存,一旦内部再修改这个值,则不会同步到外部。ES6是导出的一个引用,内部修改可以同步到外部。