冲突:多个资产发出相同的文件名

Conflict: Multiple assets emit to the same filename

我是一个webpack小白,想要一探究竟。 当 运行 我的 webpack 告诉我:

时,我遇到了冲突

ERROR in chunk html [entry] app.js Conflict: Multiple assets emit to the same filename app.js

我应该怎么做才能避免冲突?

这是我的 webpack.config.js:

module.exports = {
  context: __dirname + "/app",

  entry: {
    'javascript': "./js/app.js",
    'html': "./index.html",
  },
  output: {
    path: __dirname + "/dist",
    filename: "app.js",
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json']
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loaders: ["babel-loader"]
      },
      {
        test: /\.html$/,
        loader: "file-loader?name=[name].[ext]",
      }
    ]
  }
};

我不太熟悉你的方法,所以我会告诉你一个常用的方法来帮助你。

首先,在您的 output 上,您将 filename 指定为 app.js,这对我来说很有意义,输出仍然是 app.js。如果你想让它动态化,那么只需使用 "filename": "[name].js".

[name] 部分将为您动态生成文件名。这就是您 entry 作为对象的目的。每个键都将用作替换 [name].js.

的名称

其次,您可以使用html-webpack-plugin。您不需要将其包含为 test

我遇到了完全相同的问题。 file-loader 似乎出现了问题。当我删除 html 测试并包含 html-webpack-plugin 而不是生成 index.html 文件时,错误消失了。这是我的 webpack.config.js 文件:

var path = require('path');

var HtmlWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
  template: __dirname + '/app/index.html',
  filename: 'index.html',
  inject: 'body'
})

module.exports = { 
  entry: {
    javascript: './app/index.js',
  },  

  output: {
    filename: 'bundle.js',
    path: __dirname + '/dist'
  },  

  module: {
    rules: [
      {   
        test: /\.jsx?$/,
        exclude: [
          path.resolve(__dirname, '/node_modules/')
        ],  
        loader: 'babel-loader'
      },  
    ]   
  },  

  resolve: {
    extensions: ['.js', '.jsx', '.json']
  },  

  plugins: [HTMLWebpackPluginConfig]
}

html-webpack-plugin生成一个index.html文件,并自动将打包后的js文件注入其中。

我遇到了同样的问题,我发现是设置静态输出文件名导致了我的问题,在输出对象中尝试以下对象。

output:{
        filename: '[name].js',
        path: __dirname + '/build',
        chunkFilename: '[id].[chunkhash].js'
    },

这使得文件名不同并且不会冲突。

编辑: 我最近发现的一件事是,如果使用 HMR 重新加载,你应该使用散列而不是 chunkhash。我没有深入研究问题的根源,但我只知道使用 chunkhash 破坏了我的 webpack 配置

output: {
  path: path.resolve(__dirname, 'dist'),
  filename: '[name].[hash:8].js',
  sourceMapFilename: '[name].[hash:8].map',
  chunkFilename: '[id].[hash:8].js'
};

然后应该可以与 HMR 一起正常工作:)

编辑 2018 年 7 月:

关于此的更多信息。

哈希 这是每次 webpack 编译时生成的哈希值,在开发模式下,这有利于开发期间的缓存清除,但不应用于文件的长期缓存。这将覆盖您项目的每个构建的哈希。

Chunkhash 如果你将它与运行时块结合使用,那么你可以将它用于长期缓存,运行时块将看到你的源代码中发生了什么变化并更新相应的块哈希。它不会更新其他允许您的文件被缓存。

我遇到了同样的问题,我在文档中找到了这些。

If your configuration creates more than a single “chunk” (as with multiple entry points or when using plugins like CommonsChunkPlugin), you should use substitutions to ensure that each file has a unique name.

  • [name] is replaced by the name of the chunk.
  • [hash] is replaced by the hash of the compilation.
  • [chunkhash] is replaced by the hash of the chunk.
 output: {
    path:__dirname+'/dist/js',

    //replace filename:'app.js' 
    filename:'[name].js'
}

我在本地开发环境中遇到了这个错误。对我来说,解决此错误的方法是强制重建文件。为此,我对我的一个 CSS 文件做了一个小改动。

我重新加载了浏览器,错误消失了。

在 Vue.js 项目中使用 Karma 进行 e2e 时出现同样的错误。该页面使用静态模板 index.html/dist/build.js 提供。并得到这个错误 运行 业力。

使用 package.json 发出 Karma 的命令是:

"test": "cross-env BABEL_ENV=test CHROME_BIN=$(which chromium-browser) karma start --single-run"

webpack.config.js 中的输出配置为:

 module.exports = {
  output: {
   path: path.resolve(__dirname, './dist'),
   publicPath: '/dist/',
   filename: 'build.js'
  },
  ...
 }

我的解决方案:受 Evan Burbidge 的回答启发,我在 webpack.config.js 的末尾附加了以下内容:

if (process.env.BABEL_ENV === 'test') {
  module.exports.output.filename = '[name].[hash:8].js'
}

然后它最终适用于页面服务和 e2e。

我将 index.html 文件从 /public 目录更改为 /src 以解决此问题。 (网页包 5.1.3)

在将所有依赖项更新为最新版本(例如 webpack 4 -> 5)后,我遇到了同样的问题,因为我大约 2 年前制作的 Chrome 扩展,并设法解决了它。

投诉中有两个文件(popup.htmloptions.html)。这是我的原始 webpack.config.js 文件:

const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
    target: 'web',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },
    entry: {
        popup: './src/scripts/popup.tsx',
        options: './src/scripts/options.tsx',
    },
    context: path.join(__dirname),
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                ],
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader',
                ],
            },
        ],
    },

    resolve: {
        extensions: ['.tsx', '.ts', '.js', '.json', '.css'],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new CopyPlugin([
            { from: 'src/popup.html', to: 'popup.html' },
            { from: 'src/options.html', to: 'options.html' },
            { from: 'src/manifest.json', to: 'manifest.json' },
            { from: 'src/icons', to: 'icons' },
        ]),
        new HtmlWebpackPlugin({
            template: path.join("src", "popup.html"),
            filename: "popup.html",
            chunks: ["popup"]
        }),
        new HtmlWebpackPlugin({
            template: path.join("src", "options.html"),
            filename: "options.html",
            chunks: ["options"]
        }),
    ]
};

我通过删除解决了它:

            { from: 'src/popup.html', to: 'popup.html' },
            { from: 'src/options.html', to: 'options.html' },

new CopyPlugin... 部分下。

所以现在似乎没有必要明确地将 popup.htmloptions.html 复制到输出文件夹,因为 HtmlWebpackPlugin 已经发出它们。

升级到 Webpack 5 后我遇到了同样的问题。我的问题是由 copy-webpack-plugin.

引起的

下面是忽略指定文件的原始模式,它适用于 Webpack 4,但在 Webpack 5 中会抛出错误。

ERROR in Conflict: Multiple assets emit different content to the same filename default.hbs

  plugins: [
   new CopyPlugin({
      patterns: [
        {
          from: "./src/academy/templates",
          globOptions: {
            ignore: ["default.hbs"]
          }
        },
      ]
    }),
   ],

修复错误:

  plugins: [
   new CopyPlugin({
      patterns: [
        {
          from: "./src/academy/templates",
          globOptions: {
            ignore: ["**/default.hbs"]
          }
        },
      ]
    }),
   ],

通过不忽略指定的文件,default.hbs (a.k.a index.html) 被复制两次到构建 (a.k.a /disk) 目录中有效地导致 Webpack试图将多个资产插入到“相同”(重复的)文件名中。

在我的例子中,source map 插件与 extract mini 插件冲突。 无法在任何地方找到解决方案。 css 和 javascript 的源映射正在写入同一个文件。这是我最终在我的项目中解决它的方法:

new webpack.SourceMapDevToolPlugin({
    filename: '[name].[ext].map'
}),

与上面的文件加载器类似的解决方案,但是,我认为这个解决方案更优雅。之前,我只是指定 [name],添加 [path][name] 解决了我的冲突,如下所示:

module: {
rules: [
  {
    test: /\.(mp4|m4s)$/,
    use: [
      {
        loader: 'file-loader',
        options: {
          name: '[path][name].[ext]',
        },
      },
    ],
  },
],

我在将 webpack 3 升级到 webpack 4 时遇到了类似的问题。升级模块后我遇到了这个错误。

WARNING in Conflict: Multiple assets emit different content to the same filename alert-icon.svg

WARNING in Conflict: Multiple assets emit different content to the same filename comment.svg

问题是由 fileloader for svg 引起的。通过添加散列 name: '[name].[hash:8].[ext]' 使其在每次 webpack 编译时都是唯一的来解决错误。

提供以下代码:

module: {
rules: [
  {
  test: /\.svg$/,
  loader: 'file-loader',
  query: {
    name: '[name].[hash:8].[ext]'
  }  
]   

}