快速了解AMD、CMD、CommonJS、ESM

1.ES6 Module

javascript在ES2015(ES6)中出现了语言层面的模块(module)。javascript

ES6的模块既能够用于浏览器端,也能够用于服务器端(nodeJS)。css

ES6模块是静态化的模块加载,能够实现静态优化,在编译时就能够分析确认模块的依赖和输入输出变量。java

而AMD和CommonJS是在运行时才能确认这些东西。node

2. AMD

在此以前,浏览器端使用的模块加载方案主要是AMD,基于require.js;jquery

AMD和CMD其实都是浏览器端的异步模块加载规范;数组

AMD是RequireJS输出的规范;CMD是seaJS输出的规范;浏览器

用法

// 1. 想在页面中使用AMD加载模块,须要手动引入require.js
<script src="https://cdn.bootcss.com/require.js/2.3.6/require.js" data-main="main.js" defer async="true"></script>
// 2. 每个文件是一个模块,AMD要求模块使用define()定义模块
// test.js 模块
define(['jquery'], function(){ // 前面的数组表示依赖的模块
   return function test() {
       console.log(test);
    }
})
// 3. 在main.js中引入test.js
require(['tset'], function(test) {
   test()
})

3.CommonJS

ES6以前,服务器端(nodeJS)是CommonJS规范。缓存

09年,nodejs项目是使用CommonJS规范实现的模块系统。服务器

有一个全局的require()方法。异步

// 返回结果就是模块名字
// CommonJS里面的require用法和AMD里面的require用法不一致
let {readFile} = require('fs');

导出是module.exports = {}

⚠️: CommonJS输出的值是缓存,不是实时数据。可是ES6的export命令导出的是接口,能够访问模块的实时数据。

CommonJS第一次require,就会执行整个脚本,并在内存中生成一个对象(缓存):

{
    id: 'xxx', //模块名,
    exports: {...}, //输出的拷贝
    loaded: true/false // 加载是否完成
    ...
}
    

之后再require该模块,直接到缓存中取exports对象的值。

即不管执行加载多少次,返回的都是第一次加载时返回的值。能够手动清空缓存,清除以前的运行结果。

4. UMD

通用模块化系统,兼容AMD和CommonJS;

一般以AMD为基础,而后再包裹一层特殊代码实现CommonJS的兼容性。

相关文章
相关标签/搜索