模块化JavaScript,CommonJS、AMD、NodeJS、RequireJS、SeaJS、curljs 等模块化的JavaScript概念及库扑面而来。
如果不适用模块化,我们会遇到什么?
- 全局变量的灾难
- 函数命名冲突
- 依赖关系不好管理
javascript·使用模块化面临的问题
1.如何包装一个模块,不污染模块外的任何代码?
2.如何唯一标识一个模块?
3.如何优雅的把模块的API暴漏出来?
4.如何方便的使用所依赖的模块?
1.CommonJs
遵循commonjs规范的代码看起来是这样的:
//math.js
exports.add = function() {
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) {
sum += args[i++];
}
return sum;
};
//increment.js
var add = require('math').add;
exports.increment = function(val) {
return add(val, 1);
};
//program.js
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
2. AMD/RequireJs
AMD异步加载所需的模块,在回调函数中执行主逻辑。这正是在浏览器端开发所习惯了的方式。
AMD规范包含以下内容:
1. 用全局函数define来定义模块,用法为:define(id?, dependencies?, factory);
2. id为模块标识,遵从CommonJS Module Identifiers规范
3. dependencies为依赖的模块数组,在factory中需传入形参与之一一对应
4. 如果dependencies的值中有”require”、”exports”或”module”,则与commonjs中的实现保持一致
5. 如果dependencies省略不写,则默认为[“require”, “exports”, “module”],factory中也会默认传入require,exports,module
6. 如果factory为函数,模块对外暴漏API的方法有三种:return任意类型的数据、exports.xxx=xxx、module.exports=xxx
7. 如果factory为对象,则该对象即为模块的返回值
遵循AMD/RequireJs规范的代码看起来是这样的:
//a.js
define(function(){
console.log('a.js执行');
return {
hello: function(){
console.log('hello, a.js');
}
}
});
//b.js
define(function(){
console.log('b.js执行');
return {
hello: function(){
console.log('hello, b.js');
}
}
});
//main.js
require(['a', 'b'], function(a, b){
console.log('main.js执行');
a.hello();
$('#b').click(function(){
b.hello();
});
})
3.CMD/seajs
requirejs有上述种种不甚优雅的地方,所以必然会有新东西来完善它,这就是后起之秀seajs,seajs的作者是国内大牛淘宝前端步道者玉伯。seajs全面拥抱Modules/Wrappings规范,不用requirejs那样回调的方式来编写模块。而它也不是完全按照Modules/Wrappings规范,seajs并没有使用declare来定义模块,而是使用和requirejs一样的define,
用seajs定义模块的写法如下:
//a.js
define(function(require, exports, module){
console.log('a.js执行');
return {
hello: function(){
console.log('hello, a.js');
}
}
});
//b.js
define(function(require, exports, module){
console.log('b.js执行');
return {
hello: function(){
console.log('hello, b.js');
}
}
});
//main.js
define(function(require, exports, module){
console.log('main.js执行');
var a = require('a');
a.hello();
$('#b').click(function(){
var b = require('b');
b.hello();
});
});
4.面向未来的ES6
ES6移除了关于模块如何加载/执行的内容,只保留了定义、引入模块的语法。所以说现在的ES6 Module还只是个雏形,半成品都算不上。但是这并不妨碍我们先窥探一下ES6模块标准。
扫描二维码关注公众号,回复:
994579 查看本文章
用ES6定义模块的写法如下:
//方式一, a.js
export var a = 1;
export var obj = {name: 'abc', age: 20};
export function run(){....}
//方式二, b.js
var a = 1;
var obj = {name: 'abc', age: 20};
function run(){....}
export {a, obj, run}
//使用模块的时候用import关键字
import {run as go} from 'a'
run()