免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Webpack優(yōu)化--將你的構(gòu)建效率提速翻倍

作者:jerryOnlyZRJ

隨著構(gòu)建體系不斷完善、構(gòu)建體驗(yàn)不斷優(yōu)化,webpack 已經(jīng)逐漸成為了前端構(gòu)建體系的一大霸主,對(duì)于工作中的真正意義上的前端工程項(xiàng)目,webpack 已經(jīng)成為了我們前端構(gòu)建技術(shù)選型的不二選擇,包括 create-react-app 以及 vue-cli 等等業(yè)內(nèi)常見的腳手架工具的構(gòu)建體系,也都是基于 webpack 進(jìn)行了上層封裝。但隨著業(yè)務(wù)代碼不斷增加,項(xiàng)目深度不斷延伸,我們的構(gòu)建時(shí)長(zhǎng)也會(huì)因此不斷增加。漸漸的,總會(huì)有人拋出這樣的結(jié)論:webpack 構(gòu)建太慢了、太“重”了。就以筆者本次近期為團(tuán)隊(duì)優(yōu)化的項(xiàng)目為例,如下圖所示,我們可以看到,隨著項(xiàng)目的不斷堆砌以及一些不正確的引用,團(tuán)隊(duì)內(nèi)的項(xiàng)目單次構(gòu)建時(shí)長(zhǎng)已經(jīng)達(dá)到了40s,這就造成了工程師如果需要重啟 devServer 或者執(zhí)行 build,都會(huì)造成很不好的體驗(yàn)。

而經(jīng)過(guò)優(yōu)化后,二次啟動(dòng)的時(shí)長(zhǎng)能接近8s。那是什么樣的神仙操作能有如此效果呢?不著急,我們一步步往下看,只要你跟著我的步驟,或許只需要一個(gè)晚上,你也能將你們的團(tuán)隊(duì)項(xiàng)目的構(gòu)建體系做出進(jìn)一步優(yōu)化。

不過(guò)在正文開始之前,首先需要提前說(shuō)明一點(diǎn),本次文章介紹的構(gòu)建效率提升手段是基于 webpack4 進(jìn)行的,對(duì)于使用老版本的項(xiàng)目,如何從老版本升級(jí)到 webpack4 的流程我就不做過(guò)多介紹了,因?yàn)楦鞣N論壇上你都能搜到太多優(yōu)質(zhì)的文章了,所以對(duì)于大部分的基礎(chǔ)知識(shí),比如 webpack-dev-server 相關(guān)配置,還有一些常見的 plugin,在本文就不會(huì)較多提及。而對(duì)于那些持續(xù)跟進(jìn) webpack 版本的同學(xué),我相信你們也知道現(xiàn)階段 webpack5 也已經(jīng)呼之欲出了,下圖是官方給出的里程碑進(jìn)度,趁著目前只更新到64%,筆者趕緊先發(fā)一波文,或許到了5的時(shí)代,筆者今天所介紹的優(yōu)化方式,或許都已經(jīng)被集成到 webpack 自身的體系中了,誰(shuí)讓它一天天都在不斷變好呢??。

這一年來(lái),前前后后忙于畢業(yè)和工作,如今工作和生活也基本趨于穩(wěn)定,筆者也希望能像曾經(jīng)那樣,將自己的工作學(xué)習(xí)積淀,與大家悉數(shù)分享。作為筆者的開篇之作,希望在看完這篇文章后,能夠讓大家在工作中,對(duì)于如今前端而言不可或缺的構(gòu)建體系,有新的認(rèn)知以及更為大膽的嘗試。當(dāng)然,如果在這過(guò)程中遇到了問題,我也特別歡迎能和大家一塊交流、一塊學(xué)習(xí)、一塊進(jìn)步。

閑話不多說(shuō),接下來(lái)就進(jìn)入咱們本次的正題。

本文將以筆者在實(shí)踐中解決問題的思路為索引,逐步帶著大家以剖析問題 -> 發(fā)現(xiàn)問題 -> 解決問題的流程去了解對(duì)構(gòu)建體系進(jìn)行優(yōu)化的整個(gè)過(guò)程。

構(gòu)建打點(diǎn)

要做優(yōu)化,我們肯定得知道要從哪里做優(yōu)化對(duì)吧。那在我們的一次構(gòu)建流程中,是什么拉低了我們的構(gòu)建效率呢?我們有什么方法可以將它們測(cè)量出來(lái)呢?

要解決這兩個(gè)問題,我們需要用到一款工具:speed-measure-webpack-plugin,它能夠測(cè)量出在你的構(gòu)建過(guò)程中,每一個(gè) Loader 和 Plugin 的執(zhí)行時(shí)長(zhǎng),官方給出的效果圖是下面這樣:

而它的使用方法也同樣簡(jiǎn)單,如下方示例代碼所示,只需要在你導(dǎo)出 Webpack 配置時(shí),為你的原始配置包一層 smp.wrap 就可以了,接下來(lái)執(zhí)行構(gòu)建,你就能在 console 面板看到如它 demo 所示的各類型的模塊的執(zhí)行時(shí)長(zhǎng)。

  1. const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');

  2. const smp = new SpeedMeasurePlugin();

  3. module.exports = smp.wrap(YourWebpackConfig);

小貼士:由于 speed-measure-webpack-plugin 對(duì)于 webpack 的升級(jí)還不夠完善,目前(就筆者書寫本文的時(shí)候)還存在一個(gè) BUG,就是無(wú)法與你自己編寫的掛載在 html-webpack-plugin 提供的 hooks 上的自定義 Plugin (add-asset-html-webpack-plugin 就是此類)共存,因此,在你需要打點(diǎn)之前,如果存在這類 Plugin,請(qǐng)先移除,否則會(huì)產(chǎn)生如我這篇 issue 所提到的問題。

可以斷言的是,大部分的執(zhí)行時(shí)長(zhǎng)應(yīng)該都是消耗在編譯 JS、CSS 的 Loader 以及對(duì)這兩類代碼執(zhí)行壓縮操作的 Plugin 上,如果你的執(zhí)行結(jié)果和我所說(shuō)的一樣,請(qǐng)不要吝嗇你的手指,為我的文章點(diǎn)個(gè)好看吧??。

為什么會(huì)這樣呢?因?yàn)樵趯?duì)我們的代碼進(jìn)行編譯或者壓縮的過(guò)程中,都需要執(zhí)行這樣的一個(gè)流程:編譯器(這里可以指 webpack)需要將我們寫下的字符串代碼轉(zhuǎn)化成 AST(語(yǔ)法分析樹),就是如下圖所示的一個(gè)樹形對(duì)象:

顯而易見,編譯器肯定不能用正則去顯式替換字符串來(lái)實(shí)現(xiàn)這樣一個(gè)復(fù)雜的編譯流程,而編譯器需要做的就是遍歷這棵樹,找到正確的節(jié)點(diǎn)并替換成編譯后的值,過(guò)程就像下圖這樣:

大家一定還記得曾經(jīng)在學(xué)習(xí)《數(shù)據(jù)結(jié)構(gòu)與算法》或者是面試時(shí)候,被樹形結(jié)構(gòu)的各種算法虐待千百遍的日子吧,你一定也還記得深度優(yōu)先遍歷和廣度優(yōu)先遍歷的實(shí)現(xiàn)思路對(duì)吧??上攵詷?gòu)建時(shí)長(zhǎng)會(huì)集中消耗在代碼的編譯或壓縮過(guò)程中,正是因?yàn)樗鼈冃枰ケ闅v樹以替換字符或者說(shuō)轉(zhuǎn)換語(yǔ)法,因此都需要經(jīng)歷'轉(zhuǎn)化 AST -> 遍歷樹 -> 轉(zhuǎn)化回代碼'這樣一個(gè)過(guò)程,你說(shuō),它的時(shí)長(zhǎng)能不長(zhǎng)嘛。

優(yōu)化策略

既然我們已經(jīng)找到了拉低我們構(gòu)建速率的“罪魁禍?zhǔn)住?,接下?lái)我們就點(diǎn)對(duì)點(diǎn)逐個(gè)擊破了!這里,我就直接開門見山了,既然我們都知道構(gòu)建耗時(shí)的原因,自然就能得出針對(duì)性的方略。所以我們會(huì)從四個(gè)大方向入手:緩存、多核、抽離以及拆分,你現(xiàn)在看到這四個(gè)詞或許腦海里又能浮現(xiàn)出了一些熟悉的思路,這很棒,這樣的話你對(duì)我接下來(lái)將介紹的手段一定就能更快理解。

緩存

我們每次的項(xiàng)目變更,肯定不會(huì)把所有文件都重寫一遍,但是每次執(zhí)行構(gòu)建卻會(huì)把所有的文件都重復(fù)編譯一遍,這樣的重復(fù)工作是否可以被緩存下來(lái)呢,就像瀏覽器加載資源一樣?答案肯定是可以的,其實(shí)大部分 Loader 都提供了 cache 配置項(xiàng),比如在 babel-loader 中,可以通過(guò)設(shè)置 cacheDirectory 來(lái)開啟緩存,這樣,babel-loader 就會(huì)將每次的編譯結(jié)果寫進(jìn)硬盤文件(默認(rèn)是在項(xiàng)目根目錄下的node_modules/.cache/babel-loader目錄內(nèi),當(dāng)然你也可以自定義)。

但如果 loader 不支持緩存呢?我們也有方法。接下來(lái)介紹一款神器:cache-loader ,它所做的事情很簡(jiǎn)單,就是 babel-loader 開啟 cache 后做的事情,將 loader 的編譯結(jié)果寫入硬盤緩存,再次構(gòu)建如果文件沒有發(fā)生變化則會(huì)直接拉取緩存。而使用它的方法很簡(jiǎn)單,正如官方 demo 所示,只需要把它卸載在代價(jià)高昂的 loader 的最前面即可:

  1. module.exports = {

  2. module: {

  3. rules: [

  4. {

  5. test: /\.ext$/,

  6. use: ['cache-loader', ...loaders],

  7. include: path.resolve('src'),

  8. },

  9. ],

  10. },

  11. };

小貼士:cache-loader 默認(rèn)將緩存存放的路徑是項(xiàng)目根目錄下的 .cache-loader 目錄內(nèi),我們習(xí)慣將它配置到項(xiàng)目根目錄下的 node_modules/.cache 目錄下,與 babel-loader 等其他 Plugin 或者 Loader 緩存存放在一塊

同理,同樣對(duì)于構(gòu)建流程造成效率瓶頸的代碼壓縮階段,也可以通過(guò)緩存解決大部分問題,以 uglifyjs-webpack-plugin 這款對(duì)于我們最常用的 Plugin 為例,它就提供了如下配置:

  1. module.exports = {

  2. optimization: {

  3. minimizer: [

  4. new UglifyJsPlugin({

  5. cache: true,

  6. parallel: true,

  7. }),

  8. ],

  9. },

  10. };

我們可以通過(guò)開啟 cache 配置開啟我們的緩存功能,也可以通過(guò)開啟 parallel 開啟多核編譯功能,這也是我們下一章節(jié)馬上就會(huì)講到的知識(shí)。而另一款我們比較常用于壓縮 CSS 的插件—— optimize-css-assets-webpack-plugin,目前我還未找到有對(duì)緩存和多核編譯的相關(guān)支持,如果讀者在這塊領(lǐng)域有自己的沉淀,歡迎在評(píng)論區(qū)提出批正。

小貼士:目前而言筆者暫不建議將緩存邏輯集成到 CI 流程中,因?yàn)槟壳斑€仍會(huì)出現(xiàn)更新依賴后依舊命中緩存的情況,這顯然是個(gè) BUG,在開發(fā)機(jī)上我們可以手動(dòng)刪除緩存解決問題,但在編譯機(jī)上過(guò)程就要麻煩的多。為了保證每次 CI 結(jié)果的純凈度,這里建議在 CI 過(guò)程中還是不要開啟緩存功能。

多核

這里的優(yōu)化手段大家肯定已經(jīng)想到了,自然是我們的 happypack。這似乎已經(jīng)是一個(gè)老生常談的話題了,從3時(shí)代開始,happypack 就已經(jīng)成為了眾多 webpack 工程項(xiàng)目接入多核編譯的不二選擇,幾乎所有的人,在提到 webpack 效率優(yōu)化時(shí),怎么樣也會(huì)說(shuō)出 happypack 這個(gè)詞語(yǔ)。所以,在前端社區(qū)繁榮的今天,從 happypack 出現(xiàn)的那時(shí)候起,就有許多優(yōu)秀的質(zhì)量文如雨后春筍般層出不窮。所以今天在這里,對(duì)于 happypack 我就不做過(guò)多細(xì)節(jié)上的介紹了,想必大家對(duì)它也再熟悉不過(guò)了,我就帶著大家簡(jiǎn)單回顧一下它的使用方法吧。

  1. const HappyPack = require('happypack')

  2. const os = require('os')

  3. // 開辟一個(gè)線程池

  4. // 拿到系統(tǒng)CPU的最大核數(shù),happypack 將編譯工作灌滿所有線程

  5. const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })

  6. module.exports = {

  7. module: {

  8. rules: [

  9. {

  10. test: /\.(js|jsx)$/,

  11. exclude: /node_modules/,

  12. use: 'happypack/loader?id=js',

  13. },

  14. ],

  15. },

  16. plugins: [

  17. new HappyPack({

  18. id: 'js',

  19. threadPool: happyThreadPool,

  20. loaders: [

  21. {

  22. loader: 'babel-loader',

  23. },

  24. ],

  25. }),

  26. ],

  27. }

所以配置起來(lái)邏輯其實(shí)很簡(jiǎn)單,就是用 happypack 提供的 Plugin 為你的 Loaders 做一層包裝就好了,向外暴露一個(gè)id ,而在你的 module.rules 里,就不需要寫loader了,直接引用這個(gè) id 即可,所以趕緊用 happypack 對(duì)那些你測(cè)出來(lái)的代價(jià)比較昂貴的 loaders 們做一層多核編譯的包裝吧。

而對(duì)于一些編譯代價(jià)昂貴的 webpack 插件,一般都會(huì)提供 parallel 這樣的配置項(xiàng)供你開啟多核編譯,因此,只要你善于去它的官網(wǎng)發(fā)現(xiàn),一定會(huì)有意想不到的收獲噢~

PS:這里需要特別提及一個(gè)在 production 模式下容易遇到的坑,因?yàn)橛袀€(gè)特殊的角色出現(xiàn)了 —— mini-css-extract-plugin,坑在哪呢?有兩點(diǎn)(這也是筆者在書寫本文時(shí)還未解決的問題):

MiniCssExtractPlugin 無(wú)法與 happypack 共存,如果用 happypack 對(duì) MiniCssExtractPlugin 進(jìn)行包裹,就會(huì)觸發(fā)這個(gè)問題:github.com/amireh/happ… 。

MiniCssExtractPlugin 必須置于 cache-loader 執(zhí)行之后,否則無(wú)法生效,參考issue:github.com/webpack-con… 。

所以最后,在 production 模式下的 CSS Rule 配置就變成了下面這樣:

  1. module.exports = {

  2. ...,

  3. module: {

  4. rules: [

  5. ...,

  6. {

  7. test: /\.css$/

  8. exclude: /node_modules/,

  9. use: [

  10. _mode === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader,

  11. 'happypack/loader?id=css'

  12. ]

  13. }

  14. ]

  15. },

  16. plugins: [

  17. new HappyPack({

  18. id: 'css',

  19. threadPool: happyThreadPool,

  20. loaders: [

  21. 'cache-loader',

  22. 'css-loader',

  23. 'postcss-loader',

  24. ],

  25. }),

  26. ],

  27. }

抽離

對(duì)于一些不常變更的靜態(tài)依賴,比如我們項(xiàng)目中常見的 React 全家桶,亦或是用到的一些工具庫(kù),比如 lodash 等等,我們不希望這些依賴被集成進(jìn)每一次構(gòu)建邏輯中,因?yàn)樗鼈冋娴奶贂r(shí)候會(huì)被變更了,所以每次的構(gòu)建的輸入輸出都應(yīng)該是相同的。因此,我們會(huì)設(shè)法將這些靜態(tài)依賴從每一次的構(gòu)建邏輯中抽離出去,以提升我們每次構(gòu)建的構(gòu)建效率。常見的方案有兩種,一種是使用 webpack-dll-plugin 的方式,在首次構(gòu)建時(shí)候就將這些靜態(tài)依賴單獨(dú)打包,后續(xù)只需要引用這個(gè)早就被打好的靜態(tài)依賴包即可,有點(diǎn)類似“預(yù)編譯”的概念;另一種,也是業(yè)內(nèi)常見的 Externals的方式,我們將這些不需要打包的靜態(tài)資源從構(gòu)建邏輯中剔除出去,而使用 CDN 的方式,去引用它們。

那對(duì)于這兩種方式,我們又該如何選擇呢?

webpack-dll-plugin 與 Externals 的抉擇

團(tuán)隊(duì)早期的項(xiàng)目腳手架使用的是 webpack-dll-plugin 進(jìn)行靜態(tài)資源抽離,之所以這么做的原因是因?yàn)樵纫彩鞘褂玫?Externals,但是由于公司早期 CDN 服務(wù)并不成熟,項(xiàng)目使用了線上開源的 CDN 卻因?yàn)榉?wù)不穩(wěn)定導(dǎo)致了團(tuán)隊(duì)項(xiàng)目出現(xiàn)問題的情況,所以在一次迭代中統(tǒng)一替換成了 webpack-dll-plugin,但隨著公司建立起了成熟的 CDN 服務(wù)后,團(tuán)隊(duì)的腳手架卻因?yàn)楦鞣N原因遲遲沒再更新。

而我,是堅(jiān)定的 Externals 的支持著,這不是心之所向,先讓我們來(lái)細(xì)數(shù) webpack-dll-plugin 的三宗原罪:

需要配置在每次構(gòu)建時(shí)都不參與編譯的靜態(tài)依賴,并在首次構(gòu)建時(shí)為它們預(yù)編譯出一份 JS 文件(后文將稱其為 lib 文件),每次更新依賴需要手動(dòng)進(jìn)行維護(hù),一旦增刪依賴或者變更資源版本忘記更新,就會(huì)出現(xiàn) Error 或者版本錯(cuò)誤。

無(wú)法接入瀏覽器的新特性 script type='module',對(duì)于某些依賴庫(kù)提供的原生 ES Modules 的引入方式(比如 vue 的新版引入方式)無(wú)法得到支持,沒法更好地適配高版本瀏覽器提供的優(yōu)良特性以實(shí)現(xiàn)更好地性能優(yōu)化。

將所有資源預(yù)編譯成一份文件,并將這份文件顯式注入項(xiàng)目構(gòu)建的 HTML 模板中,這樣的做法,在 HTTP1 時(shí)代是被推崇的,因?yàn)槟菢幽軠p少資源的請(qǐng)求數(shù)量,但在 HTTP2 時(shí)代如果拆成多個(gè) CDN Link,就能夠更充分地利用 HTTP2 的多路復(fù)用特性??谡f(shuō)無(wú)憑,直接上圖驗(yàn)證結(jié)論:

  • 使用 webpack-dll-plugin 生成的 lib 文件,整體資源作為一個(gè)文件加載,需要 400 多毫秒

  • 使用 Externals 配合 HTTP2,所有資源并行加載,整體時(shí)長(zhǎng)不超過(guò) 100ms

這,就是我選擇 Externals 的原因。

但是,如果你的公司沒有成熟的 CDN 服務(wù),但又想對(duì)項(xiàng)目中的靜態(tài)依賴進(jìn)行抽離該怎么辦呢?那筆者的建議還是選擇 webpack-dll-plugin 來(lái)優(yōu)化你的構(gòu)建效率。如果你還是覺得每次更新依賴都需要去維護(hù)一個(gè) lib 文件特別麻煩,那我還是特別提醒你,在使用 Externals 時(shí)選擇一個(gè)靠譜的 CDN 是一件特別重要的事,畢竟這些依賴比如 React 都是你網(wǎng)站的骨架,少了他們可是連站點(diǎn)都運(yùn)行不起來(lái)了噢。

如何更為優(yōu)雅地編寫 Externals

我們都知道,在使用 Externals 的時(shí)候,還需要同時(shí)去更新 HTML 里面的 CDN,有時(shí)候時(shí)常會(huì)忘記這一過(guò)程而導(dǎo)致一些錯(cuò)誤發(fā)生。那作為一名追求極致的前端,我們是否可以嘗試?yán)矛F(xiàn)有資源將這一過(guò)程自動(dòng)化呢?

這里我就給大家提供一個(gè)思路,我們先來(lái)回顧及分析一下,在我們配置 Externals 時(shí),需要配置那些部分。首先,在 webpack.config.js 配置文件內(nèi),我們需要添加 webpack 配置項(xiàng):

  1. module.exports = {

  2. ...,

  3. externals: {

  4. // key是我們 import 的包名,value 是CDN為我們提供的全局變量名

  5. // 所以最后 webpack 會(huì)把一個(gè)靜態(tài)資源編譯成:module.export.react = window.React

  6. 'react': 'React',

  7. 'react-dom': 'ReactDOM',

  8. 'redux': 'Redux',

  9. 'react-router-dom': 'ReactRouterDOM'

  10. }

  11. }

與此同時(shí),我們需要在模板 HTML 文件中同步更新我們的 CDN script 標(biāo)簽,一般一個(gè)常見的 CDN Link 就像這樣:

https://cdn.bootcss.com/react/16.9.0/umd/react.production.min.js

這里以 BootCDN 提供的靜態(tài)資源 CDN 為例(但不代表筆者推薦使用 BootCDN 提供的 CDN 服務(wù),它上次更換域名的事件可真是讓我踩了不少坑),我們可以發(fā)現(xiàn),一份 CDN Link 其實(shí)主要也只是由四部分組成,它們分別是:CDN 服務(wù) host、包名、版本號(hào)以及包路徑,其他 CDN 服務(wù)也是同理。以上面的 Link 為例,這四部分對(duì)應(yīng)的內(nèi)容就是:

CDN 服務(wù) host:cdn.bootcss.com/包名:react版本號(hào):16.9.0包路徑:umd/react.production.min.js

到了這一步,大家應(yīng)該想到了吧。我們完全可以自己編寫一個(gè) webpack 插件去自動(dòng)生成 CDN Link script 標(biāo)簽并掛載在 html-webpack-plugin 提供的事件鉤子上以實(shí)現(xiàn)自動(dòng)注入 HTML,而我們所需要的一個(gè) CDN Link 的四部分內(nèi)容,CDN 服務(wù) host 我們只需要與公司提供的服務(wù)統(tǒng)一即可,包名我們可以通過(guò) compiler.options.externals 拿到,而版本號(hào)我們只需要讀取項(xiàng)目的 package.json 文件即可,最后的包路徑,一般都是一個(gè)固定的值。

具體代碼實(shí)現(xiàn)我就不作詳細(xì)介紹了,團(tuán)隊(duì)在項(xiàng)目腳手架更新迭代期間,筆者已經(jīng)根據(jù)公司提供的 CDN 服務(wù)定制了一款 Webpack 插件,實(shí)現(xiàn)邏輯就如上述所示,所以后續(xù)工程師們就不再需要去關(guān)注同步 script 標(biāo)簽了,一切都被集成進(jìn) Plugin 邏輯自動(dòng)化處理了,當(dāng)然,大家如果對(duì)插件的源碼有興趣,可以在評(píng)論區(qū)提出噢~筆者會(huì)考慮作為團(tuán)隊(duì)的開源項(xiàng)目貢獻(xiàn)給社區(qū)。

拆分

雖然說(shuō)在大前端時(shí)代下,SPA 已經(jīng)成為主流,但我們不免還是會(huì)有一些項(xiàng)目需要做成 MPA(多頁(yè)應(yīng)用),得益于 webpack 的多 entry 支持,因此我們可以把多頁(yè)都放在一個(gè) repo 下進(jìn)行管理和維護(hù)。但隨著項(xiàng)目的逐步深入和不斷迭代,代碼量必然會(huì)不斷增大,有時(shí)候我們只是更改了一個(gè) entry 下的文件,但是卻要對(duì)所有 entry 執(zhí)行一遍構(gòu)建,因此,這里為大家介紹一個(gè)集群編譯的概念:

什么是集群編譯呢?這里的集群當(dāng)然不是指我們的真實(shí)物理機(jī),而是我們的 docker。其原理就是將單個(gè) entry 剝離出來(lái)維護(hù)一個(gè)獨(dú)立的構(gòu)建流程,并在一個(gè)容器內(nèi)執(zhí)行,待構(gòu)建完成后,將生成文件打進(jìn)指定目錄。為什么能這么做呢?因?yàn)槲覀冎?,webpack 會(huì)將一個(gè) entry 視為一個(gè) chunk,并在最后生成文件時(shí),將 chunk 單獨(dú)生成一個(gè)文件.

因?yàn)槿缃駡F(tuán)隊(duì)在實(shí)踐前端微服務(wù),因此每一個(gè)子模塊都被拆分成了一個(gè)單獨(dú)的repo,因此我們的項(xiàng)目與生俱來(lái)就繼承了集群編譯的基因,但是如果把這些子項(xiàng)目以 entry 的形式打在一個(gè) repo 中,也是一個(gè)很常見的情況,這時(shí)候,就需要進(jìn)行拆分,集群編譯便能發(fā)揮它的優(yōu)勢(shì)。因?yàn)閳F(tuán)隊(duì)里面不需要進(jìn)行相關(guān)實(shí)踐,因此這里筆者就不提供細(xì)節(jié)介紹了,只是為大家提供一個(gè)方向,如果大家有疑問也歡迎在評(píng)論區(qū)與我討論。

提升體驗(yàn)

這里主要是介紹幾款 webpack 插件來(lái)幫助大家提升構(gòu)建體驗(yàn),雖然說(shuō)它們?cè)谔嵘龢?gòu)建效率上對(duì)你沒有什么太大的幫助,但能讓你在等待構(gòu)建完成的過(guò)程中更加舒服。

progress-bar-webpack-plugin

這是一款能為你展示構(gòu)建進(jìn)度的 Plugin,它的使用方法和普通 Plugin 一樣,也不需要傳入什么配置。下圖就是你加上它之后,在你的終端面板上的效果,在你的終端底部,將會(huì)有一個(gè)構(gòu)建的進(jìn)度條,可以讓你清晰的看見構(gòu)建的執(zhí)行進(jìn)度:

webpack-build-notifier

這是一款在你構(gòu)建完成時(shí),能夠像微信、Lark這樣的APP彈出消息的方式,提示你構(gòu)建已經(jīng)完成了。也就是說(shuō),當(dāng)你啟動(dòng)構(gòu)建時(shí),就可以隱藏控制臺(tái)面板,專心去做其他事情啦,到“點(diǎn)”了自然會(huì)來(lái)叫你,它的效果就是下面這樣,同時(shí)還有提示音噢~

webpack-dashboard

當(dāng)然,如果你對(duì) webpack 原始的構(gòu)建輸出不滿意的話,也可以使用這樣一款 Plugin 來(lái)優(yōu)化你的輸出界面,它的效果就是下面這樣,這里我就直接上官圖啦:

總結(jié)

綜上所述,其實(shí)本質(zhì)上,我們對(duì)與webpack構(gòu)建效率的優(yōu)化措施也就兩個(gè)大方向:緩存和多核。緩存是為了讓二次構(gòu)建時(shí),不需要再去做重復(fù)的工作;而多核,更是充分利用了硬件本身的優(yōu)勢(shì)(我相信現(xiàn)如今大家的電腦肯定都是雙核以上了吧,我自己這臺(tái)公司發(fā)的低配 MAC 都有雙核),讓我們的復(fù)雜工作都能充分利用我們的 CPU。而將這兩個(gè)方向化為實(shí)踐的主角,也是我們前面介紹過(guò)的兩大王牌,就是:cache-loader 和 happypack,所以你只要知道它并用好它,那你就能做到更好的構(gòu)建優(yōu)化實(shí)踐。所以,別光看看,快拿著你的項(xiàng)目動(dòng)手實(shí)踐下,讓你優(yōu)化后的團(tuán)隊(duì)項(xiàng)目在你的 leader 面前眼前一亮吧!

但是,大家一定要記著,這些東西并不是說(shuō)用了效果就一定會(huì)是最好的,我們一定要切記把它們用在刀刃上,就是那些在第一階段我們通過(guò)打點(diǎn)得出的構(gòu)建代價(jià)高昂的 Loader 或者 Plugin,因?yàn)槲覀冎?,像本地緩存就需要讀寫硬盤文件,系統(tǒng)IO需要時(shí)間,像啟動(dòng)多核也需要 IPC 通信時(shí)間,也就是說(shuō),如果本來(lái)構(gòu)建時(shí)長(zhǎng)就不長(zhǎng)的模塊,有可能因?yàn)樘砑恿司彺婊蛘叨嗪藭?huì)有得不償失的結(jié)果,因此這些優(yōu)化手段也需要合理的分配和使用。

如今,webpack 自身也在不斷的迭代與優(yōu)化,它早就已經(jīng)不是兩三年前那個(gè)一直讓我們吐槽構(gòu)建慢、包袱重的構(gòu)建新星了,之所以會(huì)成為主流,也正是因?yàn)?webpack 團(tuán)隊(duì)已經(jīng)在效率及體驗(yàn)上為我們做出很多了,而我們需要做的,已經(jīng)很少了,而且我堅(jiān)信,將來(lái)還會(huì)更少。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
你真的理解 Webpack?請(qǐng)回答下列問題
babel 版本原因運(yùn)行報(bào)錯(cuò),解決辦法
javascript – 語(yǔ)法錯(cuò)誤 – 目前尚未啟用對(duì)實(shí)驗(yàn)語(yǔ)法’decorators-legacy’的支持
webpack.config.js和package.json
前端模塊化工具-webpack 
Vue 項(xiàng)目架構(gòu)設(shè)計(jì)與工程化實(shí)踐
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服