漫谈 Javascript 模块化
js 代码 2009 年 HTML5 兴起后,前端代码的行数已经呈现井喷式发展,随着代码量的增加,模块的缺失的缺点日益凸显,Javascript 社区做了很多探索。如今 JavaScript 模块化编程的概念已经普及开来,一提起模块化,大家想到的可能是 AMD,CMD,requirejs 或 seajs。其实还有很多其他的概念。本文将会陈述下 JavaScript 模块的前世今生。
模块
模块,又称构件,是能够单独命名并独立地完成一定功能的程序语句的集合(即程序代码和数据结构的集合体)
一个独立的模块需要能够独立完成一个功能,可以引用依赖和被依赖。例如 C 语言中的库和头文件,Java 中的包,等等。
原始写法
一个函数实际上就是一个模块
1 | // 最简单的函数,可以称作一个模块 |
一个更合理的模拟模块方式
1 | (function (mod, $, _) { |
这依旧不完美,因为这个模块必须要先依赖 jQuery 库。理想的情况是,模块的依赖顺序是随意的,我们可以随机顺序指定依赖而不用担心定义先后的问题。
CMD (Common Module Definition)
说道 CMD 就不能不提 commonjs,提到 commonjs 就不能不提 node。
CMD 规范参照 commonjs 中的方式,定义模块的方式如下:
1 | define(function(require, exports, module) { |
一个文件就是一个模块,文件名就是模块的名字,使用模块的方法也和 commonjs 中一致,只需 require 就好了,模块名字可省略后缀。
1 | // 使用 event.js 模块 |
CMD 的典型实现就是 seajs,应用的很广泛。
AMD (Asynchronous Module Definition)
AMD) 是异步模块定义,特别适合在浏览器端使用,其规范和 CMD 是很像的,AMD 规范中定义模块的方式如下:
1 | define(id?, dependencies?, factory); |
同 CMD 一样,一个文件即一个模块,模块的使用方法如下:
1 | define(["beta"], function (beta) { |
AMD 主张依赖注入,这点和 CMD 不同(以来查找)。
AMD 也支持已 CMD 的方式来使用依赖。
AMD 的典型实现有 requireJS,modJS 和 lodJS。
ES6
ES6 带来了语言层面的模块化支持,规范方面见 这里,文档方面见 这里。=
UMD
UMD 的全称是 Universal Module Definition。和它名字的意思一样,这种规范基本上可以在任何一个模块环境中工作。
一段典型的 UMD 代码如下所示:
1 | (function (root, factory) { |
这是出自 data.js 中的一部分代码,其原理就是做个判断,不同的环境进行不同的处理。
总结
模块化的探索,使前端工程化成为了可能,可以说没有模块,工程化更无从弹起,