vue+webpack4 多页面打包配置
多页面配置通常有两种形式,一种是多页面多配置,一种是多页面单配置。因为 webpack(3.1 以上)可以直接处理一个配置对象的数组,所以可以为每个页面单独写一份配置。通常来讲,多配置的优点是配置灵活、独立,可以并行打包,从而提高打包速度,缺点是不能在多页面之间共享代码(一个页面加载了之后,下一个页面还得再加载一遍);单配置的特点基本上是和多配置相对。具体使用哪一种形式,看具体业务情况。本文主要介绍的是单配置的形式。
1. 整体目录结构
为了便于打包,我们创建一个 pages 的文件夹,在其下创建一个个的子文件夹代表一个个页面,每个子文件夹中建立各自的 spa 应用体系,如图所示:这样做的好处是,我们在配置 webpack 的打包入口时,比较好操作,而且这样的结构也较为清晰。
2. webpack 配置
2.1 文件结构
创建 base、dev、prod 三个文件。我们在 base 文件中配置 entry、output、loader、公共的 plugin 等,其余的根据开发环境和线上环境各自所需在各自不同的文件中增删改。
2.2 entry
根据整体目录结构,每个页面文件夹都有各自的入口 js 文件,我们在配置 entry 选项时,就可以按如下编码方式书写:
/**
* 通过约定,降低编码复杂度
* 每新增一个入口,即在 src/pages 目录下新增一个文件夹,以页面名称命名,内置一个 index.js 作为入口文件
* 通过 node 的文件 api 扫描 pages 目录
* 这样可以得到一个形如 {page1: “ 入口文件地址 ”, page2: “ 入口文件地址 ”, …} 的对象
*/
const getEntries = () => {
let result = fs.readdirSync(pagesDirPath);
let entry = {};
result.forEach(item => {
entry[item] = path.resolve(__dirname, `../src/pages/${item}/index.js`);
});
return entry;
}
module.exports = {
entry: getEntries()
…
}
2.3 output
output 的配置选项如下,打完包后的目录结构如图所示:
// 判断是否是开发环境
const devMode = process.env.NODE_ENV === “development”;
module.exports = {
…
output: {
publicPath: devMode ? “” : “/”,
// 这里的 name 即为我们 entry 对象中的每一个 key 值,也就是我们在 pages 目录下创建的一个个文件夹的名称
filename: devMode ? “[name].js” : “static/js/[name].[chunkhash].js”,
path: path.resolve(__dirname, “../dist”)
}
…
}
2.4 html-webpack-plugin
配置完了 entry 和 output,接下来需要为每个页面生成一个单独的 html 文件,也就是为每个页面创建一个 html-webpack-plugin 的实例:
/**
* 扫描 pages 文件夹,为每个页面生成一个插件实例对象
*/
const generatorHtmlWebpackPlugins = () => {
let arr = [];
let result = fs.readdirSync(pagesDirPath);
result.forEach(item => {
// 判断页面目录下有无自己的 index.html
let templatePath;
let selfTemplatePath = pagesDirPath + `/${item}/index.html`;
let publicTemplatePath = path.resolve(__dirname, “../src/public/index.html”);
try {
fs.accessSync(selfTemplatePath);
templatePath = selfTemplatePath;
} catch(err) {
templatePath = publicTemplatePath;
}
arr.push(new HtmlWebpackPlugin({
template: templatePath,
filename: `${item}.html`,
chunks: [“manifest”, “vendor”, item]
}));
});
return arr;
}
module.exports = {
…
plugins: [
…generatorHtmlWebpackPlugins()
]
…
}
这里为了灵活性考虑,判断了各自的页面子文件夹中有无 html 模板文件;如果不需要,可以把 templat 路径直接定义成公共 html 文件的地址。
2.5 其他配置
基本上前面的几点配置就是一个多页面打包配置的雏形。此外还可以配置下诸如 optimization、mini-css-extract-plugin 等生产环境打包的优化配置。在文末的 github 地址中可以看到全部的配置信息。
3. 多页面 +SPA
虽然我们这是一个多页面的应用,但每个页面也可以做成一个 spa,如果你有这种需求的话;此外可以配置 @babel/plugin-syntax-dynamic-import 插件以支持 import(),在 router 层面做代码分割和懒加载。
附
原文代码地址:https://github.com/gww666/2-m…