Javascript Webpack、html-webpack-plugin、错误:子编译失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43494794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:58:31  来源:igfitidea点击:

Webpack, html-webpack-plugin, Error: Child compilation failed

javascriptwebpackhtml-webpack-plugin

提问by Jakub Chlebowicz

I 've got a problem with my webpack configuration. After implementing html-webpack-plugin I got an Error, there's whole error stack from generated index.html.

我的 webpack 配置有问题。实现 html-webpack-plugin 后,我得到了一个错误,从生成的index.html.

Error Stack: Html Webpack Plugin:

错误堆栈:Html Webpack 插件:

  Error: Child compilation failed:
  Conflict: Multiple assets emit to the same filename index.html:
  Error: Conflict: Multiple assets emit to the same filename index.html

  • compiler.js:76 [Pre-build]/[html-webpack-plugin]/lib/compiler.js:76:16

  • Compiler.js:291 Compiler. [Pre-build]/[webpack]/lib/Compiler.js:291:10

  • Compiler.js:494 [Pre-build]/[webpack]/lib/Compiler.js:494:13

  • Tapable.js:138 next [Pre-build]/[tapable]/lib/Tapable.js:138:11

  • CachePlugin.js:62 Compiler. [Pre-build]/[webpack]/lib/CachePlugin.js:62:5

  • Tapable.js:142 Compiler.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:142:13

  • Compiler.js:491 [Pre-build]/[webpack]/lib/Compiler.js:491:10

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:645 self.applyPluginsAsync.err [Pre-build]/[webpack]/lib/Compilation.js:645:19

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:636 self.applyPluginsAsync.err [Pre-build]/[webpack]/lib/Compilation.js:636:11

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:631 self.applyPluginsAsync.err [Pre-build]/[webpack]/lib/Compilation.js:631:10

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:627 sealPart2 [Pre-build]/[webpack]/lib/Compilation.js:627:9

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:575 Compilation.seal [Pre-build]/[webpack]/lib/Compilation.js:575:8

  • Compiler.js:488 [Pre-build]/[webpack]/lib/Compiler.js:488:16

  • Tapable.js:225 [Pre-build]/[tapable]/lib/Tapable.js:225:11

  • Compilation.js:477 _addModuleChain [Pre-build]/[webpack]/lib/Compilation.js:477:11

  • Compilation.js:448 processModuleDependencies.err [Pre-build]/[webpack]/lib/Compilation.js:448:13

  • next_tick.js:73 _combinedTickCallback internal/process/next_tick.js:73:7

  • next_tick.js:104 process._tickCallback internal/process/next_tick.js:104:9

My webpack configuration code:

我的 webpack 配置代码:

var webpack = require('webpack'),
    path = require('path');


var CopyWebpackPlugin = require('copy-webpack-plugin'),
    ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'),
    HtmlWebpackPlugin = require('html-webpack-plugin'),

const sourcePath = path.resolve(__dirname, './src');
const staticPath = path.resolve(__dirname, './static');

module.exports = function (env) {

    const nodeEnv = env && env.prod ? 'production' : 'development';
    const isProd = nodeEnv === 'production';

    const postcssLoader = {
        loader: 'postcss-loader',
        options: {
            plugins: function () {
                return [
                    require('autoprefixer')
                ];
            }
        }
    }

    const plugins = [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks: Infinity,
            filename: 'vendor.bundle.js'
        }),
        new webpack.EnvironmentPlugin({
            NODE_ENV: nodeEnv,
        }),
        new HtmlWebpackPlugin({
            template: 'index.html',
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
            },
            chunksSortMode: 'dependency'
        })
    ];

    if(isProd) {
        plugins.push(
            new webpack.LoaderOptionsPlugin({
                minimize: true,
                debug: false
            }),
            new webpack.optimize.UglifyJsPlugin({
                compress: {
                    warnings: false,
                    screw_ie8: true,
                    conditionals: true,
                    unused: true,
                    comparisons: true,
                    sequences: true,
                    dead_code: true,
                    evaluate: true,
                    if_return: true,
                    join_vars: true,
                },
                output: {
                    comments: false,
                },
            })
        );
    } else {
        plugins.push(
            new webpack.HotModuleReplacementPlugin()
        );
    }

    return {
        devtool: isProd? 'source-map' : 'eval',
        context: sourcePath,

        entry: {
            app: './app/entry.ts',
            vendor: './app/vendor.ts'
        },

        output: {
            path: staticPath,
            filename: '[name].bundle.js',
        },

        module: {
            rules: [
                {
                    test: /\.html$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'file-loader',
                        query: {
                            name: '[name].[ext]'
                        },
                    },
                },
                {
                    test: /\.css$/,
                    exclude: /node_modules/,
                    use: [
                        'style-loader',
                        'css-loader',
                        'postcss-loader'
                    ]
                },
                {
                    test: /\.scss$/,
                    exclude: /node_modules/,
                    use: [
                        'style-loader',
                        'css-loader',
                        'postcss-loader',
                        'sass-loader'
                    ]
                },
                {
                    test: /\.ts$/,
                    exclude: /node_modules/,
                    use: [
                        'ts-loader'
                    ],
                },
            ],
        },

        resolve: {
            alias: {
                Public: path.resolve(__dirname,'src/public'),
                Style: path.resolve(__dirname,'src/styles')
            },
            extensions: ['.ts','.js', '.html'],
            modules: [
                path.resolve(__dirname, 'node_modules'),
                sourcePath
            ]
        },

        plugins,

        performance: isProd && {
            maxAssetSize: 100,
            maxEntrypointSize: 300,
            hints: 'warning'
        },

        stats: {
            colors: {
                green: '\u001b[32m'
            }
        },

        devServer: {
            contentBase: './src',
            historyApiFallback: true,
            port: 3000,
            compress: isProd,
            inline: !isProd,
            hot: !isProd,
            stats: {
                assets: true,
                children: false,
                chunks: false,
                hash: false,
                modules: false,
                publicPath: false,
                timings: true,
                version: false,
                warnings: true,
                color: {
                    green: '\u001b[32m'
                }
            },
        }
    };
};

I couldn't find any source of that Error, maybe I am little bit tired, but I would like to finish it up, so I hope for your help guys.

我找不到那个错误的任何来源,也许我有点累,但我想完成它,所以我希望你的帮助。

Maybe should I use some raw-loaderto load .html(?), which does not make me happy.

也许我应该使用一些raw-loader来加载.html(?),这让我不高兴。

回答by Michael Jungo

The problem is indeed the file-loader, because it simply copies the file over. By the time html-webpack-plugintries to write index.htmlit has already been written by file-loader, hence resulting in a conflict.

问题确实是file-loader,因为它只是简单地复制文件。到html-webpack-plugin尝试写入时,index.html它已经由 写入file-loader,因此导致冲突。

There are several ways to resolve that issue, depending on what your needs are.

有多种方法可以解决该问题,具体取决于您的需求。

You could use html-loaderfor your HTML, although if you expect your imported HTML to simply be copied, it isn't the correct choice. To be clear, by the imported HTML I don't mean the template used by the html-webpack-plugin.

您可以使用html-loader您的 HTML,但如果您希望简单地复制导入的 HTML,这不是正确的选择。需要明确的是,导入的 HTML 并不是指html-webpack-plugin.

If you want to keep using the file-loaderfor your other HTML files, you can exclude the index.htmlso html-webpack-pluginfalls back to its default loader. require.resolveworks like requirebut gives you the full path of the module instead of its content.

如果您想继续file-loader为其他 HTML 文件使用 ,则可以排除index.htmlsohtml-webpack-plugin回退到其默认加载器。require.resolve工作原理类似,require但为您提供模块的完整路径而不是其内容。

{
    test: /\.html$/,
    exclude: [/node_modules/, require.resolve('./index.html')],
    use: {
        loader: 'file-loader',
        query: {
            name: '[name].[ext]'
        },
    },
},

When no loader matches the template, the html-webpack-pluginuses an ejsloader as a fallback. If you don't need any loader for .htmlfiles, you could remove the rule entirely and it would work just fine. That is rather unlikely, otherwise you wouldn't have a .htmlrule in the first place, but this also means you can use the .ejsextension to not apply the .htmlrule, as all HTML is valid EJS. You would rename index.htmlto index.ejsand change your plugin configuration accordingly:

当没有加载器与模板匹配时,html-webpack-plugin使用ejs加载器作为后备。如果您不需要任何.html文件加载器,您可以完全删除规则,它会正常工作。这是不太可能的,否则您一开始就没有.html规则,但这也意味着您可以使用.ejs扩展来不应用.html规则,因为所有 HTML 都是有效的EJS。您将重命名index.htmlindex.ejs并相应地更改您的插件配置:

new HtmlWebpackPlugin({
    template: 'index.ejs',
    minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
    },
    chunksSortMode: 'dependency'
})