模块化的Javascript

模块化JavaScript,CommonJS、AMD、NodeJS、RequireJS、SeaJS、curljs 等模块化的JavaScript概念及库扑面而来。

如果不适用模块化,我们会遇到什么?

  1. 全局变量的灾难
  2. 函数命名冲突
  3. 依赖关系不好管理

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模块标准。

用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()

猜你喜欢

转载自my.oschina.net/ndweb/blog/1817489