前端模塊化概述

1、爲何須要模塊化jquery

   代碼量驟增 => 分治管理的剛性需求webpack

 

2、模塊化方案需解決什麼問題?web

       模塊化要實現兩個東西:模塊加載與模塊封裝。面臨的具體問題包括:數組

       一、如何定義模塊以確保模塊的做用域獨立,避免命名衝突?瀏覽器

       二、如何管理模塊間的依賴關係,避免重複加載與循環引用?網絡

       三、模塊化的代碼如何部署,以下降HTTP請求數?異步

       四、如何實現按需加載?模塊化

       五、如何在解決上述問題以後,保證性能且不影響debug?函數

 

3、原始的解決方案有何侷限?工具

   命名空間 + 當即執行函數 + script標籤

   侷限性:

   一、全局空間污染

   二、需手動管理依賴,不具有可擴展性

   三、沒法實現按需加載

 

4、新的解決方案

一、CommonJS

       CommonJS 起源於一個服務端項目 SeverJS,該項目意在經過模塊化的開發模式, 解決 JS 做用域的問題。後來發展成了一個致力於構建 JS 生態圈的組織。

       CommonJS 提供了一套模塊加載的規範,其核心語法是經過 module.exports 暴露接口,經過 require() 加載資源。

   CommonJS 規範採用同步加載,適用於服務端,但並不適用於瀏覽器環境(網絡延遲、異步特性),所以在瀏覽器端出現了各種模塊加載器,以解決模塊加載的問題。

   各種模塊加載器提出了各自的模塊封裝的規範。其中 Sea.js 提出/實現的封裝規範,就是 CMD 規範;RequireJS 提出/實現的封裝規範,就是 AMD 規範。

 

二、Sea.js

  模塊封裝:

   define (function (require, exports, module) {

    var a = require('./a')  // 模塊加載

    a.doSomething();

    // ……

    var b = require('./b')  // 依賴能夠就近書寫

    b.doSomething();

    // 經過 exports 對外提供接口

    exports.doSomething = ...

    // 或者經過 module.exports 提供整個接口

    module.exports = ...

   })

   模塊加載:

   var $ = require('jquery');

 

三、RequireJS

       模塊封裝:

   define (['./a', './b'], function(a, b) {

    a.doSomething();

    // 此處略去 100 行

    b.doSomething();

    return function () { } //返回模塊的值,能夠是函數,也能夠是對象

  })

  模塊加載:

  require (['./a', './b'], function (a, b) {

        // do sth

  })  

      區別

      RequireJS:依賴前置,提早加載

      Sea.js:依賴就近,延遲加載

 

四、UMD

       一種兼容 CommonJS 和 AMD 的語法糖。事實上 RequireJS 和 Sea.js 就是相互支持的。

圖片來源:https://www.leanpanda.com/blog/2015/06/28/amd-requirejs-commonjs-browserify/

      

五、打包工具:Browserify&Webpack

       在模塊化的開發方式下,模塊加載器(Module loader)解決了模塊的加載與依賴的自動管理,可是並無解決 HTTP 請求數的問題。如何將分散的文件合併成一個或幾個文件以減小 HTTP 請求,這就是打包工具(Module bundler)的做用。

       打包工具的核心能力是對 js 代碼進行合併,擴展能力是對 js 代碼進行優化、編譯和壓縮。webpack 的特點是擴展得比較狠,經過各種插件,能夠打包任意類型的文件。

       打包工具的真正價值在哪裏呢?僅僅是合併文件從而減小 HTTP 請求數嗎?固然不止,打包工具的真正價值是在工程開發中,完成從開發狀態到發佈狀態的自動化構建

  減小 HTTP 請求和按需加載實際上是相互矛盾的,都打包成一個文件了,天然不須要考慮模塊加載的問題。可是把全部文件都打包成一個文件,又顯得有些冗餘。因此 webpack 也支持 code spliting,把文件打成多個包。

 

六、終結者:ES6 Module

      原生模塊標準獲得瀏覽器全面支持之時,就是全部模塊封裝方案滅亡之日。但打包工具(自動化構建工具)仍會繼續存在。

 

5、模塊打包的技術實現

圖片來源:https://www.leanpanda.com/blog/2015/06/28/amd-requirejs-commonjs-browserify/

  以上是 browserify 的實現,webpack 的實現也差很少,這裏詳細說明一下。

  首先,webpack 會將每一個 js 文件編譯成一個函數:

   webpack 會將文件路徑映射爲一個數字 id,入口文件默認 id 爲 0,在入口文件中遇到的第一個加載的模塊,id 爲 1……,總之按照加載的順序依次賦予一個 id。

    webpack 函數用於整個模塊的加載,全部模塊函數會按照 id 的順序組成一個數組,傳給 webpack 進行加載。

       最後運行的結果是:

相關文章
相關標籤/搜索