精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Webpack5 實(shí)踐 - 構(gòu)建效率倍速提升!

開(kāi)發(fā) 開(kāi)發(fā)工具
對(duì)于前端構(gòu)建工具 Webpack、babel、eslint 等的每一次升級(jí),就像剛剛經(jīng)歷一場(chǎng)地震似得,最不想面對(duì)的就是處理各種 API 的不兼容性,有時(shí)還會(huì)出現(xiàn)一些奇奇怪怪的問(wèn)題,為什么還要升呢?并不是為了給自己找事,還是要講究投入產(chǎn)出比的,也就是最終的收益是要大于產(chǎn)出比的。

 [[409156]]

本文轉(zhuǎn)載自微信公眾號(hào)「五月君」,作者五月君。轉(zhuǎn)載本文請(qǐng)聯(lián)系五月君公眾號(hào)。  

對(duì)于前端構(gòu)建工具 Webpack、babel、eslint 等的每一次升級(jí),就像剛剛經(jīng)歷一場(chǎng)地震似得,最不想面對(duì)的就是處理各種 API 的不兼容性,有時(shí)還會(huì)出現(xiàn)一些奇奇怪怪的問(wèn)題,為什么還要升呢?并不是為了給自己找事,還是要講究投入產(chǎn)出比的,也就是最終的收益是要大于產(chǎn)出比的。

前段在團(tuán)隊(duì)內(nèi)部對(duì) Webpack v5 帶來(lái)的一些新特性做一些 Research,相較于一些項(xiàng)目的構(gòu)建工具版本(Webpack v3)做了一個(gè)對(duì)比,在構(gòu)建效率這塊是有質(zhì)的飛躍的,同樣相對(duì)于 Webpack v4 也是有很大提升的。本文是本次升級(jí)過(guò)程中的實(shí)踐(踩坑)記錄,分享一些值得關(guān)注的功能、一些重大的改變、遇到的一些 NPM 組建兼容性問(wèn)題,希望能給予讀者朋友一些參考和幫助。

先上一張腦圖,涵蓋本文主題!

構(gòu)建效果對(duì)比

基于一些項(xiàng)目做了一些測(cè)試,首次構(gòu)建相較于之前提速將近 2 倍多,二次構(gòu)建差不多 2s 左右,效果更顯著,修改文件后的增量構(gòu)建,差不多也在幾秒鐘可完成,整體構(gòu)建效率提升還是很明顯的,除此之外打包后的文件大小也比之前小了一些,但之間的差距不是特別的大,重點(diǎn)還是構(gòu)建效率大幅提升。

構(gòu)建效率上之所以有這么大的性能提升,這與它的基于文件系統(tǒng)的持久化緩存是有很大幫助的,下文會(huì)講解。內(nèi)部的項(xiàng)目數(shù)據(jù)就不便再這里展示了,文末提供了一些來(lái)自社區(qū)的實(shí)踐,也可以看到一些數(shù)據(jù)對(duì)比。

下面,基于之前 Research 時(shí)寫(xiě)的一些 Demo 可以對(duì)比下使用了持久化緩存在初次構(gòu)建、二次無(wú)文件改動(dòng)構(gòu)建、改動(dòng)文件后增量構(gòu)建三種情況下的效果對(duì)比,也可以顯著的看到一些效果。

代碼壓縮(生產(chǎn)環(huán)境)

JavaScript 代碼壓縮

Webpack5 在生產(chǎn)環(huán)境下默認(rèn)使用自帶的 TerserPlugin 插件(無(wú)需安裝)來(lái)做代碼壓縮,這個(gè)插件也被認(rèn)為是在代碼壓縮方面性能是較好的。無(wú)需再借助 UglifyjsPlugin、ParallelUglifyPlugin 這些插件了。

如果你使用的是 webpack4 版本需要手動(dòng)安裝 yarn add terser-webpack-plugin -D 并將插件添加到生產(chǎn)環(huán)境的配置文件中。

以下是使用示例,在 Webpack v5 的生產(chǎn)環(huán)境默認(rèn)開(kāi)啟。

  1. const TerserPlugin = require("terser-webpack-plugin"); 
  2.  
  3. module.exports = { 
  4.   optimization: { 
  5.     minimize: true
  6.     minimizer: [new TerserPlugin()], 
  7.   }, 
  8. }; 

支持做一些自定義的配置:文件過(guò)濾、并發(fā)運(yùn)行等,詳細(xì)參見(jiàn) Webpack 文檔 TerserWebpackPlugin[1]。

  • test:匹配需要壓縮的文件。
  • include:匹配包含的目錄。
  • exclude:匹配不需要包含的目錄。
  • parallel:多進(jìn)程并發(fā)運(yùn)行,默認(rèn) os.cpus().length - 1。
  1. module.exports = { 
  2.   optimization: { 
  3.     minimize: true
  4.     minimizer: [ 
  5.       new TerserPlugin({ 
  6.         test: /\.js(\?.*)?$/i, 
  7.         include: /\/includes/, 
  8.         exclude: /\/excludes/, 
  9.         parallel: true 
  10.         // more ... 
  11.       }), 
  12.     ], 
  13.   }, 
  14. }; 

CSS 文件分離

CSS 壓縮之前先做的一項(xiàng)工作是 CSS 和 JS 文件分離,如果是從 Webpack v3 升級(jí)到 v5 會(huì)遇到一些問(wèn)題,之前使用的是 extract-text-webpack-plugin 在 webpack v5 會(huì)收到廢棄提醒,建議使用 **MiniCssExtractPlugin** 這個(gè)插件,本插件基于 webpack v4 的新特性(模塊類型)構(gòu)建。

與 extract-text-webpack-plugin 相比,擁有這些特性:異步加載、沒(méi)有重復(fù)的編譯(性能提升)、更容易使用、特別針對(duì) CSS 開(kāi)發(fā)。

下面是一個(gè)配置,這里還有些優(yōu)化,生產(chǎn)模式使用 mini-css-extract-plugin 插件分離 JS/CSS 文件實(shí)現(xiàn)并行加載,而開(kāi)發(fā)環(huán)境選擇 style-loader 它可以使用多個(gè)標(biāo)簽將 CSS 插入到 DOM 中,并且反應(yīng)會(huì)更快。

  1. const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 
  2. module.exports = { 
  3.   module: { 
  4.     rules: [ 
  5.       { 
  6.         test: /\.css$/i, 
  7.         use: [ 
  8.           devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 
  9.           'css-loader' 
  10.         ], 
  11.       }, 
  12.     ], 
  13.   }, 
  14.   plugins: [new MiniCssExtractPlugin()], 
  15. }; 

關(guān)于 CSS 分割插件的更詳細(xì)配置 Webpack 文檔 mini-css-extract-plugin[2]。

CSS 打包后加載圖片 404?

生產(chǎn)環(huán)境我們使用 mini-css-extract-plugin 插件分離 CSS 文件,如果你在 CSS 里引用了圖片,可能會(huì)遇到為什么打包后 CSS 里引用的圖片加載時(shí) 404 了?

在 Webpack 的 output 選項(xiàng)中有一個(gè) publicPath 配置,它指定了應(yīng)用程序中所有資源的基礎(chǔ)路徑。

  1. module.exports = { 
  2.   output: { 
  3.     publicPath: 'auto' 
  4.   } 

Webpack loader 的 options 選項(xiàng)中也有一個(gè) publicPath 配置,為 CSS 內(nèi)的圖片、文件等外部資源指定一個(gè)自定義的公共路徑,默認(rèn)值為 output.publicPath。如果出現(xiàn)打包后 CSS 內(nèi)圖片 404 的可以檢查下這里的配置是否有問(wèn)題。

  1. const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 
  2. module.exports = { 
  3.   module: { 
  4.     rules: [ 
  5.       { 
  6.         test: /\.css$/i, 
  7.         use: [ 
  8.           devMode ? 'style-loader' : { 
  9.             loader: MiniCssExtractPlugin.loader, 
  10.             options: { 
  11.               publicPath: '../' 
  12.             } 
  13.           }, 
  14.         ], 
  15.       }, 
  16.     ], 
  17.   }, 
  18.   plugins: [new MiniCssExtractPlugin()], 
  19. }; 

CSS 代碼壓縮

CSS 壓縮之前會(huì)使用 optimize-css-assets-webpack-plugin 這個(gè)插件,在 webpack v5 之后推薦使用 css-minimizer-webpack-plugin 這個(gè)插件。

  1. const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); 
  2. module.exports = { 
  3.   optimization: { 
  4.     minimizer: [ 
  5.       new CssMinimizerPlugin(), 
  6.     ], 
  7.   }, 
  8. }; 

性能提升核心緩存優(yōu)化

之前通過(guò) cache-loader、babel-loader?cacheDirectory 在配置 cacheDirectory:true 實(shí)現(xiàn)將編譯結(jié)果寫(xiě)入磁盤或者通過(guò) hard-source-webpack-plugin 插件。

Webpack5 自帶緩存能力,會(huì)緩存生成的 webpack module 和 chunk,對(duì)于二次構(gòu)建有了很大的性能提升。通過(guò) cache 屬性配置,分為內(nèi)存和文件兩種緩存方式,默認(rèn)在生產(chǎn)環(huán)境是禁用的,需自行開(kāi)啟。

基于內(nèi)存緩存

當(dāng)在開(kāi)發(fā)環(huán)境默認(rèn)設(shè)置為 memory,基于內(nèi)存的緩存,除了下面的方式配置外,也可通過(guò) cache: true 配置。

  1. module.exports = { 
  2.   cache: { 
  3.     type: 'memory' 
  4.   }, 
  5. }; 

基于 FileSystem 的持久化緩存

基于內(nèi)存的緩存,只有在服務(wù)運(yùn)行中,才有效,每次的單獨(dú)構(gòu)建是利用不了緩存的,webpack5 對(duì)于緩存另一個(gè)比較好的功能是提供了基于文件系統(tǒng)的持久化緩存。

基于文件系統(tǒng)的持久化緩存無(wú)論在單獨(dú)構(gòu)建或連續(xù)構(gòu)建(可以指熱更新操作)中都可應(yīng)用,首先它會(huì)查看內(nèi)存緩存,如果未命中,則降級(jí)到文件系統(tǒng)緩存。

應(yīng)用很簡(jiǎn)單,設(shè)置 type:filesystem。默認(rèn)情況下它位于 node_modules/.cache/webpack/ 目錄,我們還可以通過(guò) name 屬性修改它的名稱,例如,我們通過(guò)不同的環(huán)境 NODE_ENV 來(lái)區(qū)別不同環(huán)境的緩存。

當(dāng) type 設(shè)置為 filesystem 后,有很多屬性是可以配置的,參見(jiàn) Webpack 文檔 cache[3]。

  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem'
  4.     buildDependencies: { 
  5.       config: [__filename], 
  6.     }, 
  7.     name: `${ process.env.NODE_ENV || 'development'}-cache` 
  8.   } 

緩存失效

基于內(nèi)存的緩存每一次重新運(yùn)行都是一次新的構(gòu)建。需要注意的是持久化緩存,當(dāng)你修改了文件或傳遞了一些參數(shù),發(fā)現(xiàn)最終展現(xiàn)的效果沒(méi)有被更改,通常這與持久化緩存的緩存策略相關(guān)。

出于性能考慮,緩存會(huì)跳過(guò) node_modules 認(rèn)為這會(huì)極大降低 webpack 執(zhí)行速度,建議是不要手動(dòng)編輯 node_modules。通常也不會(huì)這么干直接去修改 node_modules。

有些操作也會(huì)使緩存失效,例如:當(dāng) NPM 升級(jí) loader、plugin、更改配置等。

Webpack 提供了 buildDependencies、name、version 三種方式可以使構(gòu)建緩存失效。

方法一:cache.buildDependencies

buildDependencies 指定構(gòu)建過(guò)程中受影響的代碼依賴,默認(rèn)為 webpack/lib,當(dāng) node_modules 中的 webpack 或其依賴項(xiàng)發(fā)生任何變化,當(dāng)前的緩存即失效。

還有一個(gè)是指定的配置文件 config: [__filename] 或配置文件的依賴項(xiàng)發(fā)生變化,也會(huì)失效。

  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem'
  4.     buildDependencies: { 
  5.       defaultWebpack: ["webpack/lib/"], 
  6.       config: [__filename], 
  7.     }, 
  8.     name: `${ process.env.NODE_ENV || 'development'}-cache` 
  9.   } 

方法二:cache.version

如果是把構(gòu)建工具封裝為一個(gè)單獨(dú)的工具包,類似于 react-scripts 這種的,理論上每次升級(jí)工具包,就需要重新編譯的,之前在一次本地測(cè)試時(shí)發(fā)現(xiàn)工具包升級(jí)后緩存沒(méi)有失效,如果出現(xiàn)這種情況的可以在 cache 里加上 version 配置指向 package.json 里的 version。

  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem'
  4.     version: `${packageJson.version}` 
  5.   } 

有時(shí)配置文件或者代碼沒(méi)有修改,但是會(huì)依賴于命令行傳遞值想使緩存失效,同樣也可在 version 上加上這些命令行傳遞的值做為版本控制。

  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem'
  4.     version: `${process.env.CLI_VALUE}` 
  5.   } 

當(dāng) version 依賴于多個(gè)值時(shí),可以將多個(gè)值做個(gè) md5 生成一串唯一的字符串做為版本也可。

方法三:cache.name

name 屬性比較好的是可以保存多個(gè)緩存目錄,例如通過(guò) process.env.NODE_ENV 區(qū)分不同的環(huán)境。

  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem'
  4.     name: `${ process.env.NODE_ENV || 'development'}-cache` 
  5.   } 

持久化緩存這塊也有很多的東西可以講,詳情參見(jiàn) [譯] webpack 5 之持久化緩存[4]。

長(zhǎng)期緩存優(yōu)化

Webpack 5 新增了長(zhǎng)期緩存算法,以確定性的方式為模塊和分塊分配短的(3 或 5 位)數(shù)字 ID,這是包大小和長(zhǎng)期緩存之間的一種權(quán)衡,生產(chǎn)環(huán)境默認(rèn)開(kāi)啟以下配置。在減小文件打包大小同時(shí)也利于瀏覽器長(zhǎng)期緩存(不會(huì)因?yàn)閯h除或新增一個(gè)模塊而導(dǎo)致大量緩存文件失效)。

  1. // production default 
  2. module.exports = { 
  3.   optimization: { 
  4.     moduleIds: 'deterministic'
  5.     chunkIds: 'deterministic' 
  6.     mangleExports: 'deterministic' 
  7.   } 

Webpack v5 VS v4 模塊 ID

Webpack v4 及之前的 moduleId 默認(rèn)是自增的,例如 0.xxx.js、1.xxx.css、2.xxx.js 如果更改模塊數(shù)量(即使內(nèi)容沒(méi)有變化),也會(huì)導(dǎo)致模塊文件重新發(fā)生改變,不利于長(zhǎng)期緩存。

不同的版本也提供了不同的解決方案,webpack v4 之前使用 HashedModuleIdsPlugin 插件覆蓋默認(rèn)的模塊 ID 規(guī)則,在 webpack v4 中可以配置 optimization.moduleIds = 'hashed' 解決。這幾種方案都是使用模塊路徑生成的 hash 做為 moduleId。

Webpack v5 生產(chǎn)環(huán)境默認(rèn) optimization.moduleIds='deterministic' 無(wú)需更改。

Webpack v5 VS v4 Chunk ID

webpack v4 及之前的 chunkId 默認(rèn)也是遞增的,如果在 entry 配置中新增或刪除一個(gè)元素,chunkId 也會(huì)隨著遞增或遞減。

webpack v4 之前使用 NamedChunksPlugin 插件覆蓋默認(rèn)的 chunkId 規(guī)則,在 webpack v4 中可以配置 optimization.chunkIds = 'named' 解決。

Webpack v5 生產(chǎn)環(huán)境默認(rèn) optimization.chunkIds='deterministic' 無(wú)需更改。

真正的內(nèi)容哈希

另外,當(dāng)使用 [contenthash] 時(shí),webpack5 將使用真正的文件內(nèi)容做為哈希值,這個(gè)類似于協(xié)商緩存 Etag,不一樣的是還有一些優(yōu)化,如果你只是刪除了代碼中的一些注釋或重新命名變量,而這種情況代碼邏輯是沒(méi)有修改的,這些變化在壓縮后是不可見(jiàn)的,不會(huì)導(dǎo)致 [contenthash] 也發(fā)生變化。

如果是從 webpack v3 升級(jí)到 v5 的,HashedModuleIdsPlugin、NamedChunksPlugin 這些插件是可以去掉的,webpack v5 環(huán)境默認(rèn)開(kāi)啟新的算法,無(wú)需再配置。

參考文檔 Webpack release 日志記錄 — 重大變更:長(zhǎng)期緩存[5]。

原生支持資源模塊

Webpack v5 內(nèi)置了資源模塊(assert),用來(lái)處理資源文件(圖片、字體等),在之前是通過(guò)配置額外的 loader,例如 raw-loader、file-loader、url-loader 實(shí)現(xiàn)的。

Webpack v4 資源文件處理

下面是一段 webpack v4 及之前版本的資源文件處理配置,當(dāng)匹配的文件大小如果小于 limit 限制,將其處理成 data URI 內(nèi)聯(lián)到 bundle 中,否則生成文件(使用 file-loader)輸出到目錄中,url-loader 內(nèi)置了 file-loader 對(duì)文件的處理。

  1.   test: /\.(jpe?g|png|gif|svg)$/, 
  2.   use: [ 
  3.     { 
  4.       loader: 'url-loader'
  5.       options: { 
  6.         limit: 1024 * 10 
  7.       } 
  8.     } 
  9.   ] 
  10. }, 

Webpack v5 新的資源文件處理

Webpack v5 不再需要安裝 url-loader 處理資源文件,內(nèi)置了資源模塊類型,通過(guò) type 定義,用來(lái)替換之前需要額外配置 loader 的方式。

  • asset/resource:將文件打包輸出并導(dǎo)出 URL,類似于 file-loader。
  • asset/inline:導(dǎo)出一個(gè)資源的 data URI,編碼到 bundle 中輸出,類似于 url-loader。
  • asset/source:導(dǎo)出資源的源代碼,類似于 raw-loader。
  • asset:提供了一種通用的資源類型,根據(jù)設(shè)置的 Rule.parser.dataUrlCondition.maxSize 自動(dòng)的在 asset/resource、asset/inline 之間做選擇,小于該大小指定的文件視為 inline 模塊類型,否則視為 resource 模塊類型。

下面是一個(gè)示例,大于 4kb 的輸出到目錄 static 中。

  1.   test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i, 
  2.   type: "asset"
  3.   parser: { 
  4.     dataUrlCondition: { 
  5.       maxSize: 4 * 1024 // 4kb 
  6.     } 
  7.   }, 
  8.   generator: { 
  9.     filename: 'static/[hash][ext][query]' 
  10.   } 
  11. }, 

參考文檔 Webpack 文檔 Assert module[6]。

強(qiáng)大的 tree-shaking 能力

tree-shaking 是一個(gè)術(shù)語(yǔ),翻譯為中文為 “樹(shù)搖”,想想一下一顆長(zhǎng)滿果子的樹(shù)木,其中有些已經(jīng)熟透了,當(dāng)搖晃樹(shù)木時(shí)是不是一部分會(huì)被搖掉。

[[409157]]

圖片來(lái)源:https://cdn.pixabay.com/photo/2019/05/16/23/39/apple-tree-4208594_1280.jpg

對(duì)于我們代碼層面來(lái)說(shuō),那些上下文未引用的 JavaScript 代碼,也可以通過(guò)工具移除(“搖掉”),實(shí)現(xiàn)打包體積的優(yōu)化。

嵌套的 tree-shaking

在這種情況下,可以刪除未使用的變量 b,生產(chǎn)環(huán)境默認(rèn)開(kāi)啟。

  1. // inner.js 
  2. export const a = 1; 
  3. export const b = 2; 
  4.  
  5. // module.js 
  6. export * as inner from './inner'
  7.  
  8. // user.js 
  9. import * as module from './module'
  10. console.log(module.inner.a); 

內(nèi)部模塊 tree-shaking

Webpack v5 還增加了模塊導(dǎo)出和引用之間的依賴關(guān)系分析,通過(guò)配置 optimization.innerGraph 控制,生產(chǎn)環(huán)境默認(rèn)開(kāi)啟。

以下示例,something 只有在使用 test 導(dǎo)出時(shí)才會(huì)使用。

  1. import { something } from './something'
  2.  
  3. function usingSomething() { 
  4.   return something; 
  5.  
  6. export function test() { 
  7.   return usingSomething(); 

支持 CommonJS Tree Shaking

新增 CommonJS 模塊的導(dǎo)出和引用之間的依賴分析,下例,可以刪除未使用的變量 b。

  1. // inner.js 
  2. exports.a = 1; 
  3. exports.b = 2; 
  4.  
  5. // module.js 
  6. exports.inner = require('./inner'); 
  7.  
  8. // user.js 
  9. const module = require('./module'); 
  10. console.log(module.inner.a); 

參考 Webpack 文檔 tree-shaking[7]。

Node.js 調(diào)用 webpack API

之前在團(tuán)隊(duì)內(nèi)部,基于 webpack 這些構(gòu)建工具封裝了適合團(tuán)隊(duì)內(nèi)部的構(gòu)建工具模塊,是通過(guò) API 調(diào)用的,有些問(wèn)題還是要注意下。

生產(chǎn)環(huán)境

調(diào)用 webpack() 創(chuàng)建一個(gè) compiler 實(shí)例,之后調(diào)用 run() 方法執(zhí)行,需要注意的是在完成之后記得關(guān)閉 compiler,這樣低優(yōu)先級(jí)的工作(比如持久緩存)就有機(jī)會(huì)完成,否則,有時(shí)候會(huì)發(fā)現(xiàn)每次都是重新構(gòu)建沒(méi)有利用上緩存。

下例中的 stats 參數(shù)可以獲取到代碼編譯過(guò)程產(chǎn)生的錯(cuò)誤和警告、計(jì)時(shí)信息、module 和 chunk 信息,如果想達(dá)到 cli 環(huán)境下的日志輸出格式,調(diào)用 stats.toString() 方法即可。

  1. const compiler = webpack(config); 
  2. return new Promise((resolve, reject) => { 
  3.   compiler.run((err, stats) => { 
  4.     if (err) { 
  5.       return reject(err); 
  6.     } 
  7.  
  8.     console.log(stats.toString({ 
  9.       chunks: false
  10.       colors: true 
  11.     })); 
  12.  
  13.     compiler.close(closeErr => { 
  14.       if (closeErr) { 
  15.         console.log(chalk.red(`compiler close failed with message ${closeErr.message}`)); 
  16.       } 
  17.     }); 
  18.  
  19.     return resolve(stats); 
  20.   }); 
  21. }); 

開(kāi)發(fā)環(huán)境

與生產(chǎn)環(huán)境 API 調(diào)用不同,開(kāi)發(fā)環(huán)境我們需要熱更新,在創(chuàng)建一個(gè) compiler 后需要調(diào)用 webpack-dev-server 插件。

還有個(gè)問(wèn)題是 devServer 中的配置選項(xiàng)將被忽略,但可以將配置選項(xiàng)作為第二個(gè)參數(shù)傳入。

  1. const compiler = webpack(config); 
  2. const devServerOptions = Object.assign({}, config.devServer, { 
  3.   port: port, 
  4.   host: DEFAULT_HOST, 
  5.   opentrue
  6. }); 
  7. const server = new WebpackDevServer(compiler, devServerOptions); 
  8. server.listen(port, DEFAULT_HOST); 

參考文檔 Webpack 文檔 Node.js API 接口[8]。

原生 Web Worker 支持

從 webpack 5 開(kāi)始,使用 Web Workers 代替 worker-loader,這種語(yǔ)法也是為了實(shí)現(xiàn)不使用 bundler 就可以運(yùn)行代碼。

Web Worker 是解決一些密集型的任務(wù),例如一些加解密、圖片處理等一些耗時(shí)的計(jì)算任務(wù)可以放置于工作線程處理,處理完畢在通知到主線程,在處理的過(guò)程不會(huì)影響用戶在界面上的一些其它操作。

  1. const worker = new Worker(new URL('./worker-calculate.js', import.meta.url)); 
  2. worker.postMessage({ 
  3.   question: 
  4.     'The Answer to the Ultimate Question of Life, The Universe, and Everything.'
  5. }); 
  6. worker.onmessage = ({ data: { answer } }) => { 
  7.   console.log(answer); 
  8. }; 
  9.  
  10. // worker-calculate.js 
  11. self.onmessage = ({ data: { question } }) => { 
  12.   self.postMessage({ 
  13.     answer: 42, 
  14.   }); 
  15. }; 

Web Workers 可以在瀏覽器中的原生 ECMAScript 模塊中使用,也可以用于 Node.js 中,如果采用 ESM 模塊規(guī)范,Node.js 需要 >= 12.17.0。

  1. import { Worker } from 'worker_threads'
  2. new Worker(new URL('./worker.js', import.meta.url)); 

Node.js 通過(guò) worker_threads 模塊提供支持,在 Node.js 中如果你使用 CommonJS 規(guī)范在 v10.0.5 版本就已經(jīng)支持了。

  1. const { Worker } = require('worker_threads'); 

更多詳情參考 webpack 文檔 Web Workers[9]。

其它 NPM 組件兼容性問(wèn)題

開(kāi)發(fā)環(huán)境熱更新

如果是從 webpack v3.x 升級(jí)的,會(huì)發(fā)現(xiàn)之前的熱更新方式會(huì)報(bào)如下錯(cuò)誤。

  1. Error: Cannot find module 'webpack/bin/config-yargs' 

Webpack v5 使用 webpack serve 啟動(dòng)開(kāi)發(fā)環(huán)境,解決這個(gè)問(wèn)題就是重新安裝 webpack-cli、還有 webpack-dev-server 也是需要安裝的。

  1. // For webpack-cli 3.x: 
  2. "scripts": { "start:dev""webpack-dev-server" } 
  3.  
  4. // For webpack-cli 4.x: 
  5. "scripts": { "start:dev""webpack serve" } 

問(wèn)題參考 cannot-find-module-webpack-bin-config-yargs。

compiler.plugin is not a function with InterpolateHtmlPlugin

可能會(huì)遇到以下錯(cuò)誤:

  1. TypeError: compiler.plugin is not a function 
  2.     at InterpolateHtmlPlugin.apply (/Users/qufei/Documents/code/f-designer-tool-webpack5-test/node_modules/react-dev-utils/InterpolateHtmlPlugin.js:25:14) 

單獨(dú)安裝插件 yarn add -D interpolate-html-plugin 替換 InterpolateHtmlPlugin = require('react-dev-utils/interpolate-html-plugin'); 為 const InterpolateHtmlPlugin = require('interpolate-html-plugin');

最后確保 InterpolateHtmlPlugin 出現(xiàn)在插件列表中的 HtmlWebpackPlugin 之后。

webpack.NamedModulesPlugin is not a constructor with NamedModulesPlugin

當(dāng)開(kāi)啟 HMR 的時(shí)候使用該插件會(huì)顯示模塊的相對(duì)路徑,該插件已廢棄,在 Webpack4 中建議設(shè)置為 optimization.namedModules,但是在 Webpack5 也被廢棄,如果需要請(qǐng)改為 optimization.moduleIds: 'named',在 Webpack5 中的建議是 “請(qǐng)考慮將 optimization.moduleIds 和 optimization.chunkIds 從你 webpack 配置中移除。使用默認(rèn)值會(huì)更合適,因?yàn)樗鼈儠?huì)在 production 模式 下支持長(zhǎng)效緩存且可以在 development 模式下進(jìn)行調(diào)試。” 參見(jiàn) https://webpack.docschina.org/migrate/5/#clean-up-configuration

移除 Node.js 模塊 Polyfills

Webpack5 移除了 Node.js 模塊的 Polyfills,更專注于前端模塊兼容。認(rèn)為這會(huì)在構(gòu)建時(shí)給 bundle 附加龐大的 Polyfills,大部分情況下也并非必須的,如果你的模塊或你安裝的第三方模塊引用了 cypto、process 這些模塊,就會(huì)看到報(bào)錯(cuò)。

  1. process is not a function 
  2. xxx is not a function 

參考 automatic-nodejs-polyfills-removed,對(duì)于 webpack v5,可以從 webpack.config.js 的相應(yīng)插件部分引用 process/browser。

參考 webpack-bundle-js-uncaught-referenceerror-process-is-not-defined。

  1. const webpack = require('webpack'
  2. module.exports = { 
  3.   plugins: [ 
  4.     // fix "process is not defined" error: 
  5.     // (do "npm install process" before running the build) 
  6.     new webpack.ProvidePlugin({ 
  7.       process: 'process/browser'
  8.     }), 
  9.   ] 

compiler.plugin is not a function with react-dev-utils/WatchMissingNodeModulesPlugin

  1. new WatchMissingNodeModulesPlugin(), 
  2.  
  3. // 運(yùn)行之后報(bào)錯(cuò) 
  4. // TypeError: compiler.plugin is not a function 
  5. //      at WatchMissingNodeModulesPlugin.apply (/Users/xxx/node_modules/react-dev-utils/WatchMissingNodeModulesPlugin.js:20:14) 

這個(gè)錯(cuò)誤是在 Webpack 4 upgrade PR,升級(jí) react-dev-utils yarn add react-dev-utils -D。

babel-eslint has been deprecated

之前在使用 eslint 代碼檢查時(shí),如果有用到 eslint 不支持的試驗(yàn)性特性時(shí)會(huì)需要用到 babel-eslint,但是這個(gè)項(xiàng)目已經(jīng)廢棄了,到官網(wǎng)會(huì)看到這樣一句話:

  1. babel-eslint is now @babel/eslint-parser. This package will no longer receive updates. 

現(xiàn)在推薦使用 @babel/eslint-parser 代替。

更多新功能

  • Top Level Await 支持:目前在 Webpack v5 計(jì)劃中屬于試驗(yàn)性支持,可通過(guò)開(kāi)啟 experiments.topLevelAwait 配置支持,這對(duì)于文件頭部初始化資源很有用,無(wú)需讓 await 必須在 async 里面。參考 Webpack v5 配置#experiments。
  • 模塊聯(lián)邦(Federated Modules):是 webpack v5 增加的一個(gè)新功能,為前端項(xiàng)目打包模式提供了新的方式,對(duì)多個(gè)不存在依賴關(guān)系的多個(gè)項(xiàng)目可以獨(dú)立構(gòu)建組成一個(gè)應(yīng)用程序,從開(kāi)發(fā)者的角度看,模塊可以從遠(yuǎn)程構(gòu)建中導(dǎo)入。這通常稱為微前端,也并不僅限于此。更多可參考 Webpack 提供的單獨(dú)指南 module-federation,也可看看下面的社區(qū)實(shí)踐。
  • 原生支持 WebAssembly 構(gòu)建:webpack v5 原生支持了 WebAssembly 的代碼構(gòu)建,只需開(kāi)啟 experiments.syncWebAssembly 配置即可,這個(gè)功能也屬于試驗(yàn)性支持。
  • ... 更多功能參考 webpack v5 release 日志。

來(lái)自社區(qū)實(shí)踐

  • 字節(jié):Webpack5 新特性業(yè)務(wù)落地實(shí)戰(zhàn)
  • 騰訊:構(gòu)建效率大幅提升,webpack5 在企鵝輔導(dǎo)的升級(jí)實(shí)踐
  • 螞蟻:調(diào)研 Federated Modules,應(yīng)用秒開(kāi),應(yīng)用集方案,微前端加載方案改進(jìn)等
  • 百度:Webpack 5 升級(jí)實(shí)驗(yàn)
  • 飛書(shū):Webpack5 上手測(cè)評(píng)

因?yàn)槲⑿艑?duì)外鏈的限制,文中有些鏈接不能打開(kāi),可以 “閱讀原文” 查看。

參考資料

[1]Webpack 文檔 TerserWebpackPlugin: https://webpack.docschina.org/plugins/terser-webpack-plugin/

[2]Webpack 文檔 mini-css-extract-plugin: https://webpack.docschina.org/plugins/mini-css-extract-plugin

[3]Webpack 文檔 cache: https://webpack.docschina.org/configuration/other-options/#cache

[4][譯] webpack 5 之持久化緩存: https://juejin.cn/post/6844903967793627149

[5]Webpack release 日志記錄 — 重大變更:長(zhǎng)期緩存: https://webpack.docschina.org/blog/2020-10-10-webpack-5-release/#major-changes-long-term-caching

[6]Webpack 文檔 Assert module: https://webpack.docschina.org/guides/asset-modules/

[7]Webpack 文檔 tree-shaking: https://www.webpackjs.com/guides/tree-shaking/

[8]Webpack 文檔 Node.js API 接口: https://webpack.docschina.org/api/node/

[9]webpack 文檔 Web Workers: https://webpack.docschina.org/guides/web-workers/

 

責(zé)任編輯:武曉燕 來(lái)源: 五月君
相關(guān)推薦

2022-01-20 10:56:53

Webpack5持久化緩存

2022-04-13 08:04:40

項(xiàng)目應(yīng)用程序代碼

2021-12-24 08:01:44

Webpack優(yōu)化打包

2022-09-02 09:09:25

項(xiàng)目ReactES6

2021-09-27 08:16:38

Webpack 前端Cache

2022-09-23 15:23:08

webpack5改變代碼

2023-04-27 08:35:20

Webpack 4性能優(yōu)化

2021-12-19 07:21:48

Webpack 前端插件機(jī)制

2021-12-21 14:00:25

WebpackDevServer的開(kāi)發(fā)

2015-11-11 16:36:22

OceanStor存儲(chǔ)華為

2017-05-02 16:29:11

Webpack技巧建議

2017-03-24 10:56:21

Webpack技巧建議

2025-09-05 09:31:23

2009-07-20 09:51:55

提升Windows20企業(yè)部署

2023-11-03 15:33:22

Docker鏡像云計(jì)算

2025-02-04 10:00:30

Spring支付系統(tǒng)

2015-11-05 17:58:22

2019-10-18 15:35:16

Python編程語(yǔ)言高級(jí)用法

2024-03-28 08:43:42

webpack代碼true?
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

精品一区三区| 嫩草香蕉在线91一二三区| 国产欧美日韩一级| 亚洲一品av免费观看| 久国产精品视频| 欧美xxx黑人xxx水蜜桃| 久久亚洲欧美国产精品乐播| 国产精品视频一区国模私拍| 久久国产露脸精品国产| 国产精品亚洲人成在99www| 欧美久久久久久蜜桃| 日本午夜激情视频| 日本精品在线| 日韩国产欧美三级| 亚洲欧美国产精品久久久久久久| 日本在线播放一区二区| 欧美调教sm| 亚洲精品老司机| 日韩欧美一区二区三区四区| 隣の若妻さん波多野结衣| 日本色综合中文字幕| 久久久免费电影| 成人信息集中地| 欧美色图婷婷| 精品久久久久一区| 日韩成人精品视频在线观看| 美女100%一区| 亚洲第一精品在线| 国产精品久久成人免费观看| 国外av在线| 99久久国产综合精品色伊 | 亚洲图片在线视频| 一区二区三区四区在线观看国产日韩| 亚洲精品一区二三区不卡| 香蕉视频1024| 99tv成人影院| 欧美日韩成人综合| 国产福利一区视频| 忘忧草在线影院两性视频| 一区二区三区四区国产精品| 中文视频一区视频二区视频三区| 久久久久久久影视| 91免费看`日韩一区二区| 成人精品在线视频| 黄色av一区二区| 亚洲欧美日韩视频二区| 亚洲97在线观看| 国产精品成人免费一区二区视频| 自拍视频亚洲| 欧美精品在线免费观看| 天天操夜夜操av| 色999日韩| 中文字幕免费精品一区高清| 少妇无套高潮一二三区| 久久99久久人婷婷精品综合| 亚洲男女自偷自拍图片另类| 30一40一50老女人毛片| 欧美日韩导航| 亚洲精品天天看| 亚洲黄色在线网站| 欧美女王vk| 在线视频欧美日韩| 亚洲精品国产精品乱码在线观看| 欧美艳星介绍134位艳星| 中文字幕欧美精品在线| 国产免费一区二区三区四区| 久久久久久美女精品| 久久精品国产亚洲精品| 国产a免费视频| 伊人青青综合网| 久久999免费视频| 国产在线成人精品午夜| 亚洲国产清纯| 欧亚精品中文字幕| 欧美一级黄视频| 精品影视av免费| 91亚色免费| 欧美 日韩 国产 成人 在线| 99久久精品99国产精品| 日本一区精品| 黄色免费在线观看网站| 亚洲午夜av在线| 久久婷婷国产精品| 国产原创一区| 日韩一卡二卡三卡国产欧美| 亚洲欧美高清在线| 国产精品一区二区三区av麻 | 国产日韩1区| 日本成人激情视频| 中文字幕在线看人| 九色综合狠狠综合久久| 成人av免费电影| 免费a级片在线观看| 91麻豆精品在线观看| 亚洲精品无人区| 婷婷色在线播放| 91久久精品午夜一区二区| 亚洲午夜激情影院| 美女福利一区| 久久精品99国产精品酒店日本 | 在哪里可以看毛片| 久久久久久久久久久9不雅视频| 国模吧一区二区| 在线免费观看中文字幕| 成人免费视频一区二区| 天堂精品一区二区三区| 欧美韩日亚洲| 欧美日韩免费高清一区色橹橹| 美国黄色一级视频| 日韩av二区| 欧美一级高清免费| 精品久久国产视频| 中文字幕精品一区二区精品绿巨人| 91免费国产精品| 成人黄色毛片| 精品一区二区电影| 精品一区二区三区人妻| 免费av成人在线| 国产一区二区无遮挡| 秋霞a级毛片在线看| 粉嫩老牛aⅴ一区二区三区| 亚洲欧美日韩精品一区| 美日韩中文字幕| 欧美国产亚洲视频| 在线观看日批视频| 久久久久久久久伊人| 国产美女主播在线| 久久国产精品美女| 俺去亚洲欧洲欧美日韩| 中文字幕黄色片| 99re视频这里只有精品| 日本中文字幕一级片| 亚洲精品无播放器在线播放| 亚洲人成网站免费播放| 天堂网av手机版| a亚洲天堂av| 大荫蒂性生交片| 成人噜噜噜噜| 久久九九国产精品怡红院| 国产精品成人久久久| 26uuuu精品一区二区| 国产美女主播在线| 一区二区在线视频观看| 俺去亚洲欧洲欧美日韩| 91片黄在线观看喷潮| 国产日韩精品一区| 男人操女人免费| 日本欧美韩国国产| 91地址最新发布| 亚洲三区在线观看无套内射| 性做久久久久久免费观看欧美| 亚洲精品久久久久久| 中文精品久久| 91久色国产| www中文字幕在线观看| 欧美videofree性高清杂交| 精品99久久久久成人网站免费| 精品制服美女丁香| 女同性恋一区二区| 欧美专区一区| 欧美黑人巨大xxx极品| 欧美视频在线观看一区二区三区| 一区二区三区四区亚洲| 欧美精品一区二区蜜臀亚洲| heyzo一本久久综合| 欧美精品一区二区三区四区五区| 18av在线播放| 日韩欧美一区二区免费| 成熟的女同志hd| 国产精品中文字幕欧美| 欧美日韩中文字幕在线播放| 欧美另类中文字幕| 欧美国产日韩一区二区在线观看| 日本波多野结衣在线| 亚洲欧洲另类国产综合| 国产又粗又长又爽又黄的视频| 91国语精品自产拍| 国产精品久久波多野结衣| 美女扒开腿让男人桶爽久久软| 日韩精品视频在线免费观看| 国产九色91回来了| 亚洲女性喷水在线观看一区| 亚洲精品第二页| 久久久蜜桃一区二区人| 在线观看成人av电影| 成人51免费| 亚洲91av视频| www.视频在线.com| 欧美成人在线直播| 99精品在线播放| 国产精品的网站| 大尺度在线观看| 日本最新不卡在线| 久久香蕉视频网站| 久久99国产精品视频| 成人写真福利网| 伊人网在线播放| 久久久精品国产一区二区| 人人妻人人澡人人爽久久av| 欧美日韩一区二区在线视频| 欧美精品乱码视频一二专区| 97超碰欧美中文字幕| 成人亚洲免费视频| 亚洲免费影院| 麻豆视频传媒入口| 蜜桃视频欧美| 成人一区二区三区四区| 成人一级视频| 91av在线国产| av在线下载| 在线观看精品国产视频| 日本高清视频在线| 91精品国产乱码久久蜜臀| 99精品人妻国产毛片| 一区二区三区四区在线播放| 欧美激情视频二区| 97久久超碰精品国产| 特级西西444www| 日韩av一区二区三区| 国产精品久久中文字幕| 亚洲一区二区| 正在播放精油久久| 精品福利久久久| 精品国产乱码久久久久| 香蕉大人久久国产成人av| 国产精品视频内| 另类激情视频| 热99精品里视频精品| 丁香花在线电影小说观看| 久久久精品视频在线观看| 97在线观看免费观看高清| 亚洲精品久久久久久久久| 丰满少妇被猛烈进入| 91精品国产综合久久久蜜臀图片| 国内av在线播放| 色婷婷综合久久| 国产精品男女视频| 欧美日韩国产激情| 国产乱码久久久久久| 一区二区三区在线视频观看58| 亚洲a∨无码无在线观看| 国产调教视频一区| 中文字幕一区二区三区人妻不卡| 成人国产一区二区三区精品| wwwww在线观看| 国产精品1区2区| 天天爽夜夜爽视频| 国产毛片精品一区| 精品国产午夜福利在线观看| 国产专区欧美精品| 久久久久久久久久久久久久久国产| 久久se这里有精品| 波多野结衣国产精品| 国产综合色视频| 在线播放黄色av| 国产精品小仙女| 欧美熟妇精品一区二区| 成人综合在线观看| 大桥未久恸哭の女教师| 成人av片在线观看| 亚洲一区二区三区四区五区六区| 91一区二区在线观看| 草草影院第一页| 欧美激情一二三区| 三上悠亚在线观看视频| 亚洲欧美乱综合| 久久在线视频精品| 欧美日韩亚洲成人| 日本a级c片免费看三区| 欧洲一区在线电影| 国产一区二区在线播放视频| 日韩亚洲欧美成人一区| 丰满少妇被猛烈进入| 亚洲伦理中文字幕| 欧美69xxx| 欧美激情视频在线免费观看 欧美视频免费一| 女人天堂av在线播放| 51精品在线观看| 国产精品4hu.www| 91免费版黄色| 九九免费精品视频在线观看| 亚洲色图自拍| 伊人成人网在线看| www黄色在线| 国产精品99久久久久久久女警| 无码人妻精品一区二区三区99不卡| 久久免费精品国产久精品久久久久| 美国美女黄色片| 亚洲一区二区三区在线播放| 国产免费一级视频| 日韩亚洲欧美一区二区三区| 蜜桃免费在线| 久久99国产综合精品女同| 另类专区亚洲| 成人h在线播放| 欧美日韩在线网站| 97超碰国产精品| 人人精品人人爱| 成人做爰www看视频软件| 欧美激情资源网| 日本一级黄色录像| 欧美丰满嫩嫩电影| 瑟瑟在线观看| 色在人av网站天堂精品| 成人精品电影在线| 成人国产1314www色视频| 日韩1区2区| 国产精品视频一区二区三区四区五区 | 国产精品免费99久久久| 激情视频小说图片| 日韩精品福利网| 国产精品久久无码| 亚洲精品福利视频网站| 成人免费一区二区三区| 日韩激情av在线免费观看| 一二三四区在线观看| 国产精品综合不卡av| 亚洲毛片免费看| 岛国大片在线播放| 国产乱码精品一区二区三区忘忧草 | 欧美成人性色生活仑片| 99只有精品| 日韩精品欧美一区二区三区| 99精品视频免费观看| 亚洲欧美激情一区二区三区| 国产精品国产精品国产专区不蜜 | 6080午夜不卡| 91社区在线| 国产不卡精品视男人的天堂| 另类ts人妖一区二区三区| 国产午夜精品视频一区二区三区| 久久se精品一区精品二区| 国产高潮呻吟久久| 欧美日韩国产中文字幕| 神马久久久久久久久久| 欧美高清第一页| 日韩08精品| 狠狠精品干练久久久无码中文字幕| 久久66热偷产精品| 国产免费美女视频| 欧美乱熟臀69xxxxxx| 免费av在线| 成人免费在线视频网站| 亚洲电影影音先锋| 在线观看免费视频污| |精品福利一区二区三区| 国产美女三级无套内谢| 久久精品视频在线播放| 国产精品一级在线观看| 糖心vlog在线免费观看| 丁香亚洲综合激情啪啪综合| 九九视频免费看| 精品日产卡一卡二卡麻豆| 超黄网站在线观看| 久久精品欧美| 日韩制服丝袜av| 毛片视频免费播放| 在线不卡中文字幕| 中文字幕伦理免费在线视频| 成人影片在线播放| 日韩午夜激情| 最新中文字幕av| 欧美精品久久久久久久久老牛影院| 麻豆影院在线观看| 99久热re在线精品视频| 999亚洲国产精| 李宗瑞91在线正在播放| 欧美日本精品一区二区三区| 日本美女在线中文版| 成人女人免费毛片| 老妇喷水一区二区三区| 精品日韩在线视频| 欧美日韩一二三区| 韩国日本一区| 欧美日韩免费观看一区| 美国十次了思思久久精品导航| 国产一区二区三区在线视频观看| 精品久久一区二区| 久久天堂av| 国产91视频一区| 91丨九色丨国产丨porny| 亚洲性在线观看| 久久久天堂国产精品女人| 国产剧情一区| 亚洲911精品成人18网站| 欧美性色视频在线| 韩国av网站在线| 精品日产一区2区三区黄免费 | 91福利小视频| 色女人在线视频| 日本一区二区在线| 国产成人av电影在线观看| 国产亚洲欧美在线精品| 欧美乱妇高清无乱码| 国产精品嫩模av在线| 少妇极品熟妇人妻无码| 精品视频一区二区三区免费| sm在线观看| 中文字幕欧美日韩一区二区| 91在线视频观看|