-
Notifications
You must be signed in to change notification settings - Fork 0
Description
模块是什么?
模块: 指能够单独命名并独立地完成一定功能的程序语句集合(即程序代码和数据结构的集合体)
模块的优点
- 可维护性 根据定义可知模块是独立的,一个设计良好的模块会让外面的代码对自己的依赖越少越好,这样自己就可以独立去更新和改进。当模块与其他代码解耦时,更新单个模块更容易的多;
- 命名空间 在 JavaScript 中,顶级函数范围之外的变量是全局变量(意味着每个人都可以访问它们)。因此,
普遍存在"命名空间污染",其中完全不相关的代码共享全局变量;
使用模块化开发来封装变量,可以避免污染全局环境。 - 可重用性 对于公共代码,书写一份,通过模块引入的方式,避免重复的代码
执行环境
我们常接触的执行环境有浏览器端和 Node.js 端。执行环境的不同会造成模块运行方式不同。主要有同步模块加载和异步模块加载方式。
UMD
UMD, 全称 Universal Module Definition, 即通用模块规范。
同时支持 CommonJS 和 amd 风格,也支持非模块化在浏览器端运行。
大多数库均采用 UMD 规范。下面分析 underscore.js 的 UMD 写法。
// underscore.js v1.9.2
(function() {
var root =
(typeof self == "object" && self.self === self && self) ||
(typeof global == "object" && global.global === global && global) ||
this ||
{};
if (typeof exports != "undefined" && !exports.nodeType) {
// 支持 CommonJS 方式导出
if (typeof module != "undefined" && !module.nodeType && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
// 暴露到全局
root._ = _;
}
// some code
/*
支持 AMD 方式导出
*/
if (typeof define == "function" && define.amd) {
define("underscore", [], function() {
return _;
});
}
})();简单总结 UMD 规范。
- 判断环境里有没有 define 函数,如果有,支持 AMD 模块导出;
- 判断环境里有没有 exports 和 module 对象, 如果有,支持 CommonJS 导出,
- 如果以上两种情况都不符合,就将其暴露到全局环境中
CommonJS
CommonJS 最开始是 Mozilla 的工程师于 2009 年开始的一个项目,它的目的是让
浏览器之外的 JavaScript (比如服务端或者桌面端) 能够通过模块化的方式来开发
和协作
在 CommonJS 的规范中,每个 Javascript 文件就是一个独立的模块上下文(module context)
在这个上下文中默认创建的属性都是私有的。也就是说,在一个文件定义的变量(还包括函数和类),
都是私有的,对其他文件是不可见的。
需要注意的是,CommonJS 规范的主要适用场景是服务器编程,所有采用同步加载模块的策略。
如果我们依赖 3 个模块,代码会一个一个依次加载它们。
该模块实现方案主要包含 require 与 module 这两个关键字,其允许某个模块对外暴露部分
接口并且由其他模块导入使用。
下面,我们在 Node.js 环境下
// myModule.js
const author = "qinghuanI";
module.exports = { author };
// index.js
const { author } = require("./myModule.js");
console.log(author); // 'qinghuanI'AMD
AMD 全称 Asynchronous Module Definition, 即异步模块定义,是 RequireJS 在推广过程中对模块定义的规范化产出。
同样的,其规定一个文件就是一个模块,文件名即模块名。
AMD 使用 define 函数定义模块;使用 require 函数引用模块。
define 函数使用方式如下
define(id?, dependencies?, factory);定义 myModule.js 模块
define(['dependModule'], function(dependModule){
// do something
});require 接受两个参数,第一个参数为所依赖的模块标识数组;第二个参数为
依赖模块加载完成后的回调函数。
在 main.js 中引用 myModule 模块
require(['myModule'], function (myModule){
//do something
});AMD 推崇依赖前置,需要先异步加载其所需的依赖模块后才会执行
相应回调函数中的代码。