javascript 模块化的发展历程
JS 模块化开发有较长的历史,早起流行的命名空间 的开发思想,到后来有了一些模块化的开发规范,最先是CommonJS(主要使用在NodeJS 不是和浏览器),后来AMD、CMD、UMD、ESM等规范相继诞生。因为JS并未提供一种原生的,语言级别的模块化开发模式,而是将模块化交给开发者实现,所以这些规范的诞生,让JS模块化开发变得规范。
CommonJS
- 一个文件一个模块;
- 使用 exports.xx = ... 或者 module.exports ={} 暴露模块;
- 使用 require() 方法引入一个模块;
- require()是同步执行的;
示例
// a.js
let fn=function(msg){
console.log(msg);
}
exports.outMsg=fn;
//b.js
const a=require('./a.js');
a.outMsg('hello Commonjs'); // hello Commonjs
AMD
全称 Asynchronous module definition(异步模块定义)
- 使用 define(...) 定义一个模块;
- 使用require(...) 加载一个模块;
- 依赖前置,提前执行;
RequireJS 是AMD 的一种实现 示例
// 模块的定义
/**
*@param id 模块名称,如果为空,模块的名字默认为模块加载器请求的制定脚本名
*@param dependencies 模块依赖
*@param factory 工厂函数,模块初始化执行函数或对象
*/
define(id,dependencies,factory)
// 模块的使用,使用 require 加载模块
require([module],callback);
CMD
全称 Common Module Definition(通用模块定义)
- 一个文件为一个模块
- 使用 define(...) 定义一个模块 (和AMD相似)
- 使用require(...) 加载一个模块(和AMD 相似)
SeaJS 是CMD 的一种实现 示例:
// CMD
define(function(require,exports,module){
var a=require('./a');
a.sayHello();
var b=require('./b');// 依赖就近书写;
b.sayHello();
//...
});
CMD和AMD 的最显著的区别 AMD 是提前执行,CMD 是延迟执行,依赖就近;
AMD: 执行过程中会将所有的依赖模块前置执行,也就是自己的代码逻辑开始前全部执行;
CMD :如果require 但整个逻辑未使用这个依赖 或者为执行到逻辑使用它的地方前,不会执行。
UMD
全称 Universal Module Definition(万能模块定义),从名字就可以看出 UMD 做的是大一统的工作。Webpack 打包代码就有 UMD 这个选项。
这个万能模块,可以在服务端使用,也可以在浏览器端使用;
它主要做了三件事:
- 判断是否支持AMD
- 判断是否支持CommonJS
- 如果都不支持,使用全局变量
主要代码如下:
(function (root, factory) {
// 对应上述的三个步骤
if (typeof define === 'function' && define.amd) {
// 1.判断是否支持 AMD
// 如果 define 这个方法是被定义 并且 define 这个方法是 AMD 的规范,那就把 factory 这个模块实体用 define 方法以 AMD 的规范 定义
define([], factory); // [] 是依赖,factory 是模块实体
} else if (typeof exports === 'object') {
// 2. 判断是否支持 CommonJS
// 如果 exports 是等于一个对象,则表明是在 Node 环境中运行,则支持 CommonJS,那就用 module.exports 暴露整个模块实体
module.exports = factory();
} else {
// 3. 如果都不支持,使用全局变量
// Browser globals (root 即是 window)
root.returnExports = factory();
}
}(this, function () {
// Module Defination
var sum = function(x, y){
return x + y;
}
var sub = function(x, y){
return x - y;
}
var math = {
findSum: function(a, b){
return sum(a,b);
},
findSub: function(a, b){
return sub(a, b);
}
}
return math;
}));
ES Module (ES6 模块)
全称 ECMAScript Module
- 使用 import 导入模块;
- 使用 export 导出模块;
示例:
// 导出模块
export var a='123'; //导出变量
export function fn(){}; // 导出函数
export default {name:'p',age:18} // 导出对象; export 不能直接导出对象必须加上default;
export class Myclass{} // 导出类;
ES6 模块和Common js 模块的差异:
1、CommonJS 输出的是一个值的拷贝;ES6 模块输出的是值的引用;
2、CommonJS 模块是运行时加载;ES6模块是编译时输出接口;
由于ES6 模块是编译时输出接口,所以可以做到 tree shaking;
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!