1. 程式人生 > >耐得住寂寞也是一種境界

耐得住寂寞也是一種境界

js的模組化程序

現在前端技術日新月異,對於同一個問題痛點,各個時段有各自的解決方案,這就帶來了很大差異。今天我就打算梳理js模組化的歷史程序,講一講這些方案要做什麼,怎麼做。

js模組化程序的起因

現今的很多網頁其實可以看做是功能豐富的應用,它們擁有著複雜的JavaScript程式碼和一大堆依賴包。當一個專案開發的越來越複雜的時候,你會遇到一些問題:命名衝突(變數和函式命名可能相同),檔案依賴(引入外部的檔案數目、順序問題)等。

JavaScript發展的越來越快,超過了它產生時候的自我定位。這時候js模組化就出現了。

什麼是模組化

模組化開發是一種管理方式,是一種生產方式,一種解決問題的方案。他按照功能將一個軟體切分成許多部分單獨開發,然後再組裝起來,每一個部分即為模組。當使用模組化開發的時候可以避免剛剛的問題,並且讓開發的效率變高,以及方便後期的維護。

js模組化程序

一、早期:script標籤

這是最原始的 JavaScript 檔案載入方式,如果把每一個檔案看做是一個模組,那麼他們的介面通常是暴露在全域性作用域下,也就是定義在 window 物件中。

缺點:
1.汙染全域性作用域
2.只能按script標籤書寫順序載入
3.檔案依賴關係靠開發者主觀解決

二、發展一:CommonJS規範

允許模組通過require方法來同步載入(同步意味阻塞)所要依賴的其他模組,然後通過module.exports來匯出需要暴露的介面。

// module add.js
module.exports = function add (a, b) { return a + b; }

// main.js
var {add} = require('./math');
console.log('1 + 2 = ' + add(1,2);

CommonJS 是以在瀏覽器環境之外構建JavaScript 生態系統為目標而產生的專案,比如在伺服器和桌面環境中。

三、發展二:AMD/CMD

(1)AMD

AMD 是 RequireJS 在推廣過程中對模組定義的規範化產出(非同步模組定義)。

AMD標準中定義了以下兩個API:

  1. require([module], callback);
  2. define(id, [depends], callback);

require介面用來載入一系列模組,define介面用來定義並暴露一個模組。

    define(['./a', './b'], function(a, b) {  
        // 依賴必須一開始就寫好   
        a.add1()    
        ...  
        b.add2()    
        ...
    }) 

優點:
1、適合在瀏覽器環境中非同步載入模組 2、可以並行載入多個模組

(2)CMD

CMD 是 SeaJS 在推廣過程中對模組定義的規範化產出。(在CommomJS和AMD基礎上提出)

define(function (requie, exports, module) { 
    //依賴可以就近書寫 
    var a = require('./a'); 
    a.add1(); 
    ... 
    if (status) { 
        var b = requie('./b'); 
        b.add2(); 
    } 
}); 

優點:
1、依賴就近,延遲執行 2、可以很容易在伺服器中執行

(3)AMD 和 CMD 的區別

AMD和CMD起來很相似,但是還是有一些細微的差別:

1、對於依賴的模組,AMD是提前執行,CMD是延遲執行。

2、AMD推崇依賴前置;CMD推崇依賴就近,只有在用到某個模組的時候再去require。

3、AMD 的 API 預設是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一

四、發展三:ES6模組化

EcmaScript6 標準增加了JavaScript語言層面的模組體系定義。

在 ES6 中,我們使用export關鍵字來匯出模組,使用import關鍵字引用模組。

// module math.jsx
export default class Math extends React.Component{}

// main.js
import Math from "./Math";

目前很少JS引擎能直接支援 ES6 標準,因此 Babel 的做法實際上是將不被支援的import翻譯成目前已被支援的require。