手把手教你从零搭建一个基于webpack4的多页面打包方案(满满的肝货)
前言
说到webpack
,大家一定都习惯了webpack+vue
或者webpack+react
的单页面应用打包,这也是目前非常常见的大型项目基本架构。
但每个公司应该都会有一些小项目,例如banner
常配置的活动页,基本上每个活动的生命周期也就那么几天,然后大多数公司还是习惯了用jquery
的方式。不打包,所见即所得的方式,直接src
引入,如果是基于vue
或者react
的活动,往往不敢写太多的ES6
代码,毕竟一些客户端不兼容,且都是在线编译的方式,虽然省事(其实不省事),但是性能降低了不少,且缓存也不太好处理。
上一篇文章教大家配置了单页面打包工具,这一篇是基本版的多页面打包方案。废话不多说,先上目录结构:
├── /activity/ # 打包后输出目录
│ ├── /static/ # 静态文件存放目录(js、css、img等)
│ ├── pageA.html # 活动A入口
│ ├── pageB.html # 活动B入口
├── /config/ # 脚手架配置目录
│ ├── webpack.dev.js # 本地服务启动入口
│ ├── webpack.prod.js # 生产打包配置入口
├── /src/ # 项目源码目录
│ ├── /pageA/ # 活动A源代码
│ │ ├── main.js # 活动A总入口
│ │ └── index.html # 活动A html模板文件
│ ├── /pageB/ # 活动B源代码
│ │ ├── main.js # 活动B总入口
│ │ └── index.html # 活动B html模板文件
├── package.json # 项目信息
约定格式
src
所有开发文件都放在src
文件夹下,每个文件夹是一个活动,文件夹内必包含main.js
作为入口文件,index.html
作为模板文件。
config
打包配置文件
activity
此文件夹为打包后输出文件夹,所有生成的文件都在里面。每个活动都会生成对应的html
命名文件,其他静态文件统统放在static
文件夹下
核心逻辑内容
在搬出核心内容之前,我们先看下辅助服务类的webpack
配置。配置很简单,就不一一解释,详细可查看稍早文章。
module.exports = {
module:{
rules:[
{
test:/\.m?js/,
include:path.resolve(__dirname,'../src'),
exclude:/node_modules/,
use:[
{loader:'babel-loader'}
]
}
]
},
plugins:[
new webpack.HotModuleReplacementPlugin(),
],
devServer:{
progress:true, //进度条
inline:true, //打包后加入一个websocket客户端
hot:true, //热加载
contentBase: path.resolve(__dirname,'../src'), //开发服务运行时的文件根目录
host: 'localhost', //主机地址
port: 5000, //端口号
}
}
也没啥太特殊的,主要包括js
的loader
解析以及本地服务、热更新。
入口逻辑
我们知道webpack
配置入口entry
支持字符串、数组、对象、函数等格式,我们这里采用对象作为入口格式,一个入口就是一个活动chunk
,例如我们有两个活动,入口配置如下:
module.exports = {
//其他配置忽略
entry:{
pageA:path.resolve(__dirname,'../src/pageA/main.js'),
pageB:path.resolve(__dirname,'../src/pageB/main.js'),
}
//其他配置忽略
}
然后就是如何打包多html
,在一般的单页面应用里,只有一个html
入口,往往是使用html-webpack-plugin
这个强大的插件,配置在plugins
中,例如多个活动,就配置多个html-webpack-plugin
。例如:
module.exports = {
//其他配置忽略
plugins:[
new HtmlWebpackPlugin({
chunks:['pageA'],
filename:'pageA.html',
template:path.resolve(__dirname,'../src/pageA/index.html'),
}),
new HtmlWebpackPlugin({
chunks:['pageB'],
filename:'pageB.html',
template:path.resolve(__dirname,'../src/pageB/index.html'),
}),
]
//其他配置忽略
}
说明:template
配置模板地址,filename
为输出打包文件html
名称,chunks
是entry
中引入的文件地址,一个活动一个地址。
如此,基本上就完成一个多页面webpack
脚手架配置了。然后问题也随之而来,只要多一个活动,就要手动修改配置,比较繁琐,因为原则上不建议业务开发人员手动修改webpack
配置文件的。这个时候可以考虑glob
插件,动态读取src
文件夹下文件内容后配置输入输出。关键是这句:
const entryFiles = glob.sync(path.resolve(__dirname, '../src/*/main.js'));
得到的entryFiles
是一个符合规则的src
文件夹下的文件路径数组。之后遍历,正则匹配出文件夹名称即可。关键配置如下:
const glob = require('glob');
const path = require('path');
const getMPA = () => {
const entry = {};
const htmlWebpackPlugins = [];
const entryFiles = glob.sync(path.resolve(__dirname, '../src/*/main.js'));
for(let item of entryFiles){
const pageName = item.match(/src\/(.*)\/main.js/)[1];
entry[pageName] = item;
htmlWebpackPlugins.push(
new HtmlWebpackPlugin({
chunks:[pageName],
filename:`${pageName}.html`,
template:path.resolve(__dirname,`../src/${pageName}/index.html`),
}),
)
}
return {
entry,
htmlWebpackPlugins
}
}
const { entry, htmlWebpackPlugins } = getMPA();
以上代码的原理很简单,就是动态读取文件夹内容,生成entry
入口配置以及对应new
一个html-webpack-plugin
。
然后将生成的entry
、htmlWebpackPlugins
、webpack
配置即可
module.exports = {
entry:entry,
plugins:[
...htmlWebpackPlugins
]
}
如此,一个简单易用的多页面webpack
打包脚手架工具就配置完成了。麻雀虽小五脏俱全,此配置包括了最核心的多页面打包配置。其他loader
以及plugins
等配置此处略过,感兴趣的同学可参考之前文章。
源代码可参考这里:https://gitee.com/leishiwo31/multiPage.git
如果觉得本文对你有帮助,顺手点个赞,再关注一下呗,每月都会不定期更新肝货满满的文章。
转载自:https://juejin.cn/post/7044087513228509192