Skip to content

教学目标

  1. 理解 Webpack 多页面应用(MPA)的配置方法。

  2. 掌握如何为每个 HTML 页面单独引用对应的入口 JS 文件。

  3. 学会提取公共代码,优化打包结果。

教学内容

1. 问题背景

默认情况下,HtmlWebpackPlugin 会将所有入口的 JS 文件注入到每个 HTML 页面中。但在多页面应用中,我们希望每个 HTML 页面只引用其对应的入口 JS 文件。

2. 解决方案

通过配置 HtmlWebpackPlugin 的 chunks 选项,为每个页面指定需要注入的 JS 文件。

3. 具体步骤

3.1 项目结构

bash
src/
├── pages/
   ├── home/
   ├── index.html     # 首页模板
   └── index.js       # 首页入口
   └── about/
       ├── index.html     # 关于页模板
       └── index.js       # 关于页入口
public/                    # 静态资源(图片等)
webpack.config.js

3.2 修改** webpack.config.js**

在 HtmlWebpackPlugin 中为每个页面指定 chunks,确保只注入相关的 JS 文件。

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

module.exports = {
  entry: {
    home: './src/pages/home/index.js', // 首页入口
    about: './src/pages/about/index.js', // 关于页入口
  },
  output: {
    filename: '[name].bundle.js', // 动态生成文件名
    path: path.resolve(__dirname, 'dist'),
    clean: true,
  },
  plugins: [
    // 首页配置
    new HtmlWebpackPlugin({
      template: './src/pages/home/index.html',
      filename: 'home.html',
      chunks: ['home'], // 只注入 home 入口的 JS
    }),
    // 关于页配置
    new HtmlWebpackPlugin({
      template: './src/pages/about/index.html',
      filename: 'about.html',
      chunks: ['about'], // 只注入 about 入口的 JS
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
    ],
  },
  devServer: {
    static: './dist',
    hot: true,
    open: ['/home.html'], // 默认打开首页
  },
};

3.3 示例代码

src/pages/home/index.html

html
<!DOCTYPE html>
<html>
<head>
  <title>首页</title>
</head>
<body>
  <h1>这是首页</h1>
  <div id="app"></div>
</body>
</html>

运行 HTML

src/pages/home/index.js

console.log('这是首页的 JS 文件');

src/pages/about/index.html

html
<!DOCTYPE html>
<html>
<head>
  <title>关于我们</title>
</head>
<body>
  <h1>这是关于页</h1>
  <div id="app"></div>
</body>
</html>

运行 HTML

src/pages/about/index.js

javascript
console.log('这是关于页的 JS 文件');

3.4 运行结果

  • 打包后生成 dist/home.html 和 dist/about.html。

  • home.html 只引用 home.bundle.js。

  • about.html 只引用 about.bundle.js。

4. 高级配置

4.1 提取公共代码

如果多个页面共享某些代码(如公共库),可以使用 optimization.splitChunks 提取公共代码:

optimization: {
  splitChunks: {
    chunks: 'all',
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
      },
    },
  },
},

然后在 HtmlWebpackPlugin 中注入公共代码:

chunks: ['vendors', 'home'] // 首页注入 vendors 和 home

4.2 动态生成配置

如果页面较多,可以通过动态生成配置减少重复代码:

javascript
const pages = [
  { name: 'home', title: '首页' },
  { name: 'about', title: '关于我们' },
];

module.exports = {
  entry: pages.reduce((entries, page) => {
    entries[page.name] = `./src/pages/${page.name}/index.js`;
    return entries;
  }, {}),
  plugins: pages.map(page => 
    new HtmlWebpackPlugin({
      template: `./src/pages/${page.name}/index.html`,
      filename: `${page.name}.html`,
      chunks: [page.name], // 动态注入对应入口
      title: page.title,
    })
  ),
};

5. 总结

  • 核心配置:通过 HtmlWebpackPlugin 的 chunks 选项控制每个 HTML 页面引用的 JS 文件。

  • 优化建议:

    • 提取公共代码,减少重复加载。

    • 动态生成配置,简化多页面管理。

  • 适用场景:多页面应用(MPA)或需要独立入口的复杂项目。

课后练习

  1. 创建一个包含 3 个页面的项目,分别为 home、about 和 contact,每个页面引用不同的入口 JS 文件。

  2. 配置 optimization.splitChunks,提取 node_modules 中的代码到 vendors.bundle.js。

  3. 使用 Webpack Bundle Analyzer 分析打包结果,验证公共代码是否被正确提取。

参考资料

  • Webpack 官方文档:

  • HtmlWebpackPlugin 文档:

  • Webpack Bundle Analyzer: