likes
comments
collection
share

webpack里手写一个多页面打包的通用方案

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

回顾

上篇文章我们打包了一个detail出口文件的所要做的事情: 先在配置文件里去设置入口,然后在插件里new 一个HtmlWebpackPlugin并进行配置。 这只是一个,如果还有其他的文件需要打包处理呢,比如login、index这两个文件,如果也做打包处理,按照上面打包detail的步骤再来2遍,打包三个,我们需要这样重复3次,是不是太累了?如果文件很多,都要一个一个这样添加吗? 当然有解决方案。 我们可以自己写一个方法去解放上面手动添加的烦恼,也就是 多页面打包的通用方案

手写多页面打包的通用方案

我们知道,要添加一个出口页面,我们需要执行的操作是:

  1. 先在配置文件里去设置入口文件。
  2. 插件里new 一个HtmlWebpackPlugin并进行配置。

新建一个配置文件

为了方便查看,我们重新建一个配置文件webpack.test.config.js,想要此文件生效,我们记着一定要在package.json这样设置:

webpack里手写一个多页面打包的通用方案 重新创建配置文件就用webpack --config去指向新的配置文件名,并且自己设置一个命令,这里我设置的命令名是:config-testwebpack --config是指定哪份配置,这里指定配置文件是webpack.test.config.js 。 执行构建时: npm run config-test

就OK了,生成的文件如下:

webpack里手写一个多页面打包的通用方案 代码上面一行的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 文件定义成一个对象,而把多页面出口文件定义成一个数组,我们可以看下面原先的配置是这样的:

webpack里手写一个多页面打包的通用方案 入口配置entry那里,它本身就是个对象,所以我们只要把最后的所有入口文件的集合放在这里就好了。 然后多页面html那里,它是由多个相同的 new HtmlWebpackPlugin({ //模板的相对或者绝对路径 template: "...", filename: "...", } )这种格式构成,所以我们这里的集合设置成一个数组,到时候一解构就可以啦

所以我们这样写:

webpack里手写一个多页面打包的通用方案

上代码

我们回过头来继续填充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是可以返回找到与模式匹配的所有文件名。 返回的值如下:

webpack里手写一个多页面打包的通用方案 这里大家记得要安装一下glob:

npm install glob

关于glob.sync的详情官网文档资料如下: webpack里手写一个多页面打包的通用方案 具体glob文档链接

path.join具体详情官方资料:

webpack里手写一个多页面打包的通用方案

path其他详情看这里,官方文档

再继续往下看,我们用math+正则去查找每项对应的字符信息; 使用正则时,遇到特殊字符就要用\进行转义, .:匹配除换行符 \n 之外的任何单字符, *:匹配前面的子表达式零次或多次我们用变量math接受到了查找到的符合条件的所有信息的数组

看下打印结果:

webpack里手写一个多页面打包的通用方案 查找到的信息有我们想要的路径以及chunks。

我们用变量pageName去保存chunks的值; 然后把每项的值保存在entry里最后再往htmlwebpackplugins去push值,里面都用到了pageName的值,事实上,多页面配置里面也就这个变量的值不同,其他都一样最后,就是把这个entryshtmlwebpackpluginsreturn出去

看成果

以上代码就算是写完了,最后我们需要把打包的文件名改成test,为了和之前的dist区分开,代码如下: webpack.test.config.js: webpack里手写一个多页面打包的通用方案 执行构建,看效果:

webpack里手写一个多页面打包的通用方案

构建成功后,目录下新增了一个test的目录,里面的文件就是我们打包所需的文件,

结尾

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