likes
comments
collection
share

手把手教你从零搭建一个基于webpack4的多页面打包方案(满满的肝货)

作者站长头像
站长
· 阅读数 51

前言

说到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,						//端口号
	}
}

也没啥太特殊的,主要包括jsloader解析以及本地服务、热更新。

入口逻辑

我们知道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名称,chunksentry中引入的文件地址,一个活动一个地址。 如此,基本上就完成一个多页面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。 然后将生成的entryhtmlWebpackPluginswebpack配置即可

module.exports = {
	entry:entry,
	plugins:[
		...htmlWebpackPlugins
	]
}

如此,一个简单易用的多页面webpack打包脚手架工具就配置完成了。麻雀虽小五脏俱全,此配置包括了最核心的多页面打包配置。其他loader以及plugins等配置此处略过,感兴趣的同学可参考之前文章。 源代码可参考这里:https://gitee.com/leishiwo31/multiPage.git 如果觉得本文对你有帮助,顺手点个赞,再关注一下呗,每月都会不定期更新肝货满满的文章。

转载自:https://juejin.cn/post/7044087513228509192
评论
请登录