当一个网站复杂度较高需要多人协作开发时,传统的非模块化编程模式容易导致代码冲突和依赖等问题,而模块化编程的诞生正是为了解决此类问题。然而,在ES6之前,原生JavaScript是不支持模块化的,因此就出现了一系列的JavaScript库来实现此功能,这些库主要遵循以下三种规范:
① CommonJS
② AMD
③ CMD
接下来我就粗略地讲讲这三种规范。
一、CommonJS规范
关键词: module,exports,require
CommonJS规范下的模块调用是同步的,也就是说必须等模块加载完成之后,接下来的代码才能继续运行。因此,该规范主要适用于服务端,因为服务端可以直接从硬盘中调用所需要的模块,而这个过程速度是非常快的。相比之下,通过网络调用所需模块的浏览器客户端则不适合使用该规范。
目前使用该规范的典型代表有:Node.js、微信小程序。
下面以Node.js中的两个小例子,简单讲讲CommonJS规范下的模块化编程。
1. 无返回值的模块调用
//module.js
console.log('这是一个模块。');
//main.js
require('./module'); // 或写成 require('./module.js'),但千万注意不能写成 require('module')
以上module.js和main.js两个文件处于同一目录下。
2. 有返回值的模块调用
//module.js
function foo(){
console.log('这是一个模块。');
}
module.exports = { // 此处提供模块对外接口
foo: foo // 此处对外接口中的方法名不一定要与以上定义的方法名一致,比如可以写成 func: foo,那么此时调用时就应该写成 module.func()
};
//main.js
var module = require('./module.js'); // 加载module模块
module.foo(); // 此处调用module模块下的foo方法,该方法名须与模块中对外接口方法名一致
**
二、AMD规范
**
关键词: define,require
与CommonJS不同,AMD规范下的模块调用是异步的,主要适用于浏览器客户端。
目前使用该规范的典型代表有:require.js、curl.js。
下面以require.js为例,简单讲讲AMD规范下的模块化编程。
<!--HTML-->
<script src="scripts/require.js"></script>
<script src="scripts/main.js" data-main="scripts/main"></script>
1. 无返回值的模块调用
//module.js
console.log('这是一个模块。');
//main.js
require(['scripts/module']); // 请求的模块路径用数组表示
2. 有返回值的模块调用
//module.js
function foo(){
console.log('这是一个模块。');
}
define(function(){
return {
foo: foo
}
});
//main.js
require(['scripts/module'],function(module){
module.foo();
});
**
三、CMD规范
**
关键词: use,define,require,exports,module
CMD规范结合了以上两种规范的特点,既可以同步调用,也可以异步调用,在语法上也非常相似。
目前使用该规范的典型代表有:sea.js。
下面就以sea.js为例,简单讲讲CMD规范下的模块化编程。
<!--HTML-->
<script src="scripts/sea.js"></script>
<!--引入主模块,模块根目录为sea.js所在目录,有点类似于C语言中的main函数-->
<script type="text/javascript">
seajs.use('main');
</script>
1. 无返回值的模块调用
//module.js
console.log('这是一个模块。');
//main.js
define(function(require,exports,module){
require('module');
});
这里需要重点说明一下,define()中回调函数中所传参数名称不允许修改。
2. 有返回值的模块调用
定义模块:
//module.js
function foo(){
console.log('这是一个模块。');
}
define(function(require,exports,module){
//也可以直接通过return方式暴露模块接口,这样就与AMD规范相同
module.exports = {
foo: foo
}
});
调用模块存在同步和异步两种方式:
① 同步调用
//main.js
define(function(require,exports,module){
var module = require('module');
module.foo();
});
② 异步调用
//main.js
define(function(require,exports,module){
require.async('module',function(module){
module.foo();
});
});
本次有关JavaScript模块化编程规范的分享就到这里,若有不到之处,欢迎指正,谢谢!