Webpack 管理輸出

2023-05-17 15:29 更新

到目前為止,我們都是在 ?index.html? 文件中手動(dòng)引入所有資源,然而隨著應(yīng)用程序增長(zhǎng),并且一旦開(kāi)始 在文件名中使用 hash 并輸出 多個(gè) bundle,如果繼續(xù)手動(dòng)管理 ?index.html? 文件,就會(huì)變得困難起來(lái)。然而,通過(guò)一些插件可以使這個(gè)過(guò)程更容易管控。

預(yù)先準(zhǔn)備

首先,調(diào)整一下我們的項(xiàng)目:

project

  webpack-demo
  |- package.json
  |- package-lock.json
  |- webpack.config.js
  |- /dist
  |- /src
    |- index.js
+   |- print.js
  |- /node_modules

我們?cè)?nbsp;src/print.js 文件中添加一些邏輯:

src/print.js

export default function printMe() {
  console.log('I get called from print.js!');
}

并且在 src/index.js 文件中使用這個(gè)函數(shù):

src/index.js

 import _ from 'lodash';
+import printMe from './print.js';

 function component() {
   const element = document.createElement('div');
+  const btn = document.createElement('button');

   element.innerHTML = _.join(['Hello', 'webpack'], ' ');

+  btn.innerHTML = 'Click me and check the console!';
+  btn.onclick = printMe;
+
+  element.appendChild(btn);
+
   return element;
 }

 document.body.appendChild(component());

還要更新 dist/index.html 文件,來(lái)為 webpack 分離入口做好準(zhǔn)備:

dist/index.html

 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8" />
-    <title>管理資源</title>
+    <title>管理輸出</title>
+    <script src="./print.bundle.js"></script>
   </head>
   <body>
-    <script src="bundle.js"></script>
+    <script src="./index.bundle.js"></script>
   </body>
 </html>

現(xiàn)在調(diào)整配置。我們將在 entry 添加 src/print.js 作為新的入口起點(diǎn)(print),然后修改 output,以便根據(jù)入口起點(diǎn)定義的名稱,動(dòng)態(tài)地產(chǎn)生 bundle 名稱:

webpack.config.js

 const path = require('path');

 module.exports = {
-  entry: './src/index.js',
+  entry: {
+    index: './src/index.js',
+    print: './src/print.js',
+  },
   output: {
-    filename: 'bundle.js',
+    filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
 };

執(zhí)行 npm run build,然后看到生成如下:

...
[webpack-cli] Compilation finished
asset index.bundle.js 69.5 KiB [emitted] [minimized] (name: index) 1 related asset
asset print.bundle.js 316 bytes [emitted] [minimized] (name: print)
runtime modules 1.36 KiB 7 modules
cacheable modules 530 KiB
  ./src/index.js 406 bytes [built] [code generated]
  ./src/print.js 83 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
webpack 5.4.0 compiled successfully in 1996 ms

我們可以看到,webpack 生成 ?print.bundle.js? 和 ?index.bundle.js? 文件,這也和我們?cè)?nbsp;index.html 文件中指定的文件名稱相對(duì)應(yīng)。如果你在瀏覽器中打開(kāi) index.html,就可以看到在點(diǎn)擊按鈕時(shí)會(huì)發(fā)生什么。

但是,如果我們更改了我們的一個(gè)入口起點(diǎn)的名稱,甚至添加了一個(gè)新的入口,會(huì)發(fā)生什么?會(huì)在構(gòu)建時(shí)重新命名生成的 bundle,但是我們的 index.html 文件仍然引用舊的名稱。讓我們用 HtmlWebpackPlugin 來(lái)解決這個(gè)問(wèn)題。

設(shè)置 HtmlWebpackPlugin

首先安裝插件,并且調(diào)整 ?webpack.config.js? 文件:

npm install --save-dev html-webpack-plugin

webpack.config.js

 const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
+  plugins: [
+    new HtmlWebpackPlugin({
+      title: '管理輸出',
+    }),
+  ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
 };

在我們構(gòu)建之前,你應(yīng)該了解,雖然在 dist/ 文件夾我們已經(jīng)有了 index.html 這個(gè)文件,然而 HtmlWebpackPlugin 還是會(huì)默認(rèn)生成它自己的 index.html 文件。也就是說(shuō),它會(huì)用新生成的 ?index.html? 文件,替換我們的原有文件。我們看下執(zhí)行 npm run build 后會(huì)發(fā)生什么:

...
[webpack-cli] Compilation finished
asset index.bundle.js 69.5 KiB [compared for emit] [minimized] (name: index) 1 related asset
asset print.bundle.js 316 bytes [compared for emit] [minimized] (name: print)
asset index.html 253 bytes [emitted]
runtime modules 1.36 KiB 7 modules
cacheable modules 530 KiB
  ./src/index.js 406 bytes [built] [code generated]
  ./src/print.js 83 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
webpack 5.4.0 compiled successfully in 2189 ms

如果在代碼編輯器中打開(kāi) ?index.html?,你會(huì)看到 HtmlWebpackPlugin 創(chuàng)建了一個(gè)全新的文件,所有的 bundle 會(huì)自動(dòng)添加到 html 中。

如果你想要了解 HtmlWebpackPlugin 插件提供的全部的功能和選項(xiàng),你就應(yīng)該閱讀 HtmlWebpackPlugin 倉(cāng)庫(kù)中的源碼。

清理 /dist 文件夾

你可能已經(jīng)注意到,由于遺留了之前的指南和代碼示例,我們的 /dist 文件夾顯得相當(dāng)雜亂。webpack 將生成文件并放置在 /dist 文件夾中,但是它不會(huì)追蹤哪些文件是實(shí)際在項(xiàng)目中用到的。

通常比較推薦的做法是,在每次構(gòu)建前清理 /dist 文件夾,這樣只會(huì)生成用到的文件。讓我們使用 output.clean 配置項(xiàng)實(shí)現(xiàn)這個(gè)需求。

webpack.config.js

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
   plugins: [
     new HtmlWebpackPlugin({
       title: 'Output Management',
     }),
   ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
+    clean: true,
   },
 };

現(xiàn)在,執(zhí)行 npm run build,檢查 /dist 文件夾。如果一切順利,現(xiàn)在只會(huì)看到構(gòu)建后生成的文件,而沒(méi)有舊文件!

manifest

你可能會(huì)很感興趣,webpack 和 webpack 插件似乎“知道”應(yīng)該生成哪些文件。答案是,webpack 通過(guò) manifest,可以追蹤所有模塊到輸出 bundle 之間的映射。如果你想要知道如何以其他方式來(lái)控制 webpack 輸出,了解 manifest 是個(gè)好的開(kāi)始。

通過(guò) WebpackManifestPlugin 插件,可以將 manifest 數(shù)據(jù)提取為一個(gè) json 文件以供使用。

我們不會(huì)在此展示一個(gè)如何在項(xiàng)目中使用此插件的完整示例,你可以在 manifest 概念頁(yè)面深入閱讀,以及在 緩存 指南中,了解它與長(zhǎng)效緩存有何關(guān)系。

結(jié)論

現(xiàn)在,你已經(jīng)了解如何向 HTML 動(dòng)態(tài)添加 bundle,讓我們深入 開(kāi)發(fā)環(huán)境 指南?;蛘呷绻阆胍钊敫嘞嚓P(guān)高級(jí)話題,我們推薦你前往 代碼分離 指南。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)