ccjoe / m

mark for joe, blog
0 stars 0 forks source link

JS模块化演变简略 #7

Open ccjoe opened 7 years ago

ccjoe commented 7 years ago

title: JS模块化演变及组件化 speaker: Joe Liu date: 2015年3月8日 keyword: 模块化, 组件化, 构建


Table Of Contents


No Modular


基本的模块化封装

如果一个模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用"放大模式"(augmentation)

var module2 = (function (mod){
    mod.m3 = function () {};
    return mod;
  })(module1);
var module1 = (function ($, YAHOO) {
  //...
$
})(jQuery, YAHOO);

JS Modular


require.js (AMD)

[magic data-transition="cover-circle"]

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为对象,则该对象即为模块的返回值

    • 定义模块(代码示例:cd /e/git/h5-mvc define:gom/src/gom require: scripts/app)
      
      define(/**'ModuleNameOrFileName', **/ ['jquery', 'underscore'], function ($, _) {
      //    方法
      function a(){};    //    私有方法
      function b(){};    //    公共方法
      function c(){};    //    公共方法

    // 暴露公共方法 return { b: b, c: c } }); require('ModuleNameOrFileName', function(ModuleNameOrFileName){ //do sth });

    
    - 项目示例  (示例:gulp serve)
    - 构建模块  (示例:config: app/gom/r-config.js  build:gulp gom-scripts)
    [/magic]

node.js(server CMD)

sea.js(browser CMD) {:&.moveIn}

define(function(require, exports, module) { {:&.moveIn}

    // 文件名: foo.js
    var $ = require('jquery');
    var _ = require('underscore');
    // methods
    function a(){ // $.methods, _.extend };    //    私有方法,因为它没在module.exports中 (见下面)
    function b(){};    //    公共方法,因为它在module.exports中定义了
    function c(){};    //    公共方法,因为它在module.exports中定义了
    // 暴露公共方法
    module.exports = {
        b: b,
        c: c
    };

}); {:&.moveIn}


UMD(Universal Module Definition)

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery', 'underscore'], factory);  // AMD
    } else if (typeof exports === 'object') {
        module.exports = factory(require('jquery'), require('underscore')); // Node, CommonJS之类的
    } else {
        root.returnExports = factory(root.jQuery, root._); // 浏览器全局变量(root 即 window)
    }
}(this, function ($, _) {
    function a(){};    //    私有方法,因为它没被返回 (见下面)
    function b(){};    //    公共方法,因为被返回了
    function c(){};    //    公共方法,因为被返回了

    //    暴露公共方法
    return {
        b: b,
        c: c
    }
}));

ES6(ECMAScript 6/2015年6月17日发布)

组件化(Componentizes) 参见另一篇......

sunshine940326 commented 7 years ago

放大模式这里不是很理解,能否写的详细一点呢,谢谢

ccjoe commented 7 years ago

@sunshine940326 放大模式,如上所述当一个模块很复杂很大的时候, 需要将这个模块分解成多个模块。

var module1 = (function(){
    var _count = 0;
    var m1 = function(){};
    var m2 = function(){};
    return {
      m1 : m1,
      m2 : m2
    };
  })();
var module2 = (function (mod){
    mod.m3 = function () {};
    return mod;
  })(module1);

如上代码假设module1是个很大的模块, module1实现了一部分逻辑, 那么属于module1但又相对较独立的模块可以独立出来写在module2. module1的方法有m1,m2 module2的方法有m1,m2,m3

module2 放大了module1模块的内部逻辑,module2最后return 的结果是扩展了的module1。