写在前面
ES6之前,Javascript并没有模块体系。但是实际开发中,为了更高效的开发,我们需要模块化编程开发,也就产生了几类模块化标准。
CommonJS(服务器端)
- 一个文件就是一个模块,每个模块都是单独的作用域,除非定义为
global
对象的属性 - 输出模块
module.exports
对象 - 加载模块使用
require
方法 - 同步读取模块,适合nodejs,由于网络的原因,并不适合浏览器端(异步加载)
异步加载模块(浏览器端)
面对的问题
- 多个文件的依赖关系,被依赖的文件需要在依赖他的文件之前加载到浏览器
- js加载时,浏览器会停止页面的渲染,加载的文件越多,页面失去相应的时间越长
AMD(异步模块定义)+ Require.js
其原理是异步加载模块,模块的加载不影响其后面语句的运行。所有以来这个模块的语句都会添加进一个回调函数中,等到模块加载完成,回调函数就会执行。
require([modlue], callback)
读取模块
require.config
配置别名,使用栗子:
//别名配置
requirejs.config({
paths: {
jquery: 'jquery.min' //可以省略.js
}
});
//引入模块,用变量$表示jquery模块
requirejs(['jquery'], function ($) {
$('body').css('background-color','red');
});
define(id?, dependencies?, factory)
定义模块
- id:模块名
- dependencies:当前模块依赖的模块
- factory:工厂方法,一般直接返回一个对象
define('math',['jquery'], function ($) {//引入jQuery模块
return {
add: function(x,y){
return x + y;
}
};
});
CMD(通用模块定义)+ SeaJS
CMD和AMD解决的问题一样,不过是模块定义方式、模块加载的时机不同
seajs示例:
// 定义模块 myModule.js
define(function(require, exports, module) {
var $ = require('jquery.js')
$('div').addClass('active');
exports.data = 1;
});
// 加载模块
seajs.use(['myModule.js'], function(my){
var star= my.data;
console.log(star); //1
});
CMD & AMD间的区别
- AMD依赖前置,在定义模块时就声明其所要依赖的模块
- CMD是按需加载依赖,在用到那个模块再去
require
- AMD在使用前就准备好,CMD是用到了再去准备模块
ES6模块(服务器&浏览器端通用)
具体使用参考潜入理解ES6-模块化
- 静态加载,编译时确定依赖关系
- 模块输出为值得引用,CommonJS是值得拷贝
- 自动运行于严格模式之下
export
关键字导出import
关键字导入- 同步、异步加载均可