在js中,我们为了更好的理解,开发,以及维护,我们会将我们的代码,文件,依赖等等分成一个一个的模块。其中典型的有AMD,CMD,Commonjs,ES Moudle等等,amd和cmd
AMD
AMD用的比较少,简单介绍下,AMD的主要思想是异步模块,主逻辑在回调中执行
//module.js
define(function (require, exports, module) {
console.log('module.js');
exports.name = 'jack'; //暴露
});
//module2.js
define(function (require, exoprts, module) {
console.log('module2.js');
exports.desc = 'hello world';
});
//main.js
require(['module1', 'module2'], function (m1, m2) {
console.log('main.js');
console.log(m1.name + ',' + m2.desc); //引入module1和module2之后,直接使用其暴露的属性
});
CMD
CMD规范和AMD很相似,简单,并与CommonJS和Node.js的 Modules 规范保持了很大的兼容性;在CMD规范中,一个模块就是一个文件。
//module1.js
define(function (require, exports, module) {
console.log('module1.js');
// module.exports = value;
// exports.xxx = value
exports.name = 'i am module1';
});
//main.js
define(function (require, exports, module) {
//引入依赖模块(同步)
var module2 = require('./module2');
console.log(module2.name);
//引入依赖模块(异步1)
require.async('./module3', function (m3) {
//这里m3对应module3
});
//引入依赖模块(异步2)
var module4 = require.async('./module4');
console.log(module4.name);
});
CommonJS
我们在node服务端应用较多的模块化,是一种同步加载规范,允许模块通过require方法来同步加载所要依赖的其他模块,然后通过exports或module.exports来导出需要暴露的接口。
默认导出
module.exports = {
count: 1
};
导入
const a = require('./1.js');
console.log(a); //{ count: 1 }
按需导出
exports.getStoreInfo = function () {
console.log(123);
};
导入
const a = require('./1.js');
console.log(a); // { getStoreInfo: [Function (anonymous)] }
- 模块通过
exports来向外暴露API,exports只能是一个对象,暴露的API需作为此对象的属性 - 定义全局函数
require,通过传入模块标识来引入其他模块,执行的结果即为别的模块暴露出来的API - 如果被reqiure函数引入的模块中也包含依赖,那么以此加载这些依赖
ESmoudle
是ES6提出的模块化规则, ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值,换句话说,ES6的输入有点像Unix系统的“符号连接”,原始值变了,import输入的值也会跟着变。
默认导出
export default {
count: 1
};
默认导入
import a from './1.js';
console.log(a);
按需导出
export let a = {
count: 1
};
按需导入
import { a } from './1.js';
console.log(a);