什么是模块化?
模块化主要是为了实现代码可复用,一个模块拥有独立的作用域,避免多个功能模块定义的变量冲突,防止全局污染。同时通过模块化的代码拆分,拥有更规范的代码结构,增强代码的维护性,提高开发效率。有了模块化后,就可以根据需要加载对应的功能模块,减少代码体积的同时也使代码结构更直观。在早些时候,JavaScript并没有其官方支持的模块化,为了应对多种场景需求,社区中出现了多种规范,其中包括AMD、CMD、UMD、CJS、ESM,其中ESM是ES6中原生支持的,是现在以及将来主要使用的规范。
模块化的分类
CJS规范
CommonJS的缩写,用于后端,在nodejs中的模块化,使用的是common.js规范。一个文件就是一个模块,通过require导入模块,module.export或exports导出模块。模块可以多次加载,但只会在第一次加载执行一次,然后运行结果就会被缓存,模块加载的顺序是按照其在代码中出现的顺序加载的。
由于用户可以动态 require,无法做到提前分析依赖以及Tree-Shaking。CommonJS 规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。
// 文件名: foo.js
var $ = require('jquery'); // 导入模块
// 暴露公共方法(一个)
function myFunc(){};
module.exports = myFunc; // 导出方法
AMD规范
AMD即 Asynchronous Module Definition 的缩写,代表异步模块定义,它是一个概念,并不是一个真实的规范标准,RequireJS是对这个概念的实现,可以实现异步加载文件。通过define()函数定义,接收两个参数,第一个参数是一个数组,数组里定义了一些需要依赖的包,第二个参数是一个回调函数,当依赖可用时调用此回调函数,并且参数就是依赖的包变量。
// 文件名: foo.js
define(['jquery'], function ($) {
function myFunc(){};
// 暴露公共方法
return myFunc;
});
UMD规范
UMD是 Universal Module Definition 的缩写,代表通用模块定义。是一种通用的写法,在AMD和CJS流行而不统一的情况下,催生出了UMD来统一规范,所以UMD同时兼容 CJS 和 AMD,前后端通用。
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS之类的
module.exports = factory(require('jquery'));
} else {
// 浏览器全局变量(root 即 window)
root.returnExports = factory(root.jQuery);
}
}(this, function($) {
function myFunc() {};
// 暴露公共方法
return myFunc;
}));
CMD规范
CMD规范是在sea.js推广过程中对模块定义的规范化产出。sea.js是淘宝团队提供的一个模块化开发框架,是一个同步模块定义,通过define()定义,通过require加载。与AMD类型,区别是CMD没有依赖前置,它是依赖就近,在什么地方使用到插件就在什么地方require该插件,即用即返,是一个同步的概念。
define(function(require, exports, module){
var $ = require('jquery.js');
function myFunc() {};
exports.myFunc = myFunc;
})
ESM规范
ESM是 ECMAScript Module 的缩写,是ES6原生支持的,使用 import、export 来管理依赖。由于它们只能写在所有表达式外面,所以打包器可以轻易做到分析依赖以及 Tree-Shaking。ESM 也支持动态加载(import )。浏览器直接通过 <script type="module">
即可使用该写法。
export 向外暴露或导出模块 export default xxx;
import 引入模块 import { xxx } from './xxx';
import React from 'react';
export default MyFunc(){};
总结
- 由于
ESM
具有简单的语法,异步特性和可摇树性,因此它是最好的模块化方案 UMD
随处可见,通常在 ESM 不起作用的情况下用作备用CJS
是同步的,适合后端AMD
是异步的,适合前端