Webpack5 多页面的项目实践
作者:蓝精灵001
本文主要介绍了Webpack5 多页面的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
特性维度 | 单页面应用-SPA | 多页面统一目录-MPA | 多页面单独部署-MPA |
---|---|---|---|
入口数量 | 单个,只有一个 HTML 文件 | 多个,多个 HTML 文件 | 多个,多个 HTML 文件,分别打包输出 |
资源输出结构 | 所有资源输出到统一目录(如 js/, css/) | 所有页面的资源共用 js/, css/ 等目录 | 每页资源放在各自目录(如 index/js/, index/css/) |
公共资源复用 | 高:依赖打入主包或懒加载 chunk,资源完全共享 | 中:可通过 splitChunks 提取公共模块,多个页面共用依赖 | 低:默认每个页面依赖重复打包,需通过 CDN 或构建优化共享资源 |
首屏加载速度 | 中低:主包体积大需优化 | 高:每页只加载自身资源 | 高:每页打包独立、加载自身资源 |
项目推荐模式 | 用户交互复杂、状态集中、路由频繁 | 页面之间结构清晰、流程独立但资源共用 | 需要页面级灰度、子模块独立开发与部署 |
1. 示例多页面配置
- 配置外部依赖、CDN 资源以及页面级 CDN 扩展
- 自动生成入口和 HtmlWebpackPlugin 实例
- 导出生成的入口配置、插件配置、依赖过滤配置
- entries:入口配置对象(用于 entry)
- plugins:HtmlWebpackPlugin 实例数组(用于 plugins)
- externals:供主配置使用(用于排除模块打包)
1.1多页面统一目录(MPA)
dist/ ├── test1.html ├── test2.html ├── js/ │ ├── test1.[hash].js │ └── test2.[hash].js └── 图片、字体等资源
const path = require("path"); const glob = require("glob"); const { merge } = require("webpack-merge"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const resolve = (dir) => path.resolve(__dirname, "..", dir); // 打包排除某些依赖 const externals = { vue: "Vue", vuex: "Vuex", "vue-router": "VueRouter", axios: "axios", vant: "vant", }; // cdn资源 const assetsCDN = { // 开发环境 dev: { css: ["//xxx/npm/vant@2.12/lib/index.css"], js: ["//xxx/npm/eruda@2.4/eruda.min.js"], }, // 生产环境 build: { css: ["//xxx/npm/vant@2.12/lib/index.css"], js: [ "//xxx/npm/vue@2.6/dist/vue.min.js", "//xxx/npm/vuex@3.6/dist/vuex.min.js", "//xxx/npm/vue-router@3.5/dist/vue-router.min.js", "//xxx/npm/axios@0.21/dist/axios.min.js", "//xxx/npm/vant@2.12/lib/vant.min.js", ], }, }; const entryCDN = { test: { dev: merge(assetsCDN.dev, { css: [], js: ["//res.wx.qq.com/open/js/jweixin-1.6.0.js"], }), build: merge(assetsCDN.build, { css: [], js: ["//res.wx.qq.com/open/js/jweixin-1.6.0.js"], }), }, }; const getEntry = () => { // 多页面打包的入口集合 const entries = {}; // 多页面打包的模板集合 const plugins = []; // 借助 glob 获取 src 目录下的所有入口文件 const globPath = resolve("src/views/**/main.js"); // 遍历文件集合,生成所需要的 entries、plugins 集合 glob.sync(globPath).map((item) => { const match = item.match(/src/views/(.*)/main.js$/); const name = match?.[1]; entries[name] = [item]; // CDN配置 const env = process.env.NODE_ENV === "production" ? "build" : "dev"; const pageCDN = (entryCDN[name] && entryCDN[name][env]) || assetsCDN[env]; if (!entryCDN[name]) { console.warn(`页面 ${name} 未配置 entryCDN,已使用默认配置`); } // 多页面所需要的模板集合 plugins.push( new HtmlWebpackPlugin({ title: "", filename: `${name}.html`, template: "public/index.html", favicon: "public/favicon.ico", chunks: [name], minify: process.env.NODE_ENV === "production" ? { //压缩HTML文件 removeComments: true, // 移除HTML中的注释 collapseWhitespace: true, // 删除空白符和换行符 } : false, cdn: process.env.NODE_ENV === "production" ? entryCDN[name].build : entryCDN[name].dev, }) ); }); // 对外输出页面打包需要的 入口集合、依赖过滤 return { entries, plugins, externals }; }; module.exports = getEntry();
const { entries, plugins, externals } = require("./entry"); entry: { base: ["core-js/stable", "regenerator-runtime/runtime"], ...entries }
1.2多页面单独部署(MPA)
dist/ ├── test1/ │ ├── index.html │ └── js/ │ └── test1.[hash].js └── test2/ ├── index.html └── js/ └── test2.[hash].js
// 在多页面统一目录的基础上新增配置 const CopyWebpackPlugin = require("copy-webpack-plugin"); const getEntry = () => { // 多页面打包的入口集合 const entries = {}; // 多页面打包的模板集合 const plugins = []; // 借助 glob 获取 src 目录下的所有入口文件 const globPath = resolve("src/views/**/main.js"); const base = ["core-js/stable", "regenerator-runtime/runtime"]; // 遍历文件集合,生成所需要的 entries、plugins 集合 glob.sync(globPath).map(item => { const match = item.match(/src/views/(.*)/main.js$/); const name = match?.[1]; entries[name] = [...base, item]; const env = process.env.NODE_ENV === "production" ? "build" : "dev"; const pageCDN = (entryCDN[name] && entryCDN[name][env]) || assetsCDN[env]; if (!entryCDN[name]) { console.warn(`页面 ${name} 未配置 entryCDN,已使用默认配置`); } // 多页面所需要的模板集合 plugins.push( new HtmlWebpackPlugin({ title: "", filename: `${name}/index.html`, template: "public/index.html", // favicon: "public/favicon.ico", chunks: [name], minify: process.env.NODE_ENV === "production" ? { //压缩HTML文件 removeComments: true, // 移除HTML中的注释 collapseWhitespace: true // 删除空白符和换行符 } : false, cdn: pageCDN }), new CopyWebpackPlugin({ patterns: [{ from: "public/favicon.ico", to: `${name}/favicon.ico` }] }) ); }); // 对外输出页面打包需要的 入口集合、依赖过滤 return { entries, plugins, externals }; };
// 1. 注释掉 entry base 的配置 // 2. css、img、font的filename 增加 [name]/ splitChunks: false // ❌ 禁用公共拆包
到此这篇关于Webpack5 多页面的项目实践的文章就介绍到这了,更多相关Webpack5 多页面内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!