js的模块化

common.js

参考模块化的历程


模块化面临什么问题

  1. 如何安全的包装一个模块的代码?(不污染模块外的任何代码)
  1. 如何唯一标识一个模块?
  2. 如何优雅的把模块的API暴漏出去?(不能增加全局变量)
  1. 如何方便的使用所依赖的模块?
    围绕着这些问题,js模块化开始了一段艰苦而曲折的征途。

2009年,nodejs 促发了common.js的发展

1、CommonJS定义的模块分为:
{模块引用(require)} {模块定义(exports)} {模块标识(module)}
require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身

规范

  1. 模块的标识应遵循的规则(书写规范)
  1. 定义全局函数require,通过传入模块标识来引入其他模块,执行的结果即为别的模块暴漏出来的API
  2. 如果被require函数引入的模块中也包含依赖,那么依次加载这些依赖
  3. 如果引入模块失败,那么require函数应该报一个异常
  1. 模块通过变量exports来向往暴漏API,exports只能是一个对象,暴漏的API须作为此对象的属性。

//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


服务端向前端进军 AMD/RequireJs的崛起与妥协

AMD的思想正如其名,异步加载所需的模块,然后在回调函数中执行主逻辑。这正是我们在浏览器端开发所习惯了的方式,其作者亲自实现了符合AMD规范的requirejs,AMD/RequireJs迅速被广大开发者所接受。
AMD规范包含以下内容:

  1. 用全局函数define来定义模块,用法为:define(id?, dependencies?, factory);
  1. id为模块标识,遵从CommonJS Module Identifiers规范
  2. dependencies为依赖的模块数组,在factory中需传入形参与之一一对应
  3. 如果dependencies的值中有"require"、"exports"或"module",则与commonjs中的实现保持一致
  4. 如果dependencies省略不写,则默认为["require", "exports", "module"],factory中也会默认传入require,exports,module
  5. 如果factory为函数,模块对外暴漏API的方法有三种:return任意类型的数据、exports.xxx=xxx、module.exports=xxx
  1. 如果factory为对象,则该对象即为模块的返回值

/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(); }); })


你可能感兴趣的:(js的模块化)