本文介绍了Webpack、html-webpack-plugin、错误:子编译失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

错误堆栈:Html Webpack 插件:

Error Stack:Html Webpack Plugin:


  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[预构建]/[html-webpack-plugin]/lib/compiler.js:76:16

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

Compiler.js:291 编译器.[预构建]/[webpack]/lib/Compiler.js:291:10

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

Compiler.js:494[预构建]/[webpack]/lib/Compiler.js:494:13

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

Tapable.js:138 下一个[预构建]/[tapable]/lib/Tapable.js:138:11

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

CachePlugin.js:62 编译器.[预构建]/[webpack]/lib/CachePlugin.js:62:5

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

Tapable.js:142 Compiler.applyPluginsAsyncSeries[预构建]/[tapable]/lib/Tapable.js:142:13

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

Compiler.js:491[预构建]/[webpack]/lib/Compiler.js:491:10

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

Tapable.js:131 Compilation.applyPluginsAsyncSeries[预构建]/[tapable]/lib/Tapable.js:131:46

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

Compilation.js:645 self.applyPluginsAsync.err[预构建]/[webpack]/lib/Compilation.js:645:19

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

Tapable.js:131 Compilation.applyPluginsAsyncSeries[预构建]/[tapable]/lib/Tapable.js:131:46

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

Compilation.js:636 self.applyPluginsAsync.err[预构建]/[webpack]/lib/Compilation.js:636:11

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

Tapable.js:131 Compilation.applyPluginsAsyncSeries[预构建]/[tapable]/lib/Tapable.js:131:46

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

Compilation.js:631 self.applyPluginsAsync.err[预构建]/[webpack]/lib/Compilation.js:631:10

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

Tapable.js:131 Compilation.applyPluginsAsyncSeries[预构建]/[tapable]/lib/Tapable.js:131:46

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

Compilation.js:627 sealPart2[预构建]/[webpack]/lib/Compilation.js:627:9

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

Tapable.js:131 Compilation.applyPluginsAsyncSeries[预构建]/[tapable]/lib/Tapable.js:131:46

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

Compilation.js:575 Compilation.seal[预构建]/[webpack]/lib/Compilation.js:575:8

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

Compiler.js:488[预构建]/[webpack]/lib/Compiler.js:488:16

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

Tapable.js:225[预构建]/[tapable]/lib/Tapable.js:225:11

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

Compilation.js:477 _addModuleChain[预构建]/[webpack]/lib/Compilation.js:477:11

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

Compilation.js:448 processModuleDependencies.err[预构建]/[webpack]/lib/Compilation.js:448:13

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

next_tick.js:73 _combinedTickCallback内部/进程/next_tick.js:73:7

next_tick.js:73 _combinedTickCallbackinternal/process/next_tick.js:73:7

next_tick.js:104 process._tickCallback内部/进程/next_tick.js:104:9

next_tick.js:104 process._tickCallbackinternal/process/next_tick.js:104:9

我的 webpack 配置代码:

My webpack configuration code:

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.

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

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

推荐答案

问题确实出在 file-loader 上,因为它只是简单地将文件复制过来.当 html-webpack-plugin 尝试编写 index.html 时,它已经由 file-loader 编写,因此导致冲突.

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

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

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

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

You could use html-loader for 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 文件使用 file-loader,你可以排除 index.html 所以 html-webpack-plugin 回退到它的默认加载器.require.resolverequire 的工作方式类似,但为您提供模块的完整路径而不是其内容.

If you want to keep using the file-loader for your other HTML files, you can exclude the index.html so html-webpack-plugin falls back to its default loader. require.resolve works like require but gives you the full path of the module instead of its content.

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

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

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

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

这篇关于Webpack、html-webpack-plugin、错误:子编译失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 12:16