vue报错 Multiple assets emit different content to the same filename index.html

发布时间 2023-08-07 12:40:58作者: 飞向狙沙

vue-cli版本:@vue/cli@5.0.8

报错现象:想把css和script全部内嵌到html文件中,就用了"HtmlInlineScriptPlugin"插件,打包后js代码被嵌到了head里,导致代码提前执行找不到#app,再配置HtmlWebpackPlugin插件通过inject: "body"指定代码内嵌到body,打包报错"Multiple assets emit different content to the same filename index.html"

报错原因:通过查询源码发现"node_modules\@vue\cli-service\lib\config\app.js"文件中引用了一个HtmlWebpackPlugin插件

// resolve HTML file(s)
    const HTMLPlugin = require('html-webpack-plugin')
    // const PreloadPlugin = require('@vue/preload-webpack-plugin')
    const multiPageConfig = options.pages
    const htmlPath = api.resolve('public/index.html')
    const defaultHtmlPath = path.resolve(__dirname, 'index-default.html')
    const publicCopyIgnore = ['**/.DS_Store']

    if (!multiPageConfig) {
      // default, single page setup.
      htmlOptions.template = fs.existsSync(htmlPath)
        ? htmlPath
        : defaultHtmlPath

      publicCopyIgnore.push(api.resolve(htmlOptions.template).replace(/\\/g, '/'))

      webpackConfig
        .plugin('html')
          .use(HTMLPlugin, [htmlOptions])

 在configureWebpack配置HtmlWebpackPlugin插件导致冲突,自定义的HtmlWebpackPlugin插件和脚手架的插件同时向默认的index.html中写入内容导致报错

config.plugins.push(
    new HtmlWebpackPlugin({
        inject: "body",
    })) 

解决方案:

      方案1: HtmlWebpackPlugin配置输出文件名为app.html(打包后dist文件夹中会同时有app.html和index.html,app.html为可用文件)

 new HtmlWebpackPlugin({
	filename: "app.html",
	templateParameters: {
		BASE_URL: `/`
	},
	template: resolve("./public/index.html"),
	inlineSource: ".(js|css)$",
	inject: "body",
}),   

      方案2:在chainWebpack中配置HtmlWebpackPlugin覆盖脚手架配置

chainWebpack: (config) => {
	config
		.plugin('html')
		.use(new HtmlWebpackPlugin({
			filename: "index.html",
			templateParameters: {
				BASE_URL: `/`
			},
			template: resolve("./public/index.html"),
			inlineSource: ".(js|css)$",
			inject: "body",
		}))
},   

 

完整配置:

      修改前:

//部分
module.exports = {
    configureWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            config.plugins.push(
                new HtmlWebpackPlugin({
                filename: "index.html",
                templateParameters: {
                    BASE_URL: `/`
                },
                template: resolve("./public/index.html"),
                inlineSource: ".(js|css)$",
                inject: "body",
            })
            )
        }
    },
    chainWebpack: (config) => {
       
    },
}

  修改后:

module.exports = {
    configureWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
        
        }
    },
    chainWebpack: (config) => {
        config
            .plugin('html')
            .use(new HtmlWebpackPlugin({
                filename: "index.html",
                templateParameters: {
                    BASE_URL: `/`
                },
                template: resolve("./public/index.html"),
                inlineSource: ".(js|css)$",
                inject: "body",
            }))
    },
}

后记:

修改后使用的HtmlWebpackPlugin插件时new出来的对象,脚手架自用的是静态类,暂时不知道为什么这样用,改后有没有什么影响,HtmlWebpackPlugin有几个静态方法特别是getHooks估计会有影响,遇到了再研究吧