本文主要讲解如何处理vue2多页面打包时通过chainWebpack设置html打包选项,包括问题排查过程,心急的朋友可以直接拉到最后看解决方案。
在用vue2开发多入口应用的时候,由于某些特殊的原因,要求打包出来的html中,所有对css和js的引用都必须带上双引号,如下图,第一行带了引号,第二行没带,默认打包生成的html是第二种,我要生成第一种
其实在webpack打包的时候,默认会把双引号去掉的,查询vue的文档以及一位踩过坑的大佬的建议,知道是要修改某个插件的配置,从而在打包的时候保留双引号
vue的教程 cli.vuejs.org/zh/guide/we…
踩坑大佬的建议是这样写:
- Building for production... ERROR TypeError: Cannot read property '__expression' of undefined TypeError: Cannot read property '__expression' of undefined at Object.toConfig (G:\js\Trajectory\trajectory\node_modules\webpack-chain\src\Plugin.js:56:38)
跟说好的不一样啊,但生活总要继续 于是勉为其难的搭建一下build的debug命令,希望掌握整个打包的过程(实际上只是想看看到底怎么肥事,报错的上下文都在干什么),于是在工程根目录添加.vscode文件夹,并且里面添加launch.json,如下图
然后愉快的开始debug,对chainWebpack函数以及tap里面的东西都打上断点
在chainWebpack函数中触发了断点,查看config对象(在DEBUG CONSOLE里面输入命令可以对对象进行一些操作的)
emmm太长不看,只看我要用的,在命令行执行config.plugin("html"),同样太长不看,主要是看不懂,进下一个断点,
跑到tap里面来了,惊讶的发现args是一个空数组。
那我晓得了,判空谁还不会呢,我给args添加一个元素,并且为args[0]设置minify=false即可!
555555别打了孩子知道错了……
看来要掏真家伙了,找到报错栈顶的这一行,是Plugin.js这文件的问题。在vscode里面,按住ctrl并且单击报错栈最上层的node_modules\webpack-chain\src\Plugin.js文件,找到报错的地方,同样上断点。我来康康到底是怎么肥事!
因为知道vue其实在打包的过程中使用了很多plugin默默地为我们解决了很多事情,所以其实加载的时候会有很多plugin,于是我默默的等待,等到了一个为undifine的plugin,get了一下args发现里面只有一个minify:false这么一对值,确认是我要设置的plugin,但为什么会是undefine呢,于是我给这地方设置了条件断点,当!plugin的时候就停下来,当断点再次停下来之后,我查看了堆栈
于是对更上一层的node_modules/webpack-chain/src/Config.js断点了,重新开始调试
然后发现了宝贝,可以看到上图中,包含html这插件,但同时也包含html-page1和html-page2这两个插件,于是修改vue.config.js
问题解决了,因为config.plugin("html")是针对单页面入口的,对于多页面入口,vue为每个页面单独多开了一个插件html-页面名,因此需要在chainWebpack里面为每一个入口都单独定制。优化后可以这样写
实际上我后俩又折腾了一下,想知道这html-页面名的插件到底是怎么来的,于是对node_modules/webpack-chain/src/Config.js下了条件断点,当name === "html-page1" || name === "html-page2"的时候断点,然后查看调用堆栈,在node_modules/@vue/cli-service/lib/config/app.js里面找到了这么几行,所以可以知道vue在处理pages的时候,利用html-webpack-plugin为每个页面生成了单独的html插件
webpackConfig
.plugin(html-${name})
.use(HTMLPlugin, [pageHtmlOptions])