javascript在ES2015(ES6)中出现了语言层面的模块(module)。javascript
ES6的模块既能够用于浏览器端,也能够用于服务器端(nodeJS)。css
ES6模块是静态化的模块加载,能够实现静态优化,在编译时就能够分析确认模块的依赖和输入输出变量。java
而AMD和CommonJS是在运行时才能确认这些东西。node
在此以前,浏览器端使用的模块加载方案主要是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() })
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对象的值。
即不管执行加载多少次,返回的都是第一次加载时返回的值。能够手动清空缓存,清除以前的运行结果。
通用模块化系统,兼容AMD和CommonJS;
一般以AMD为基础,而后再包裹一层特殊代码实现CommonJS的兼容性。