Webpack实现多页面打包

193 阅读1分钟

一、多页面概念

多页面应用(Multi-Page Application,MPA)是一种传统的 Web 应用程序架构,其特点是每个页面都是一个独立的 HTML 文件,用户的每次请求都会从服务器加载完整的新页面。与单页面应用(SPA)相比,MPA 的页面切换需要重新加载整个页面,但具有更好的 SEO 性能和首屏加载速度。

二、多页面打包思路

Webpack本身是一个模块打包器,主要用于将JavaScript应用程序打包成一个或多个bundle。对于多页面应用(MPA),每个页面有其独立的入口文件和输出文件。多页面打包的策略如下:

1.创建页面入口和模板

(1)按照约定格式创建入口,如下page1、page2:

        app
        |--xxxx
        |-- pages
        |   |-- page1 
        |   |-- |--entry.page1.js  // page1的入口文件
        |   |-- |--page1.vue   // page1的功能页面
        |   |-- page2
        |   |-- |--entry.page2.js // page2的入口文件
        |   |-- |--page2.vue   // page2的功能页面
        |   |-- xxxx

entry.page1.js:

import boot from '$pages/boot.js';
import page1 from './page1.vue';=
boot(page1);

page1.vue:

<template>
  <h1>page1</h1>
  <div>{{ content }}</div>
</template>
<script setup> 
import {ref, onMounted} from 'vue';
import $curl from '$common/curl';
const content = ref('');
});
</script>

<style lang="less" scoped>
</style>

(2)创建公共模板:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>{{name}}</title>
  <link href="/static/normalize.css" rel="stylesheet"/>
  <link href="/static/logo.png" rel="icon" type="image/x-icon"/>
  <title>{{name}}</title>
</head>

<body style="margin:0">
  <div id="root"></div>
  // webpack会自动注入js/css
</body>
</html>

3.创建 Webpack 配置

(1)指定打包入口文件

image.png

(2) 使用HtmlWebpackPlugin为每个页面生成HTML


plugins: [
    new VueLoaderPlugin(),

    // 构造最终渲染的页面->page1
    new HtmlWebpackPlugin({
      // 产物(最终模版)输出路径
      filename: path.resolve(process.cwd(), './app/public/dist/', 'entry.page1.tpl'),
      // 指定要使用的模版文件
      template: path.resolve(process.cwd(), './app/view/entry.tpl'),
      // 要注入的代码块
      chunks: ['entry.page1']
    }),

    // 构造最终渲染的页面->page2
    new HtmlWebpackPlugin({
      // 产物(最终模版)输出路径
      filename: path.resolve(process.cwd(), './app/public/dist/', 'entry.page2.tpl'),
      // 指定要使用的模版文件
      template: path.resolve(process.cwd(), './app/view/entry.tpl'),
      // 要注入的代码块
      chunks: ['entry.page2']
    }),
    ……

  ],

运行npm run build命令后,即可生成entry.page1.tpl、entry.page2.tpl以及对应的js文件,并分别将js注入到tpl,实现多页面应用。

image.png

多页面实现基本思路:为每个页面创建独立的入口文件和 HTML 模板,并通过 Webpack 配置动态生成多个 HTML 文件。

三、多页面打包通用逻辑

如果有多个页面,可以通过动态生成HtmlWebpackPlugin实例,避免重复代码。

// 动态生成多个入口和 HTML 页面:
const pageEntries = [];
const htmlWebpackPluginList = [];
// 获取app/pages 目录下所有入口文件(entry.xxx.js)
const entryList = path.resolve(process.cwd(), './app/pages/**/entry.*.js');
glob.sync(entryList).forEach(file => {
  const entryName = path.basename(file, '.js');
  // 构造entry
  pageEntries[entryName] = file;

  htmlWebpackPluginList.push(
    // HtmlWebpackPlugin辅助注入打包后的bundle.js文件到tpl文件中
    new HtmlWebpackPlugin({
      // 产物(最终模版)输出路径
      filename: path.resolve(process.cwd(), './app/public/dist/', `${entryName}.tpl`),
      // 指定要使用的模版文件
      template: path.resolve(process.cwd(), './app/view/entry.tpl'),
      // 要注入的代码块
      chunks: [entryName]
    })
  );
});


module.exports = {
  // 入口配置
  entry: {
    ...pageEntries
  },
  plugins: [
    xxx,
    // 构造最终渲染的页面
    ...htmlWebpackPluginList
  ]
}