JavaScript中模块化相关内容
概念
-
模块化概念:
JavaScript在早期设计时,并没有模块、类、包等概念,开发者需要模拟出类似的功能,用来分散复杂的JavaScript代码,称之为模块化。
模块化,就是将独立的功能代码封装成一个独立的文件,其他模块需要使用,在进行引用。
-
模块化需要解决的问题:
模块化需要实现:模块封装和模块加载,在这两个过程中会有以下问题:
2.1 如何确保定义的各模块之间作用域独立,避免命名冲突;
2.2 如何处理模块间依赖关系;
2.3 模块化后,代码如何部署,如何减低HTTP请求次数;
2.4 如何实现模块按需加载;
2.5 如何保证性能以及后期调试debug等;
模块化开发,需要紧扣上述问题来进行,避免后期出现问题。
-
原始解决方案的局限性:
原始解决方案:命名空间、立即执行函数、script标签。
局限性: 3.1 全局空间污染; 3.2 无法按需加载; 3.3 可扩展性低;
分类
后面在JavaScript不断的发展过程中,主要形成了以下几种模块化规范:
-
浏览器端:
1.1 AMD(异步模块规范) RequireJs
1.2 CMD(普通模块规范) SeaJs
-
Node端:
CommonJS(同步模块规范)
-
通用:
浏览器和Node兼容端 UMD(通用模块规范)
-
ECMAScript官方:
ES Module即ESM
AMD
AMD是RequireJS在推广过程中对模块定义的规范化产出。
AMD是异步加载模块。它的模块支持对象、函数、构造器、字符串、JSON等各类型的模块。
define(['dep1', 'dep2'], function (dep1, dep2) {
//Define the module value by returning a value.
return function () {};
});
CMD
CMD是SeaJS 在推广过程中对模块定义的规范化产出
CMD和AMD的区别有以下几点:
-
对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。
-
CMD推崇依赖就近,AMD推崇依赖前置。
CommonJS
CommonJS就是一个JavaScript模块化的规范,该规范最初是用在服务器端NodeJS中,前端的webpack也是对CommonJS原生支持的。
CommonJS 提供了一套模块加载的规范,其核心语法是通过 module.exports 暴露接口,通过 require() 加载资源。
模块定义及导出:
// importing
const doSomething = require('./doSomething.js');
// exporting
module.exports = function doSomething(n) {
// do something
}
UMD
UMD是AMD和CommonJS的综合产物。
AMD 浏览器第一的原则发展 异步加载模块。
CommonJS 模块以服务器第一原则发展,选择同步加载,它的模块无需包装。
UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。
再判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。
(function (window, factory) {
if (typeof exports === 'object') {
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
define(factory);
} else {
window.eventUtil = factory();
}
})(this, function () {
// module ...
});
ES Module
ECMA推出了官方标准的模块化解决方案,使用 export 导出,import 导入,编码简洁,从语义上更加通俗易懂。
ES6 支持异步加载模块 的模块不是对象,而是在编译的时候就完成模块的引用,所以是编译时才加载的。
ES Module特性:
-
ESM 自动采用严格模式,忽略 'use strict'
-
每个 ES Module 都是运行在单独的私有作用域中
-
ESM 是通过 CORS 的方式请求外部 JS 模块的
-
ESM 的 script 标签会延迟执行脚本(浏览器页面渲染后执行)
import {foo, bar} from './myLib';
...
export default function() {
// your Function
};
export const function1() {...};
export const function2() {...};