输出管理

到目前为止,我们已在 index.html 文件中手动包含了所有资产,但随着应用程序的增长,以及您开始在文件名中使用哈希并输出多个捆绑包后,手动管理 index.html 文件将变得很困难。但是,存在一些插件可以使此过程更容易管理。

准备

首先,让我们稍微调整一下项目

项目

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

让我们在 src/print.js 文件中添加一些逻辑

src/print.js

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

并在 src/index.js 文件中使用该函数

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 文件,为 webpack 拆分条目做准备

dist/index.html

 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8" />
-    <title>Asset Management</title>
+    <title>Output Management</title>
+    <script src="./print.bundle.js"></script>
   </head>
   <body>
-    <script src="bundle.js"></script>
+    <script src="./index.bundle.js"></script>
   </body>
 </html>

现在调整配置。我们将添加 src/print.js 作为新的入口点 (print),并将更改输出,以便它根据入口点名称动态生成捆绑包名称

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'),
   },
 };

让我们运行 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.jsindex.bundle.js 文件,我们也在 index.html 文件中指定了这些文件。如果您在浏览器中打开 index.html,您就可以看到单击按钮时会发生什么。

但是,如果我们更改了其中一个入口点的名称,甚至添加了一个新的入口点,会发生什么呢?生成的捆绑包将在构建时重命名,但我们的 index.html 文件仍将引用旧名称。让我们使用HtmlWebpackPlugin 来解决这个问题。

设置 HtmlWebpackPlugin

首先安装插件并调整 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 Management',
+    }),
+  ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
 };

在进行构建之前,您应该知道,HtmlWebpackPlugin 默认情况下会生成自己的 index.html 文件,即使我们已经在 dist/ 文件夹中有一个。这意味着它将用新生成的文件替换我们的 index.html 文件。让我们看看当我们执行 npm run build 时会发生什么。

...
[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

如果您在代码编辑器中打开 index.html,您会看到 HtmlWebpackPlugin 为您创建了一个全新的文件,并且所有捆绑包都已自动添加。

如果您想了解更多关于 HtmlWebpackPlugin 提供的所有功能和选项的信息,那么您应该在 HtmlWebpackPlugin 仓库中阅读。

清理 /dist 文件夹

您可能已经注意到,在过去的指南和代码示例中,我们的 /dist 文件夹变得相当混乱。Webpack 会为您生成文件并将它们放在 /dist 文件夹中,但它不会跟踪哪些文件实际上被您的项目使用。

通常,在每次构建之前清理 /dist 文件夹是一个好习惯,这样只有使用的文件才会被生成。让我们使用 output.clean 选项来解决这个问题。

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,
   },
 };

现在运行 npm run build 并检查 /dist 文件夹。如果一切顺利,您现在应该只看到从构建中生成的,而不是旧文件!

清单

您可能想知道 webpack 及其插件是如何“知道”哪些文件正在生成的。答案在于 webpack 保持的清单,它跟踪所有模块如何映射到输出捆绑包。如果您有兴趣以其他方式管理 webpack 的 output,清单将是一个不错的起点。

清单数据可以使用 WebpackManifestPlugin 提取到 json 文件中以供使用。

我们不会详细介绍如何在项目中使用此插件,但您可以阅读 概念页面缓存指南,了解它如何与长期缓存相关联。

结论

现在您已经了解了如何将捆绑包动态添加到 HTML 中,让我们深入了解 开发指南。或者,如果您想深入了解更高级的主题,我们建议您前往 代码拆分指南

8 位贡献者

skipjackTheDutchCodersudarsangpJGJPEugeneHlushkoAnayaDesignchenxsansnitin315