生產

在本指南中,我們將深入探討一些最佳實務和實用工具,以建立生產環境網站或應用程式。

設定

開發生產 建置的目標大不相同。在 開發 中,我們需要強大的來源對應和具有即時重新載入或熱模組替換功能的本機主機。在 生產 中,我們的目標轉移到縮小的套件、較輕量的來源對應和最佳化的資產,以改善載入時間。有了這個邏輯區分,我們通常建議為每個環境撰寫 獨立的 webpack 設定檔

雖然我們會將生產開發專屬的區塊分開,但請注意,我們仍會維護一個「共用」組態,以保持 DRY。為了合併這些組態,我們將使用一個名為 webpack-merge 的工具程式。有了「共用」組態後,我們就不必在環境專屬組態中重複程式碼。

讓我們從安裝 webpack-merge 和拆分我們已在先前指南中處理的區塊開始

npm install --save-dev webpack-merge

專案

  webpack-demo
  |- package.json
  |- package-lock.json
- |- webpack.config.js
+ |- webpack.common.js
+ |- webpack.dev.js
+ |- webpack.prod.js
  |- /dist
  |- /src
    |- index.js
    |- math.js
  |- /node_modules

webpack.common.js

+ const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
+
+ module.exports = {
+   entry: {
+     app: './src/index.js',
+   },
+   plugins: [
+     new HtmlWebpackPlugin({
+       title: 'Production',
+     }),
+   ],
+   output: {
+     filename: '[name].bundle.js',
+     path: path.resolve(__dirname, 'dist'),
+     clean: true,
+   },
+ };

webpack.dev.js

+ const { merge } = require('webpack-merge');
+ const common = require('./webpack.common.js');
+
+ module.exports = merge(common, {
+   mode: 'development',
+   devtool: 'inline-source-map',
+   devServer: {
+     static: './dist',
+   },
+ });

webpack.prod.js

+ const { merge } = require('webpack-merge');
+ const common = require('./webpack.common.js');
+
+ module.exports = merge(common, {
+   mode: 'production',
+ });

webpack.common.js 中,我們現在已設定我們的 entryoutput 組態,並包含了兩個環境都需要的任何外掛程式。在 webpack.dev.js 中,我們已將 mode 設定為 development。此外,我們已新增建議的 devtool 以供該環境(強大的原始碼對應),以及我們的 devServer 組態。最後,在 webpack.prod.js 中,mode 設定為 production,它會載入 TerserPlugin,這是在 tree shaking 指南中首次介紹的。

請注意在環境專屬組態中使用 merge() 呼叫,以在 webpack.dev.jswebpack.prod.js 中包含我們的共用組態。webpack-merge 工具提供了多種進階功能以進行合併,但對於我們的使用案例,我們不需要任何這些功能。

NPM 腳本

現在,讓我們修改我們的 npm 腳本來使用新的組態檔。對於執行 webpack-dev-serverstart 腳本,我們將使用 webpack.dev.js,而對於執行 webpack 以建立生產組建的 build 腳本,我們將使用 webpack.prod.js

package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "src/index.js",
    "scripts": {
-     "start": "webpack serve --open",
+     "start": "webpack serve --open --config webpack.dev.js",
-     "build": "webpack"
+     "build": "webpack --config webpack.prod.js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "express": "^4.15.3",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^4.30.0",
      "webpack-dev-middleware": "^1.12.0",
      "webpack-dev-server": "^2.9.1",
      "webpack-merge": "^4.1.0",
      "xml-loader": "^1.2.1"
    }
  }

歡迎執行這些腳本,並在我們持續新增至我們的生產組態時,看看輸出如何變更。

指定模式

許多函式庫會以 process.env.NODE_ENV 變數為關鍵,來決定應包含在函式庫中的內容。例如,當 process.env.NODE_ENV 未設定為 'production' 時,有些函式庫可能會加入額外的記錄和測試,以簡化除錯。然而,當 process.env.NODE_ENV 設定為 'production' 時,它們可能會移除或加入大量程式碼,以最佳化實際使用者執行的方式。自 webpack v4 起,指定 mode 會透過 DefinePlugin 自動為您設定 process.env.NODE_ENV

webpack.prod.js

  const { merge } = require('webpack-merge');
  const common = require('./webpack.common.js');

  module.exports = merge(common, {
    mode: 'production',
  });

如果您使用類似 react 的函式庫,您應該會在加入 DefinePlugin 後,看到套件大小大幅下降。此外,請注意我們任何本地的 /src 程式碼也可以以此為關鍵,因此以下檢查會是有效的

src/index.js

  import { cube } from './math.js';
+
+ if (process.env.NODE_ENV !== 'production') {
+   console.log('Looks like we are in development mode!');
+ }

  function component() {
    const element = document.createElement('pre');

    element.innerHTML = [
      'Hello webpack!',
      '5 cubed is equal to ' + cube(5)
    ].join('\n\n');

    return element;
  }

  document.body.appendChild(component());

縮小

Webpack v4+ 會在 生產模式 中預設縮小您的程式碼。

請注意,雖然 TerserPlugin 是開始縮小的絕佳選擇,且預設會使用它,但還有其他選項

如果您決定嘗試其他縮小外掛,請確保您的新選擇也會刪除無效程式碼,如 tree shaking 指南中所述,並將其提供為 optimization.minimizer

Source Mapping

我們建議您在生產環境中啟用原始碼對應,因為它們對於除錯和執行基準測試很有用。話雖如此,您應該選擇在生產環境中使用速度相當快的建置速度(請參閱 devtool)。對於本指南,我們將在生產環境中使用 source-map 選項,而不是在開發中使用的 inline-source-map

webpack.prod.js

  const { merge } = require('webpack-merge');
  const common = require('./webpack.common.js');

  module.exports = merge(common, {
    mode: 'production',
+   devtool: 'source-map',
  });

縮小 CSS

對於生產環境,縮小 CSS 至關重要。請參閱 針對生產環境縮小 部分。

CLI 選擇

上面描述的許多選項都可以設定為命令列參數。例如,optimization.minimize 可以使用 --optimization-minimize 設定,而 mode 可以使用 --mode 設定。執行 npx webpack --help=verbose 以取得 CLI 參數的完整清單。

雖然這些簡寫方法很有用,但我們建議在 webpack 設定檔中設定這些選項以提高可設定性。

21 貢獻者

rajagopal4890markeriksonsimon04kisnowschrisVillanuevaswapnilmishrabring2dipredianskipjackxgqfrmskelsetxgirmamehrdaadSevenOutmanAnayaDesignwizardofhogwartsaholznerEugeneHlushkosnitin315