diff --git a/lib/Compiler.js b/lib/Compiler.js index 7b852fd06..64906e4cc 100644 --- a/lib/Compiler.js +++ b/lib/Compiler.js @@ -14,7 +14,6 @@ const { AsyncSeriesHook } = require("tapable"); const { SizeOnlySource } = require("webpack-sources"); - const Cache = require("./Cache"); const Compilation = require("./Compilation"); const ConcurrentCompilationError = require("./ConcurrentCompilationError"); @@ -24,6 +23,7 @@ const RequestShortener = require("./RequestShortener"); const ResolverFactory = require("./ResolverFactory"); const Stats = require("./Stats"); const Watching = require("./Watching"); +const WebpackError = require("./WebpackError"); const { Logger } = require("./logging/Logger"); const { join, dirname, mkdirp } = require("./util/fs"); const { makePathsRelative } = require("./util/identifier"); @@ -480,6 +480,7 @@ class Compiler { const assets = compilation.getAssets(); compilation.assets = { ...compilation.assets }; + const caseInsensitiveMap = new Map(); asyncLib.forEachLimit( assets, 15, @@ -498,6 +499,19 @@ class Compiler { targetFile ); + const caseInsensitiveTargetPath = targetPath.toLowerCase(); + if (caseInsensitiveMap.has(caseInsensitiveTargetPath)) { + const other = caseInsensitiveMap.get(caseInsensitiveTargetPath); + const err = new WebpackError(`Prevent writing to file that only differs in casing from already written file. +This will lead to a race-condition and corrupted files on case-insensitive file systems. +${targetPath} +${other}`); + err.file = file; + return callback(err); + } else { + caseInsensitiveMap.set(caseInsensitiveTargetPath, targetPath); + } + // check if the target file has already been written by this Compiler const targetFileGeneration = this._assetEmittingWrittenFiles.get( targetPath diff --git a/test/configCases/errors/case-emit/errors.js b/test/configCases/errors/case-emit/errors.js new file mode 100644 index 000000000..0e4de2461 --- /dev/null +++ b/test/configCases/errors/case-emit/errors.js @@ -0,0 +1 @@ +module.exports = [[/only differs in casing/, /a\.js/, /A\.js/]]; diff --git a/test/configCases/errors/case-emit/index.js b/test/configCases/errors/case-emit/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/configCases/errors/case-emit/webpack.config.js b/test/configCases/errors/case-emit/webpack.config.js new file mode 100644 index 000000000..9b771c254 --- /dev/null +++ b/test/configCases/errors/case-emit/webpack.config.js @@ -0,0 +1,10 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + a: "./index.js?1", + A: "./index.js?2" + }, + output: { + filename: "[name].js" + } +};