模塊化及AMD、CMD、CommonJS、ES6的對比

模塊化

概念: 將一個複雜的程序依據一定的規則(規範)封裝成幾個塊(文件)並進行組合。

模塊的內部數據的實現是私有的,只是向外部暴露一些接口(方法)與外部其他模塊通信,這就是模塊化。

優點: 模塊化可以降低代碼耦合度,減少重複代碼,提高代碼重用性,並且在項目結構上更加清晰,便於維護。

AMD、CMD、CommonJs、ES6的對比

他們都是用於在模塊化定義中使用的,AMD、CMD、CommonJs是ES5中提供的模塊化編程的方案,import/export是ES6中定義新增的

AMD

AMD是RequireJS在推廣過程中對模塊定義的規範化產出,它是一個概念,RequireJS是對這個概念的實現,就好比JavaScript語言是對ECMAScript規範的實現。AMD是一個組織,RequireJS是在這個組織下自定義的一套腳本語言

RequireJS:是一個AMD框架,可以異步加載JS文件,按照模塊加載方法,通過define()函數定義第一個參數是一個數組,裏面定義一些需要依賴的包,第二個參數是一個回調函數,通過變量來引用模塊裏面的方法,最後通過return來輸出。

是一個依賴前置、異步定義的AMD框架(在參數裏面引入js文件),在定義的同時如果需要用到別的模塊,在最前面定義好即在參數數組裏面進行引入,在回調裏面加載

define(['./a', './b'], function(a, b) {
    a.do();
    b.do();
});
define(function(require,exports,module){
	var a = require('./a');
    a.doSomething();
    var b = require('./b');
    b.doSomething();
});

CMD

SeaJS在推廣過程中對模塊定義的規範化產出,是一個同步模塊定義,是SeaJS的一個標準,SeaJS是CMD概念的一個實現,SeaJS是淘寶團隊提供的一個模塊開發的js框架.

通過define()定義,沒有依賴前置,通過require加載jQuery插件,CMD是依賴就近,在什麼地方使用到插件就在什麼地方require該插件,即用即返,這是一個同步的概念

define(id?, deps?, factory)

factory是一個函數,有三個參數,function(require, exports, module)

  1. require 是一個方法,接受 模塊標識 作爲唯一參數,用來獲取其他模塊提供的接口:require(id)
  2. exports 是一個對象,用來向外提供模塊接口
  3. module 是一個對象,上面存儲了與當前模塊相關聯的一些屬性和方法
// 定義模塊  module.js
define(function(require, exports, module) {
  var $ = require('jquery.min.js')
  $('div').addClass('active');
});

// 加載模塊
seajs.use(['module.js'], function(my){
});

AMD與CMD區別

AMD和CMD最明顯的區別就是在模塊定義時對依賴模塊的執行時機處理不同。

1、AMD推崇依賴前置,在定義模塊的時候就要聲明其依賴的模塊

js可以方便知道依賴模塊是誰,立即加載;

2、CMD推崇就近依賴,只有在用到某個模塊的時候再去require

需要使用把模塊變爲字符串解析一遍才知道依賴了那些模塊,犧牲性能來帶來開發的便利性,實際上解析模塊用的時間短到可以忽略。

ES6

ES6模塊的主要有兩個功能:export和import。

  • export用於對外輸出本模塊(一個文件可以理解爲一個模塊)變量的接口。
  • import用於在一個模塊中加載另一個含有export接口的模塊。

也就是說使用export命令定義了模塊的對外接口以後,其他JS文件就可以通過import命令加載這個模塊(文件)。

//util1.js
export default {
    a: 100
}

//index.js
import util1 from './util1.js'
console.log(util1);
//util2.js
export function fn1() {
    alert('fn1');
}
export function fn2() {
    alert('fn2');
}

//index.js
import { fn1, fn2 } from './util2.js'
fn1();
fn2();

CommonJs

是通過module.exports定義的,在前端瀏覽器裏面並不支持module.exports,通過node.js後端使用的。Nodejs端是使用CommonJS規範的,前端瀏覽器一般使用AMD、CMD、ES6等定義模塊化開發的。

加載模塊使用require方法,該方法讀取一個文件並執行,最後返回文件內部的exports對象。

CommonJS定義的模塊分爲:{模塊引用(require)} {模塊定義(exports)} {模塊標識(module)}

  • require()用來引入外部模塊;
  • exports對象用於導出當前模塊的方法或變量,唯一的導出口;
  • module對象就代表模塊本身。
// a.js
module.exports = {
    a: 1;
}
// or
exports.a = 1;

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

commonjs和ES6模塊化的區別

  • 前者支持動態導入,也就是require(${path}/xx.js),後者目前不支持,但是已有提案
  • 前者是同步導入,因爲用於服務端,文件都在本地,同步導入即使卡住主線程影響也不大。而後者是異步導入,因爲用於瀏覽器,需要下載文件,如果也採用導入會對渲染有很大影響
  • 前者在導出時都是值拷貝,就算導出的值變了,導入的值也不會改變,所以如果想更新值,必須重新導入一次。但是後者採用實時綁定的方式,導入導出的值都指向同一個內存地址,所以導入值會跟隨導出值變化。
  • 後者會編譯成require/export來執行
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章