了解前端模块化系列内容:
三、了解前端模块化系列(1)——模块化的理解
三、了解前端模块化系列(2)——模块化规范-CommonJS
三、了解前端模块化系列(3)——模块化规范-AMD
三、了解前端模块化系列(4)——模块化规范-CMD & ES6
三、了解前端模块化系列(5)——模块化规范-UMD & 总结(CommonJS AMD CMD ES6 UMD)
三、模块化规范
3.5 UMD(Universal Module Definition)
3.5.1 UMD 是什么?
-
JavaScript 通用模块定义规范——使得模块在JavaScript所有运行环境(浏览器运行环境、Node.js 运行环境)中发挥作用。
-
通用——同时满足 CommonJS、AMD、CMD 的标准。
3.5.2 UMD 实现
;(function (root, factory) {
if (typeof module === 'object' && typeof module.exports === 'object') {
console.log('是commonjs模块规范,nodejs环境')
module.exports = factory()
} else if (typeof define === 'function' && define.amd) {
console.log('是AMD模块规范,如require.js')
define(factory)
} else if (typeof define === 'function' && define.cmd) {
console.log('是CMD模块规范,如sea.js')
define(function (require, exports, module) {
module.exports = factory()
})
} else {
console.log('没有模块环境,直接挂载在全局对象上')
root.umdModule = factory()
}
})(this, function () {
return {
name: '我是一个umd模块'
}
})
3.5.3 UMD 实现——factory 异想天开
参数为什么叫 factory ?我知道有个设计模式叫工厂模式,搜一搜。 看到这篇文章:JavaScript 设计模式(三):工厂模式
内容大致如下:
-
简单工厂模式: 应用:创建的对象数量较少,对象的创建逻辑不复杂时使用。 缺点:每添加一个构造函数需要修改两处代码。 (就跟今天看了一个文章:如何区分 Babel 中的 stage-0,stage-1,stage-2 以及 stage-3(一)babel-stage-2 提案文章提到提交了鸡肋的功能,程序员追求代码完美,能改一处就不改两处代码的提案,代码结尾最后加个逗号。)
let UserFactory = function (role) { function User(opt) { this.name = opt.name; this.viewPage = opt.viewPage; } switch (role) { case 'superAdmin': return new User({ name: '超级管理员', viewPage: ['首页', '通讯录', '发现页', '应用数据', '权限管理'] }); break; case 'admin': return new User({ name: '管理员', viewPage: ['首页', '通讯录', '发现页', '应用数据'] }); break; case 'user': return new User({ name: '普通用户', viewPage: ['首页', '通讯录', '发现页'] }); break; default: throw new Error('参数错误, 可选参数:superAdmin、admin、user') } } //调用 let superAdmin = UserFactory('superAdmin'); let admin = UserFactory('admin') let normalUser = UserFactory('user') -
工厂方法模式
工厂方法我们只把它看作是一个实例化对象的工厂,它只做实例化对象这一件事情! 我们采用安全模式创建对象。
//安全模式创建的工厂方法函数 let UserFactory = function(role) { if(this instanceof UserFactory) { var s = new this[role](); return s; } else { return new UserFactory(role); } } //工厂方法函数的原型中设置所有对象的构造函数 UserFactory.prototype = { SuperAdmin: function() { this.name = "超级管理员", this.viewPage = ['首页', '通讯录', '发现页', '应用数据', '权限管理'] }, Admin: function() { this.name = "管理员", this.viewPage = ['首页', '通讯录', '发现页', '应用数据'] }, NormalUser: function() { this.name = '普通用户', this.viewPage = ['首页', '通讯录', '发现页'] } } //调用 let superAdmin = UserFactory('SuperAdmin'); let admin = UserFactory('Admin') let normalUser = UserFactory('NormalUser') -
ES6 中的工厂模式
- ES6 重写简单工厂
- ES6 重写工厂方法
- ES6 重写抽象工厂
-
工厂模式的项目实战应用
-
总结
- 什么时候会用工厂模式?
- 将 new 操作简单封装,遇到 new 的时候就应该考虑是否用工厂模式;
- jQuery 工厂模式
- React 的 createElement()
- Vue 的异步组件
看第 1 点,第 2 点。
所以也就明白了:
- UMD 实现也可以理解为一个简单工厂模式,对象数量较少,对象的创建逻辑不复杂时使用。
- 针对这四种情况,进行 export :
- commonjs 模块规范
- AMD 模块规范
- CMD 模块规范
- 没有模块直接挂载全局对象
- 所以这不就通用 UMD 了嘛~
四、总结(CommonJS AMD CMD ES6 UMD)
以下将分别按照 3 个方面总结:运行的环境、加载模块的方式以及特点优点缺点。
-
CommonJS 规范
- 环境:服务器环境——服务端编程;
- 加载方式:同步加载模块——不适合浏览器环境;
- 特点 & 缺点:同步即阻塞加载——浏览器资源异步加载;
- 因此—— AMD CMD 解决方案;
-
AMD 规范
- 环境:浏览器环境——浏览器编程;
- 加载方式:异步加载模块——并行加载多个模块;
- 特点 & 缺点:
- 开发成本高;
- 代码的阅读书写困难;
- 模块定义语义不顺畅;
-
CMD 规范(与 AMD 规范相似)
- 环境:浏览器环境——浏览器编程;
- 加载方式:异步加载模块——并行加载多个模块;
- 特点:
- 依赖就近,延迟执行;
- 容易运行在 Node.js 中;
-
ES6
- 环境:浏览器、服务器环境——浏览器、服务端编程——所有运行环境;
- 加载方式:编译时加载(也叫静态加载)
- 特点 & 优点:
- 语言标准层面,实现模块功能
- 实现简单——完全可以取代 CommonJS 和 AMD 规范,
- 浏览器和服务器通用模块解决方案;
-
UMD
- 环境:浏览器、服务器环境——浏览器、服务端编程——所有运行环境;
- 加载方式:通用——同步、异步
- 特点 & 优点:
- 通用——同时满足 CommonJS, AMD, CMD 标准的实现
前端模块化的基础学习,终于写完啦!~
这只是一个开始,噗[捂脸哭.jpg]。