webpack 源碼-資源加載

準備編譯的代碼資源

一共四個文件資源

// index.js
import { varA, varB } from './mod1'
import m2 from './mod2'

let b = 'bbb'
console.log(varA, varB, m2)

// mod1.js
export const varA = 'aaa'
export const varB = 'bbb'

// mod2.js
import { c } from './modc.js'
export default {
  m1: 'm1',
  m2: 'm2'
}

// modc.js
export const c = 'cccc'

webpack 資源加載 - 主流程

1.Compiler.js - run,在 run 方法中執(zhí)行 this.compile()

Compiler.js - run

2.Compiler.js - compile,生成 Compiltaion 實例執(zhí)行 make hooks

Compiler.js - compile

make hooks 的實現(xiàn)在 SingleEntryPlugin 插件里,生成 SingleEntryDependency 調用 compilation 實例的 addEntry 方法.


SingleEntryPlugin.js

SingleEntryDependency

3.Compilation.js - addEntry - 處理入口 entry 執(zhí)行 _addModuleChain

addEntry 中把 SingleEntryPlugin 生成的 dep 也就是 entry 傳入執(zhí)行 _addModuleChain,發(fā)現(xiàn)執(zhí)行的 _addModuleChain 回調有在 this.entries 中 push 一個 module 的線索


4.Compilation.js - _addModuleChain - factory 創(chuàng)建 module - addModule 到 this.modules

_addModuleChain 創(chuàng)建 module,此時第一個 module 出現(xiàn),這個 module 是以為 entry 創(chuàng)建的


_addModuleChain 創(chuàng)建module

5.Compilation.js - _addModuleChain - addModule 把 module push 到 this.modules 中

執(zhí)行 addModule
addModule 中 this.modules.push module 并返回

5.Compilation.js - _addModuleChain - buildModule - 對 entry 的 module 進行 Loader 處理

buildModule 由 NormalModule.js 實現(xiàn),對遠嗎執(zhí)行 loader 并收集依賴


buildModule

此時 compilation 實例中 enties 和 modules 各自有一個 module , 這個 module 都是 entry 入口文件生成的。


此時 compilation 實例中 enties 和 module

此時 entry 的 module 已經分析出了 import 導入的模塊語法
module 的依賴

entry 的 module 的源碼也被 babel-loader 處理成了 ES5 的代碼


module 的源碼已經被 loader 處理

6.Compilation.js - _addModuleChain - afterBuild - 主入口 module 處理完畢

在 processModuleDependencies 中對 entry 的 module 的依賴進行遞歸調用 buildModule,分析出所有的 module 放入到 this.modules 中最后進入 seal 階段。此時 modues 已經不止 entry 的 module 了,把所有 import 語句導入的 module 都收集完畢。


資源加載收集完畢進入 seal 階段

Compilation.js - _addModuleChain 做了什么

1.傳入 entry 信息
2.moduleFactory 創(chuàng)建 entry 的 module, 添加到 this.modules 和 this.enties 中
3.調用 buildModule,對 entry 的 module 進行 loader 調用、分析 entry 源碼中的 import 導入模塊語句分析出依賴信息。
4.執(zhí)行 afterBuild 在 processModuleDependencies 中處理 entry module 的依賴文件,處理成 module 放入 this.modules 中,完成資源加載

buildModule

buildModule 中執(zhí)行當前 module 類型的 module.build


執(zhí)行 module.build

進入 NormalModule.js 的 doBuild 執(zhí)行 LoaderRunner.js 文件 runLoaders


執(zhí)行 doBuild 中的 runLoaders

這里遇到 LOADER_EXECUTION 函數(shù),里面 的 fn 就是 loader, args 是 loader 處理前的源碼


babel-loader 前

到這一步中間就在 loader 中執(zhí)行,經過 loader 出來后的代碼就是 arguments, 這里已經轉譯成 ES5 了, 執(zhí)行的 callback 是 doBuild 的回調


babel-loader 后

帶著 loader 處理后的源碼回到 doBuild 回調中走this.parser.parse 中


doBuild 回調執(zhí)行 parse

帶著 loader 處理后的源碼進入 parse 出來 ast 對象


帶著 loader 處理后的源碼進入 parse 出來 ast 對象

通過 acorn 三方模塊對源碼分析出 ast ,描述源碼的語義


ast 是源碼的語義描述

parse 最后就是返回一個 state,這時 state 中 module.dependencies 還是空的


parse 處理 ast

源碼生成的 ast 經過 walker 的處理,在 state 上分析出了所有 import 文件的信息


module.dependencies 分析完畢

用這種語法徹底描述出源碼中的依賴關系


用這種語法徹底描述出源碼中的依賴關系

此時 entry 文件的就處理完了,此時 compilation 實例上的 this.modules 仍然只有一個 entry module,但是現(xiàn)在 webpack 已經通過 ast 解析出了所有 entry module 中的依賴模塊的信息,后面就根據(jù)這些依賴信息生成各個模塊

資源遞歸收集依賴

對依賴進行處理,發(fā)現(xiàn)是 import 語義的依賴才進行處理


處理 ast 分析過的 module

處理收集 import 的依賴調用 addModuleDependencies,方法里與 buildModule 類似,工廠生成 module,addModule 加入到 this.modules 中,進行 loader 處理源碼


進入 addModuleDependencies

最后進入 afterBuild 判斷當前處理的 module 結果是否繼續(xù)有依賴進行遞歸處理
對結果分析進行遞歸

總結

1.Compiler.js - compiler.run 執(zhí)行 this.compile()
2.Compiler.js - compile,生成 Compiltaion 實例執(zhí)行 make hooks
3.Compilation.js - addEntry - 處理入口 entry 執(zhí)行 _addModuleChain
4._addModuleChain 使用工廠函數(shù)創(chuàng)建 module,使用 module 自己的 build
5.build 在 NormalModule 中執(zhí)行 doBuild 調用 LoaderRunner.js 的 runLoaders 使用 loader 處理源碼
6.loader 處理完源碼回到 doBuild 回調調用 Parser 的 parse
7.使用 acorn 分析源碼成 ast ,給 module.dependencies 添加依賴關系
8.根據(jù)依賴關系在 afterBuild 中調用 processModuleDependencies 遞歸處理依賴文件
9.最后把所有處理好的 module 都放入 compilation 實例的 this.modules 中進入 seal 階段

參考資源加載

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

相關閱讀更多精彩內容

  • 說在前面:這些文章均是本人花費大量精力研究整理,如有轉載請聯(lián)系作者并注明引用,謝謝本文的受眾人群不是webpack...
    RockSAMA閱讀 7,088評論 2 7
  • GitChat技術雜談 前言 本文較長,為了節(jié)省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,914評論 7 110
  • webpack 介紹 webpack 是什么 為什么引入新的打包工具 webpack 核心思想 webpack 安...
    yxsGert閱讀 6,681評論 2 71
  • webpack 核心 核心概述 entry 入口文件:js 代碼文件,可執(zhí)行的 node 模塊或打包的入口文件。 ...
    coolheadedY閱讀 3,614評論 1 6
  • 起床:5:026 體重: 昨日反思: 1、背會道德經第60章。 2、美協(xié)人員到學院交流座談會成功舉...
    水墨0801閱讀 87評論 0 0

友情鏈接更多精彩內容