Skip to content

Latest commit

 

History

History
90 lines (70 loc) · 4.58 KB

模块化.md

File metadata and controls

90 lines (70 loc) · 4.58 KB

模块化:

彻底弄懂CommonJS和AMD/CMD!

CommomJS (服务端模块)

是同步的 NodeJS是CommomJS规范的实现

var module = {exports: {}};

(function(module, exports) {
  exports.multiply = function (n) { return n * 1000 };
}(module, module.exports))

var f = module.exports.multiply;
f(5) // 5000
// 上面代码向一个立即执行函数提供module和exports两个外部变量
// 模块就放在这个立即执行函数里面。模块的输出值放在module.exports之中,这样就实现了模块的加载

一个纯浏览器的 CommonJS 模块加载器 tiny-browser-require 。完全不需要命令行,直接放进浏览器即可,所有代码只有30多行。

AMD(客户端模块))

异步模块 RequireJS实现了AMD规范

  • 实现js文件的异步加载,避免网页失去响应
  • 管理模块之间的依赖性,便于代码的编写和维护。
 <script src="js/require.js" defer async="true" ></script>

async属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持defer,所以把defer也写上。 加载require.js以后,下一步就要加载我们自己的代码了。假定我们自己的代码文件是main.js,也放在js目录下面。那么,只需要写成下面这样就行了:

 <script src="js/require.js" data-main="js/main"></script>

data-main属性的作用是,指定网页程序的主模块。在上例中,就是js目录下面的main.js,这个文件会第一个被require.js加载。由于require.js默认的文件后缀名是js,所以可以把main.js简写成main。

 // main.js

 require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){

    // some code here

  });

require()函数接受两个参数。第一个参数是一个数组,表示所依赖的模块,上例就是['moduleA', 'moduleB', 'moduleC'],即主模块依赖这三个模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。

require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。

使用require.config()方法,我们可以对模块的加载行为进行自定义。require.config()就写在主模块(main.js)的头部。参数就是一个对象,这个对象的paths属性指定各个模块的加载路径。

requre.config({
    basUrl: "js/lib", // 改变基目录
    paths: {
        "juery": 'lib/juery.min',
        "underscore": "underscore.min",
     "backbone": "backbone.min"
    },
    // underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。
    shim: {

      'underscore':{
        exports: '_'
      },
      'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      }

    }
})

还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义

  • exports值(输出的变量名),表明这个模块外部调用时的名称;
  • deps数组,表明该模块的依赖性。

CMD

  • 定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。Sea.js 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 环境中。
  • 遵循的规范不同。RequireJS 遵循 AMD(异步模块定义)规范,Sea.js 遵循 CMD (通用模块定义)规范。规范的不同,导致了两者 API 不同。Sea.js 更贴近 CommonJS Modules/1.1 和 Node Modules 规范。
  • 推广理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。Sea.js 不强推,采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。
  • 对开发调试的支持有差异。Sea.js 非常关注代码的开发调试,有 nocache、debug 等用于调试的插件。RequireJS 无这方面的明显支持。
  • 插件机制不同。RequireJS 采取的是在源码中预留接口的形式,插件类型比较单一。Sea.js 采取的是通用事件机制,插件类型更丰富。

SeaJS与RequireJS最大的区别 SeaJs