js 的实现模块化的历程

传统意义的网站只是提供浏览功能,随着网站功能越来越强大,如今的网站,已是“互联网应用程序”。而驱动这个应用程序的 JavaScript 也变得越来越庞大、复杂!开发、维护、管理这些 js 代码显得越来越困难了,实现 js 的模块化开发成为了迫切的需求。

以下简单记录 js 实现模块化的一些实现方式

函数

单纯的把一个函数或多个函数放在一起,组成一个模块。这种方式污染了全局变量,管理起来也不清晰。

1
2
3
4
5
6
function bar {
// do somethings
}
function foo {
// do somethings
}

对象

把所有的模块成员塞进一个对象。这样减少了全局变量的污染,但这样会暴露所有模块成员,内部状态可以被外部改写。

1
2
3
4
5
6
7
8
var module = {
name: '_my_module',
each: function () {
// do somethings
}
}
// 改写内部模块
module.each = null

立即执行函数

可以对上述方式进行改进,利用函数返回一个对象来创建。

1
2
3
4
5
6
7
8
var module = (function () {
return {
name: '_my_module',
each: function () {
// do somethings
}
}
})()

再改进一下,可以实现简单的模块扩展,模块依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var module = (function (mod) {
return {
name: '_my_module',
each: function () {
// do somethings
},
// 该依赖依赖 moduleA
getTime: function () {
return mod.getTime()
},
// 可扩展
extend: function (name, m) {
this[name] = m
}
}
})(window.moduleA || {})

CommonJS

nodejs 推出后,js 可以用于复杂的服务器端编程,nodejs 参照了 CommonJS 规范实现了模块化。在 CommonJS 中,有一个全局变量 require 用于加载模块。

1
2
var moduleA = require('moduleA')
var time = moduleA.getTime()

AMD

正如上述,nodejs 是为服务端编程而实现了模块化,但浏览器端并没有实现。而 require 是同步加载的,在浏览器有网络传输延迟,使用同步加载模块显然不合理。为了保持模块使用风格的一致性,便探索出了异步模块定义(Asynchronous Module Definition),即 AMD 规范。实现了依赖模块异步加载,加载完后成通过回调执行。目前有两个主流库实现了 AMD 规范,分别是 require.js curl.js

1
2
3
4
require(['moduleA'], function(moduleA) {
var time = moduleA.getTime()
// ...
})

兼容性写法

很多优秀的第三方库,使用兼容性写法,以兼容 CommonJS 、AMD 的模块化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(function(global, factory) {
// AMD 模块
if (typeof define === 'function' && define.amd) {
define([], factory)
// CommonJS 模块
} else if (typeof module === 'object' && typeof module.exports === 'object' ) {
module.exports = factory()
} else {
// 直接挂载到全局对象上
global.myFn = factory()
}
})(window, function () {
// myFn
return function () {
// do somethings ...
}
})
The End
# module

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×