成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

webpack原理

trigkit4 / 2624人閱讀

摘要:原理查看所有文檔頁面前端開發(fā)文檔,獲取更多信息。初始化階段事件名解釋初始化參數(shù)從配置文件和語句中讀取與合并參數(shù),得出最終的參數(shù)。以上處理的相關(guān)配置如下編寫編寫的職責(zé)由上面的例子可以看出一個(gè)的職責(zé)是單一的,只需要完成一種轉(zhuǎn)換。

webpack原理
查看所有文檔頁面:前端開發(fā)文檔,獲取更多信息。
原文鏈接:webpack原理,原文廣告模態(tài)框遮擋,閱讀體驗(yàn)不好,所以整理成本文,方便查找。
工作原理概括 基本概念

在了解 Webpack 原理前,需要掌握以下幾個(gè)核心概念,以方便后面的理解:

Entry:入口,Webpack 執(zhí)行構(gòu)建的第一步將從 Entry 開始,可抽象成輸入。

Module:模塊,在 Webpack 里一切皆模塊,一個(gè)模塊對應(yīng)著一個(gè)文件。Webpack 會從配置的 Entry 開始遞歸找出所有依賴的模塊。

Chunk:代碼塊,一個(gè) Chunk 由多個(gè)模塊組合而成,用于代碼合并與分割。

Loader:模塊轉(zhuǎn)換器,用于把模塊原內(nèi)容按照需求轉(zhuǎn)換成新內(nèi)容。

Plugin:擴(kuò)展插件,在 Webpack 構(gòu)建流程中的特定時(shí)機(jī)會廣播出對應(yīng)的事件,插件可以監(jiān)聽這些事件的發(fā)生,在特定時(shí)機(jī)做對應(yīng)的事情。

流程概括

Webpack 的運(yùn)行流程是一個(gè)串行的過程,從啟動(dòng)到結(jié)束會依次執(zhí)行以下流程:

初始化參數(shù):從配置文件和 Shell 語句中讀取與合并參數(shù),得出最終的參數(shù);

開始編譯:用上一步得到的參數(shù)初始化 Compiler 對象,加載所有配置的插件,執(zhí)行對象的 run 方法開始執(zhí)行編譯;

確定入口:根據(jù)配置中的 entry 找出所有的入口文件;

編譯模塊:從入口文件出發(fā),調(diào)用所有配置的 Loader 對模塊進(jìn)行翻譯,再找出該模塊依賴的模塊,再遞歸本步驟直到所有入口依賴的文件都經(jīng)過了本步驟的處理;

完成模塊編譯:在經(jīng)過第4步使用 Loader 翻譯完所有模塊后,得到了每個(gè)模塊被翻譯后的最終內(nèi)容以及它們之間的依賴關(guān)系;

輸出資源:根據(jù)入口和模塊之間的依賴關(guān)系,組裝成一個(gè)個(gè)包含多個(gè)模塊的 Chunk,再把每個(gè) Chunk 轉(zhuǎn)換成一個(gè)多帶帶的文件加入到輸出列表,這步是可以修改輸出內(nèi)容的最后機(jī)會;

輸出完成:在確定好輸出內(nèi)容后,根據(jù)配置確定輸出的路徑和文件名,把文件內(nèi)容寫入到文件系統(tǒng)。

在以上過程中,Webpack 會在特定的時(shí)間點(diǎn)廣播出特定的事件,插件在監(jiān)聽到感興趣的事件后會執(zhí)行特定的邏輯,并且插件可以調(diào)用 Webpack 提供的 API 改變 Webpack 的運(yùn)行結(jié)果。

流程細(xì)節(jié)

Webpack 的構(gòu)建流程可以分為以下三大階段:

初始化:啟動(dòng)構(gòu)建,讀取與合并配置參數(shù),加載 Plugin,實(shí)例化 Compiler。

編譯:從 Entry 發(fā)出,針對每個(gè) Module 串行調(diào)用對應(yīng)的 Loader 去翻譯文件內(nèi)容,再找到該 Module 依賴的 Module,遞歸地進(jìn)行編譯處理。

輸出:對編譯后的 Module 組合成 Chunk,把 Chunk 轉(zhuǎn)換成文件,輸出到文件系統(tǒng)。

如果只執(zhí)行一次構(gòu)建,以上階段將會按照順序各執(zhí)行一次。但在開啟監(jiān)聽模式下,流程將變?yōu)槿缦拢?/p>

在每個(gè)大階段中又會發(fā)生很多事件,Webpack 會把這些事件廣播出來供給 Plugin 使用,下面來一一介紹。

初始化階段
事件名 解釋
初始化參數(shù) 從配置文件和 Shell 語句中讀取與合并參數(shù),得出最終的參數(shù)。 這個(gè)過程中還會執(zhí)行配置文件中的插件實(shí)例化語句 new Plugin()。
實(shí)例化 Compiler 用上一步得到的參數(shù)初始化 Compiler 實(shí)例,Compiler 負(fù)責(zé)文件監(jiān)聽和啟動(dòng)編譯。Compiler 實(shí)例中包含了完整的 Webpack 配置,全局只有一個(gè) Compiler 實(shí)例。
加載插件 依次調(diào)用插件的 apply 方法,讓插件可以監(jiān)聽后續(xù)的所有事件節(jié)點(diǎn)。同時(shí)給插件傳入 compiler 實(shí)例的引用,以方便插件通過 compiler 調(diào)用 Webpack 提供的 API。
environment 開始應(yīng)用 Node.js 風(fēng)格的文件系統(tǒng)到 compiler 對象,以方便后續(xù)的文件尋找和讀取。
entry-option 讀取配置的 Entrys,為每個(gè) Entry 實(shí)例化一個(gè)對應(yīng)的 EntryPlugin,為后面該 Entry 的遞歸解析工作做準(zhǔn)備。
after-plugins 調(diào)用完所有內(nèi)置的和配置的插件的 apply 方法。
after-resolvers 根據(jù)配置初始化完 resolver,resolver 負(fù)責(zé)在文件系統(tǒng)中尋找指定路徑的文件。
空格 空格
空格 空格
空格 空格
編譯階段
事件名 解釋
run 啟動(dòng)一次新的編譯。
watch-run run 類似,區(qū)別在于它是在監(jiān)聽模式下啟動(dòng)的編譯,在這個(gè)事件中可以獲取到是哪些文件發(fā)生了變化導(dǎo)致重新啟動(dòng)一次新的編譯。
compile 該事件是為了告訴插件一次新的編譯將要啟動(dòng),同時(shí)會給插件帶上 compiler 對象。
compilation 當(dāng) Webpack 以開發(fā)模式運(yùn)行時(shí),每當(dāng)檢測到文件變化,一次新的 Compilation 將被創(chuàng)建。一個(gè) Compilation 對象包含了當(dāng)前的模塊資源、編譯生成資源、變化的文件等。Compilation 對象也提供了很多事件回調(diào)供插件做擴(kuò)展。
make 一個(gè)新的 Compilation 創(chuàng)建完畢,即將從 Entry 開始讀取文件,根據(jù)文件類型和配置的 Loader 對文件進(jìn)行編譯,編譯完后再找出該文件依賴的文件,遞歸的編譯和解析。
after-compile 一次 Compilation 執(zhí)行完成。
invalid 當(dāng)遇到文件不存在、文件編譯錯(cuò)誤等異常時(shí)會觸發(fā)該事件,該事件不會導(dǎo)致 Webpack 退出。
空格 空格
空格 空格

在編譯階段中,最重要的要數(shù) compilation 事件了,因?yàn)樵?compilation 階段調(diào)用了 Loader 完成了每個(gè)模塊的轉(zhuǎn)換操作,在 compilation 階段又包括很多小的事件,它們分別是:

事件名 解釋
build-module 使用對應(yīng)的 Loader 去轉(zhuǎn)換一個(gè)模塊。
normal-module-loader 在用 Loader 對一個(gè)模塊轉(zhuǎn)換完后,使用 acorn 解析轉(zhuǎn)換后的內(nèi)容,輸出對應(yīng)的抽象語法樹(AST),以方便 Webpack 后面對代碼的分析。
program 從配置的入口模塊開始,分析其 AST,當(dāng)遇到 require 等導(dǎo)入其它模塊語句時(shí),便將其加入到依賴的模塊列表,同時(shí)對新找出的依賴模塊遞歸分析,最終搞清所有模塊的依賴關(guān)系。
seal 所有模塊及其依賴的模塊都通過 Loader 轉(zhuǎn)換完成后,根據(jù)依賴關(guān)系開始生成 Chunk。
輸出階段
事件名 解釋
should-emit 所有需要輸出的文件已經(jīng)生成好,詢問插件哪些文件需要輸出,哪些不需要。
emit 確定好要輸出哪些文件后,執(zhí)行文件輸出,可以在這里獲取和修改輸出內(nèi)容。
after-emit 文件輸出完畢。
done 成功完成一次完成的編譯和輸出流程。
failed 如果在編譯和輸出流程中遇到異常導(dǎo)致 Webpack 退出時(shí),就會直接跳轉(zhuǎn)到本步驟,插件可以在本事件中獲取到具體的錯(cuò)誤原因。

在輸出階段已經(jīng)得到了各個(gè)模塊經(jīng)過轉(zhuǎn)換后的結(jié)果和其依賴關(guān)系,并且把相關(guān)模塊組合在一起形成一個(gè)個(gè) Chunk。 在輸出階段會根據(jù) Chunk 的類型,使用對應(yīng)的模版生成最終要要輸出的文件內(nèi)容。

輸出文件分析

雖然在前面的章節(jié)中你學(xué)會了如何使用 Webpack ,也大致知道其工作原理,可是你想過 Webpack 輸出的 bundle.js 是什么樣子的嗎? 為什么原來一個(gè)個(gè)的模塊文件被合并成了一個(gè)多帶帶的文件?為什么 bundle.js 能直接運(yùn)行在瀏覽器中? 本節(jié)將解釋清楚以上問題。

先來看看由 安裝與使用 中最簡單的項(xiàng)目構(gòu)建出的 bundle.js 文件內(nèi)容,代碼如下:

See the Pen bundle.js by whjin (@whjin) on CodePen.


這里的 bundle.js 和上面所講的 bundle.js 非常相似,區(qū)別在于:

多了一個(gè) __webpack_require__.e 用于加載被分割出去的,需要異步加載的 Chunk 對應(yīng)的文件;

多了一個(gè) webpackJsonp 函數(shù)用于從異步加載的文件中安裝模塊。

在使用了 CommonsChunkPlugin 去提取公共代碼時(shí)輸出的文件和使用了異步加載時(shí)輸出的文件是一樣的,都會有 __webpack_require__.ewebpackJsonp。 原因在于提取公共代碼和異步加載本質(zhì)上都是代碼分割。

編寫 Loader

Loader 就像是一個(gè)翻譯員,能把源文件經(jīng)過轉(zhuǎn)化后輸出新的結(jié)果,并且一個(gè)文件還可以鏈?zhǔn)降慕?jīng)過多個(gè)翻譯員翻譯。

以處理 SCSS 文件為例:

SCSS 源代碼會先交給 sass-loader 把 SCSS 轉(zhuǎn)換成 CSS;

sass-loader 輸出的 CSS 交給 css-loader 處理,找出 CSS 中依賴的資源、壓縮 CSS 等;

css-loader 輸出的 CSS 交給 style-loader 處理,轉(zhuǎn)換成通過腳本加載的 JavaScript 代碼;

可以看出以上的處理過程需要有順序的鏈?zhǔn)綀?zhí)行,先 sass-loadercss-loaderstyle-loader。 以上處理的 Webpack 相關(guān)配置如下:

See the Pen 編寫 Loader by whjin (@whjin) on CodePen.


監(jiān)聽文件變化

Webpack 會從配置的入口模塊出發(fā),依次找出所有的依賴模塊,當(dāng)入口模塊或者其依賴的模塊發(fā)生變化時(shí), 就會觸發(fā)一次新的 Compilation。

在開發(fā)插件時(shí)經(jīng)常需要知道是哪個(gè)文件發(fā)生變化導(dǎo)致了新的 Compilation,為此可以使用如下代碼:

See the Pen Compilation by whjin (@whjin) on CodePen.


閱讀需要支付1元查看
<