前端模塊化 CommonJS AMD CMD ES6

  模塊化開始如今已經很流行了,方便代碼的管理,一般一個文件就是一個模塊,有本身的做用域,只是向外暴露特定的變量或者函數
目前流行的js模塊化規範就有 CommonJS AMD CMD ES6 模塊系統,這個總結 是看別人的原始出處在 掘金APP 上;
  一: CommonJS
    Node.js是commonJS規範的主要實踐者,它有四個重要的環境變量爲模塊化的實現提供支持:module exports require global
    用module.exprots定義當前模塊對外輸出的藉口 用require加載模塊
    定義math.js文件
      var basicNum = 0;
      function add(a,b){
  javascript

    return a+b;
      };
    module.exports = {add:add,basicNum:basicNum}; //對象輸出特定變量
    //文件引入
    var math = require('./math');
    math.add(2,3);
    //文件引入核心模塊時候不須要帶路徑
    var http = require('http');
    http.createSevise(...).listen(3000);
    CommonJS 用同步的方式加載模塊,在服務器端模塊文件都是在本地磁盤上,讀取很是快,可是在瀏覽器端限於網絡緣由,更適合用異步加載
  二: AMD和require.js
    AMD規範採用異步方式加載模塊,模塊的加載不影響它後面的語句執行,全部依賴這個模塊語句都定義在一個函數回調中,
    等到加載完成以後,纔開始執行回調函數,用require.config()指定引用路徑 用define()定義模塊 用require加載模塊
    首先咱們須要引入require.js文件和一個入口文件main.js 在main.js中配置require.config()並規定項目中用到的基礎模塊
    //在網頁中引入require.js和main.js
    <script src="js/require.js" data-main="js/main"></script>
    //在main.js入口文件 首先定義config()指定各模塊路徑和引用名
    require.config({
    baseUrl: 'js/lib',
    paths: {
      'require': 'jquire.main' //實際路徑爲 js/lib/jquire.main.js
      'underscore': 'underscore.main'
    }
    });
    //執行基本操做
    require(['jquire','underscore'],function($,...){
      //some code here
    });
    引用模塊時候,咱們講模塊名放在[]中做爲require()第一參數,若是咱們定義的模塊自己也依賴其餘模塊,那就須要將他們放在[]中做爲define()第一參數,html

    若是咱們定義的模塊自己也依賴其餘模塊,那就須要將他們放在
    //定義main.js模塊
    define(function(){
    var basicNum = 0;
    var add = function(x,y){
      return x+y;
    };
    return {
      add : add,
    basicNum : basicNum
    };java

    });
    //定義一個依賴underscore.js模塊
    define(['underscore'],function(_){
    var classify = function(list){
    -.countBy(list,function(num){
    return num > 20 ? 'old' : 'young';
    });
    }
    return {
      classify:classify
      }
    });
    //引用模塊,將模塊放在[]內
    require(['jquire','main'],function($,math){
    var sum = math.add(2,3);
      $("#sum").html(sum);
    });
  三:CMD和sea.js
    require.js在聲明依賴模塊時會第一之間加載並執行模塊內的代碼;
    define(['a','b','c'],function(a,b,c){
    //等於在最前面聲明並初始化要用到的全部模塊
    if(false){
      //即使沒有用到某個模塊b,但b仍是提早執行了
      b.foo();
      }
    });
    CMD是另外一個js模塊化方案,和AMD很相識,不一樣點在於:AMD推崇依賴前置,提早執行,CMD推崇依賴就近,延遲執行,在sea.js中推廣中產生的
    //CMD寫法:
    define(function(require,exports,module){
    var a = require('./a'); //在須要時候聲明
      a.doSomething();
    if(false){
      var b = require('./b');
      b.doSomething()
    }
    });
    //sea.js
    //定義模塊main.js
    define(function(require,exports,module){
    var $ = require('jquire.js');
    var add = function(a,b){
      return a+b;
    };
    exports.add = add;
    });
    //加載模塊
    seajs.use(['main.js'],function(){
      var sum = math.add(1+1);
    });
  四:ES6 Module
    ES6在語言標準的層面上,實現了模塊功能,並且實現得至關簡單,旨在瀏覽器和服務器通用的模塊解決方案,
    其主要構成是:export和import,export命令用於規定模塊的對外接口,import命令用於輸入其餘模塊提供功能
    //定義模塊main.js
    var basicNum = 0;
    var add = function(a,b){
      return a+b;
    };
    export({basicNum,add});
    //引用模塊
    import {basicNum,add} from './main'
    function test(ele){
      ele.testCont = add(2+basicNum);
    };

    若是用export default{basicNum,add}; 不用使用大括號
    //定義輸出
    export default{basicNum,add};
    //引入
    import math from './main';
    function test(ele){
      ele.testCont = math.add(99+math.basicNum);
    }
    ES6模塊不是對象,import命令會被javascript引擎靜態分析,在編譯時引入模塊代碼,而不是在代碼運行時候加載,因此沒法實現條件加載
    也是這個緣由,使得靜態分析成爲可能
  五:ES6模塊與CommonJS模塊的差別
    1.CommonJS模塊輸出的是一個值得拷貝,ES6模塊輸出的值得引用
      CommonJS模塊輸出是一個值得拷貝,也就是說一旦輸出一個值,模塊內部變化就影響不到這個值
      ES6模塊運行機制,JS引擎對腳本靜態分析的時候,遇到模塊加載命令import,就會生成一個只讀引用,等到腳本真正執行時,再根據
      這個只讀引用到被加載的那個模塊裏面去取值, import加載的值也會跟着變,所以ES6模塊是動態引用,而且不會緩存值
    2.CommonJS模塊是運行時加載,ES6模塊是編譯時輸出接口
      運行時加載:CommonJS模塊就是對象,即在輸入時是先加載整個對象,生成一個對象,而後再從這個對象上讀取方法,這種稱爲:運行時加載
      編譯時加載:ES6模塊不是對象,而是經過exprot命令顯示指定輸出的代碼,import時採用靜態命令形式,而不是加載整個模塊 這種稱爲:編譯時加載

  CommonJS加載是一個對象 (module.exprots屬性) 而ES6模塊不是對象,它的對外接口是一種靜態定義,在代碼靜態解析階段會生成瀏覽器

相關文章
相關標籤/搜索