最全的前端模塊化方案

模塊化主要是用來抽離公共代碼,隔離作用域,避免變量沖突等。將一個復(fù)雜的系統(tǒng)分解為多個模塊以方便編碼。

會講述以下內(nèi)容

  1. CommonJS
  2. AMD 及 核心原理實現(xiàn)
  3. CMD 及 核心原理實現(xiàn)
  4. UMD 及 源碼解析
  5. ES6 Module
  6. webpack打包策略

CommonJS

同步加載

CommonJS API是以在瀏覽器環(huán)境之外構(gòu)建 JS 生態(tài)系統(tǒng)為目標(biāo)而產(chǎn)生的項目

如果沒有寫后綴名Node會嘗試為文件名添加.js、.json、.node后再搜索。

.js件會以文本格式的JavaScript腳本文件解析,.json文件會以JSON格式的文本文件解析,.node文件會以編譯后的二進(jìn)制文件解析。

AMD

異步加載(對象)

"Asynchronous Module Definition"(異步模塊定義),是由RequireJS提出的

AMD核心實現(xiàn)

  function require (url, callback) {
    // url可以換成List,然后遍歷;
    var $script = document.createElement('script');
    $script.src = url;

    // 利用onload回調(diào),實現(xiàn)依賴加載
    $script.onload = function (e) {
      // 省略callback 檢測
      callback();
    }
    document.body.appendChild($script);
  }

CMD

按需加載

由玉伯提出的(seajs),按需解析加載模塊(代價挺大的),需要使用把模塊變?yōu)樽址馕鲆槐椴胖酪蕾嚵四切┠K

CMD核心實現(xiàn)

  // ajax,怕忘了原生ajax怎么寫。順手寫一個

  function myAjax (url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('get', url);
    xhr.send();

    xhr.onreadystatechange = function () {
      if (request.readyState === 4) {
          if (request.status === 200) {
              return callback(request.responseText);
          } else {
              // 省略...
          }
      } else {
        // 省略...
      }
    }
  }

  // 實現(xiàn)
  function require(url) {
    myAjax(url, function(res) {
      // 此時 res 的對應(yīng)JS的 String形式
      // 解析 省略
      // 執(zhí)行
      eval(res);
    });
  }

UMD

兼容AMD,CommonJS 模塊化語法。

UMD源碼解析

  (function (root, factory) {

    // 判斷是否支持AMD(define是否存在)
    if (typeof define === 'function' && define.amd) {
        define(['b'], factory);

    // 判斷是否支持NodeJS模塊格式(exports是否存在)
    } else if (typeof module === 'object' && module.exports) {
        module.exports = factory(require('b'));

    // 前兩個都不存在,則將模塊公開到全局(window或global)
    } else {
        root.returnExports = factory(root.b);
    }
  } (this, function (b) {
      // ...
  }));

import

加載引用

  • 編譯時加載(靜態(tài)執(zhí)行)。
  • 加載的是引用
  • 不能處于代碼塊中
    • 為了實現(xiàn)編譯時加載
      • 提案表示可以用 import()使用時加載
  • 不能使用表達(dá)式和變量 等運行時加載的語法
    • 同上

webpack打包策略

import會被編譯成 require/exports (CommonJS規(guī)范)

1. 直接引入

import xxx.js或者import xxx.css會像添加<script><link>標(biāo)簽一樣注入到全局中去

2. commonjs同步語法

webpack會將require('abc.js')打包進(jìn)引用它的文件中。以對象的形式獲取。

3. commonjs異步加載

webpack(require.ensure):webpack 2.x 版本中的代碼分割。

在commonjs中有一個Modules/Async/A規(guī)范,里面定義了require.ensure語法。webpack實現(xiàn)了它,作用是可以在打包的時候進(jìn)行代碼分片,并異步加載分片后的代碼。

此時list.js會被打包成一個單獨的chunk文件。像這樣:1.d6f343b727f5923508bf.js

例如:vue路由懶加載const Foo = () => import('./Foo.vue')

manifest

manifest文件是最先加載的,manifest是在vendor的基礎(chǔ)上,再抽取出要經(jīng)常變動的部分,通過manifest.js文件來管理bundle文件的運行和加載。(比如關(guān)于異步加載js模塊部分的內(nèi)容)

webpack v4.6.0+ 添加了預(yù)取和預(yù)加載的支持

  import(/* webpackPrefetch: true */ 'LoginModal');
  
  會生成 <link rel="prefetch" href="login-modal-chunk.js"> 并追加到頁面頭部

整理不易,喜歡請 star,https://github.com/zhongmeizhi

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 系列文章導(dǎo)航 模塊(一) CommonJs,AMD, CMD, UMD 本文參考阮一峰 ES6入門 Module的...
    合肥黑閱讀 6,354評論 0 4
  • 1. 前言 現(xiàn)在的前端開發(fā), 通常是一個單頁面應(yīng)用,每一個視圖通過異步的方式加載,這導(dǎo)致頁面初始化和使用過程中會加...
    majun00閱讀 811評論 0 2
  • Javascript模塊化編程,已經(jīng)成為一個迫切的需求。理想情況下,開發(fā)者只需要實現(xiàn)核心的業(yè)務(wù)邏輯,其他都可以加載...
    zhoulujun閱讀 3,024評論 0 14
  • 1.幾種基本數(shù)據(jù)類型?復(fù)雜數(shù)據(jù)類型?值類型和引用數(shù)據(jù)類型?堆棧數(shù)據(jù)結(jié)構(gòu)? 基本數(shù)據(jù)類型:Undefined、Nul...
    極樂君閱讀 5,878評論 0 106
  • 在現(xiàn)在的前端開發(fā)中,前后端分離、模塊化開發(fā)、版本控制、文件合并與壓縮、mock數(shù)據(jù)等等一些原本后端的思想開始...
    Charlot閱讀 5,659評論 1 32

友情鏈接更多精彩內(nèi)容