1. 程式人生 > >前端commonjs、AMD、CMD、ES6等模組化的對比

前端commonjs、AMD、CMD、ES6等模組化的對比

  • CommmonJS用於node端,是同步載入的
  • AMD依賴於requirejs,是非同步載入的,是提前載入,立即載入 
  • CMD依賴於seajs,是非同步載入,延後載入,就近載入,用時載入 
  • ES6是ES2015的簡稱,一般通過export來暴露模組,import來匯入模組

CommonJS

CommonJS模組化規範:

1.通過module.exports或exports來暴露模組

2.通過require來載入模組

//用法舉例

//a.js檔案
var math = {
add:function(a,b){
return a+b;
}
}
module.exports = math	
//module是代表當前模組,通常通過module.exports來暴露模組


//b.js
var math = require('./a.js')		//模組依賴,通過require匯入模組
console.log(math.add(1,2))		//3
//一個模組有多個變數時
//a.js
var x = 5;
var addX = function (value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

//b.js
var example = require('./a.js');

console.log(example.x); // 5
console.log(example.addX(1)); // 6

注意:當被暴露的物件是單一的值時,不能通過exports來暴露,只能通過module.exports來暴露

var x = 5
module.exports.x = x  //不能使用exports.x = x

CommonJS的特點

1.同步載入,一般用於node端

2.一次載入,多次使用。對同一個模組而言,只會執行一次,多次使用時會從快取中獲取

3.模組載入的順序,按照它出現的順序

4.程式碼都執行在模組作用域,不會造成全域性汙染

AMD

AMD是一種非同步載入模組的方式,主要用在瀏覽器環境中。主要依賴於require.js庫

AMD模組化規範:

1.通過define()方法定義模組

2.通過require方法載入模組

使用方法

1.先載入require.js(從官網下載最新版本)

//通過這種方式先載入requirejs
<script src="js/require.js"></script>

//為防止載入require.js阻塞頁面,可以將其寫在頁面的底部,或寫成以下這種形式
 <script src="js/require.js" defer async="true" ></script>
//async屬性表明要非同步載入,避免網頁失去響應,IE不支援這個屬性,為相容IE,所以需要新增defer屬性

2.建立一個主檔案(入口檔案)

//建立一個main.js,我們要寫的程式碼從這裡開始
//在html裡匯入以下js
<script src="js/require.js" data-main="js/main"></script>

//data-main的作用時指出我們的入口檔案在哪,require.js會第一個載入主檔案

3.主檔案的寫法

//若主模組不依賴於其他模組,則不必要使用requirejs

//一般而言,主模組要依賴於其他模組,需要使用AMD的require方法來載入依賴的模組

//main.js
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){

    // some code here

});
//require第一個引數時一個數組,表示依賴的模組,第二個引數是一個回撥,回撥的引數表示對應的模組,這樣在回撥中就可以使用這些模組了

//它的回掉函式只有在所有模組都載入完成才開始執行
4.在主模組中配置模組載入的一些行為(通過require.config()方法)
// main.js

require.config({
  paths: {

      "jquery": "lib/jquery.min",
      "underscore": "lib/underscore.min",
      "backbone": "lib/backbone.min"
    }
});

//require配置一般寫在main.js入口檔案的頂部
//paths屬性表示要載入的檔案的路徑,可以寫本地路徑,或伺服器路徑
//baseUrl屬性可以用來改變基目錄,上面程式碼可用以下方式表示

require.config({
    baseUrl: "js/lib",
    paths: {
      "jquery": "jquery.min",
      "underscore": "underscore.min",
      "backbone": "backbone.min"
    }
});

5.定義模組(通過define()方法)

//a.js
//通過define來定義模組,
//如果該模組還依賴其他模組,則第一個引數是一個數組,表示其依賴的模組
 define(['package/lib'], function(lib){
  function foo(){
    lib.log('hello world!');
  }

  return {
    foo: foo
  };
});
//b.js
//在其他模組使用a.js
require(['a'], function (a){
   a.foo()
});

CMD(seajs)

//依賴就近,延遲載入
define(function (require, exports, module){
  var someModule = require("someModule");
  var anotherModule = require("anotherModule");

  someModule.doTehAwesome();
  anotherModule.doMoarAwesome();

  exports.asplode = function (){
    someModule.doTehAwesome();
    anotherModule.doMoarAwesome();
  };
});

ES6

模組化規範:

  • 一個模組就是一個獨立的檔案。該檔案內部的所有變數,外部無法獲取。
  • export 命令用於規定模組的對外介面。
  • import 命令用於輸入其他模組提供的功能。
//export暴露介面
//圓面積計算
export function area(radius) {
  return Math.PI * radius * radius;
}
 
//圓周長計算
export function circumference(radius) {
  return 2 * Math.PI * radius;
}

//main.js
//import匯入模組
//以大括號的形式載入對外的模組
import {area,circumference} from './hangge';
console.log('圓面積:' + area(10));
console.log('圓周長:' + circumference(11));

//也可以通過以下方式匯入所有介面
import * as circle from './hangge';
console.log('圓面積:' + circle.area(10));
console.log('圓周長:' + circle.circumference(11));export default:用來預設暴露模組,匯入時不需要使用大括號

export default:用來預設暴露模組,匯入時不需要使用大括號

//a.js
//圓面積計算(作為預設介面)
export default function(radius) {
  return Math.PI * radius * radius;
}
 
//圓周長計算
export function circumference(radius) {
  return 2 * Math.PI * radius;
}


//b.js
//area匯入的是export default暴露的介面
import area, {circumference} from './a';
console.log('圓面積:' + area(10));
console.log('圓周長:' + circumference(11));


//注:es6 需要babel來支援