webpack里手写一个多页面打包的通用方案
回顾
上篇文章我们打包了一个detail出口文件的所要做的事情:
先在配置文件里去设置入口,然后在插件里new 一个HtmlWebpackPlugin
并进行配置。
这只是一个,如果还有其他的文件需要打包处理呢,比如login、index这两个文件,如果也做打包处理,按照上面打包detail的步骤再来2遍,打包三个,我们需要这样重复3次,是不是太累了?如果文件很多,都要一个一个这样添加吗?
当然有解决方案。
我们可以自己写一个方法去解放上面手动添加的烦恼,也就是 多页面打包的通用方案
手写多页面打包的通用方案
我们知道,要添加一个出口页面,我们需要执行的操作是:
- 先在配置文件里去设置入口文件。
- 插件里new 一个
HtmlWebpackPlugin
并进行配置。
新建一个配置文件
为了方便查看,我们重新建一个配置文件webpack.test.config.js
,想要此文件生效,我们记着一定要在package.json
这样设置:
重新创建配置文件就用
webpack --config
去指向新的配置文件名,并且自己设置一个命令,这里我设置的命令名是:config-test
。
webpack --config
是指定哪份配置,这里指定配置文件是webpack.test.config.js
。
执行构建时:
npm run config-test
就OK了,生成的文件如下:
代码上面一行的
test
命令,指向的是webpack默认的webpack.config.js
文件,执行 npm run test
就会运行webpack.config.js配置文件。
手写代码
我们再来写一下webpack.test.config.js
中的代码:
先分析一波
首先我们先把webpack.config.js
中的代码复制过来,然后代码里面新增一个runTest方法,它会返回我们想要的2个重要数据;
里面定义两个变量分别是出口js文件合集的entrys
变量,它是一个对象,我们先初始化为一个空对象,另一个是出口多页面的一个集合htmlwebpackplugins
变量,它是一个数组,我们先初始化为一个空数组;
然后把这两个变量返回,最后调用runTest方法并通过解构拿到entrys, htmlwebpackplugins
变量;
代码如下:
function runTest(){
var entrys={},htmlwebpackplugins=[];
return {
entrys,
htmlwebpackplugins
}
}
const {entrys,htmlwebpackplugins}=runTest();
至于为什么要把出口 js 文件定义成一个对象,而把多页面出口文件定义成一个数组,我们可以看下面原先的配置是这样的:
入口配置entry那里,它本身就是个对象,所以我们只要把最后的所有入口文件的集合放在这里就好了。
然后多页面html那里,它是由多个相同的
new HtmlWebpackPlugin({ //模板的相对或者绝对路径 template: "...", filename: "...", } )
这种格式构成,所以我们这里的集合设置成一个数组,到时候一解构就可以啦。
所以我们这样写:
上代码
我们回过头来继续填充runTest
方法里面的代码,直接上代码如下:
var glob=require('glob');
function runTest(){
var entrys={},htmlwebpackplugins=[];
const entryFiles = glob.sync(path.join(__dirname, "./src/*/index.js"));
console.log('==============>',entryFiles);
entryFiles.map((item,index)=>{
let match=item.match(/src/(.*)/index.js/);
console.log('match=====>',match);
let pageName=match[1];
entrys[pageName]=item;
htmlwebpackplugins.push(
new HtmlWebpackPlugin({
// "./src/index.html"
template: `./src/${pageName}.html`,
// "index.html"
filename: `${pageName}.html`,
chunks:[pageName]
} ),
)
})
return {
entrys,
htmlwebpackplugins
}
}
const {entrys,htmlwebpackplugins}=runTest();
分析代码
分析一波这段代码:
entry: {
index: './src/index.js',
list: './src/list.js',
detail:'./src/detail/index.js',
},
首先我们看一下原先entry里面对象里的每一项,分别是一个chunks的键名key也就是属性名,value是对应的入口文件路径。
所以我们再分析上述runTest
里面的代码:
先定义两个变量分别存放入口文件的集合的entrys
变量和存放多页面集合的htmlwebpackplugins
变量。
然后,path.join()是拼接路径,参数./src/*/index.js
就是路径片段,这里*
是通配符所有任意字符的意思;
比如可以匹配到./src/index/index.js
、./src/detail/index.js
、./src/login/index.js
等都是可以匹配到的。
然后glob.sync
是可以返回找到与模式匹配的所有文件名。
返回的值如下:
这里大家记得要安装一下glob:
npm install glob
关于glob.sync
的详情官网文档资料如下:
具体glob文档链接
path.join
具体详情官方资料:
path
其他详情看这里,官方文档
再继续往下看,我们用math+正则去查找每项对应的字符信息;
使用正则时,遇到特殊字符就要用\
进行转义, .
:匹配除换行符 \n
之外的任何单字符, *
:匹配前面的子表达式零次或多次;
我们用变量math接受到了查找到的符合条件的所有信息的数组。
看下打印结果:
查找到的信息有我们想要的路径以及chunks。
我们用变量pageName去保存chunks的值;
然后把每项的值保存在entry里;
最后再往htmlwebpackplugins
去push值,里面都用到了pageName的值,事实上,多页面配置里面也就这个变量的值不同,其他都一样;
最后,就是把这个entrys
、htmlwebpackplugins
return出去;
看成果
以上代码就算是写完了,最后我们需要把打包的文件名改成test
,为了和之前的dist
区分开,代码如下:
webpack.test.config.js
:
执行构建,看效果:
构建成功后,目录下新增了一个test
的目录,里面的文件就是我们打包所需的文件,
结尾
转载自:https://juejin.cn/post/7111990146374828046