Skip to content

Chunk optimization fails with "Multiple conflicting contents for sourcemap source" when a fileReplacements target imports a same-named file next to the replaced file #33891

Description

@SebastianPost1996

Command

build

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

21

Description

Since updating to Angular 22, a production-style build (optimization on, sourceMap: true) fails during the new default chunk optimization pass:

X [ERROR] Chunk optimization failed
  Multiple conflicting contents for sourcemap source <root>/libs/env/src/environment.dev.ts

The build succeeds with NG_BUILD_OPTIMIZE_CHUNKS=0, which is our current workaround.

The setup that triggers it: a fileReplacements entry whose with file lives in a different directory and imports a file that has the same basename and sits next to the replace file.

libs/env/src/environment.ts          <- "replace"
libs/env/src/environment.dev.ts      <- real file, imported by the replacement
apps/app1/src/env/environment.dev.ts <- "with", imports ../../../../libs/env/src/environment.dev
"fileReplacements": [
  {
    "replace": "libs/env/src/environment.ts",
    "with": "apps/app1/src/env/environment.dev.ts"
  }
]

The dev configuration also has "optimization": { "scripts": true, ... } and "sourceMap": true, and the app has more than 3 lazy chunks, so the chunk optimizer runs.

What I found

Building with NG_BUILD_OPTIMIZE_CHUNKS=0 and inspecting the emitted .js.map files shows the same source path recorded twice in one chunk, with different sourcesContent:

chunk-XXXX.js.map sources:
  libs/env/src/environment.dev.ts   (content of the real lib file)
  libs/env/src/environment.dev.ts   (content of apps/app1/src/env/environment.dev.ts!)

So the replaced module is recorded under dirname(replace) + basename(with) instead of the actual path of the with file. My understanding of the cause: the replacement happens in the compiler plugin's onLoad hook, so the esbuild module keeps the original path, and the emitted sourcemap for the compiled replacement file only carries the basename, which esbuild then resolves against the original module's directory.

This wrong path is harmless on its own, but when it collides with a real module that is also in the bundle (here: the lib's own environment.dev.ts, imported by the replacement file), the rollup-based chunk optimizer refuses to merge the sourcemaps and the whole build fails.

Minimal Reproduction

see above

Exception or Error

Application bundle generation failed.

X [ERROR] Chunk optimization failed
  Multiple conflicting contents for sourcemap source <root>/libs/env/src/environment.dev.ts

Your Environment

Angular CLI / @angular/build: 22.0.9
Angular: 22.0.8
Node: 22.13.0
Package manager: npm
OS: reproduced on both Windows 11 and macOS

Anything else relevant?

Workaround: NG_BUILD_OPTIMIZE_CHUNKS=false.

Expected behavior: the sourcemap source for a replaced module should be the path of the with file (or at least a path that cannot collide with a different real module), and chunk optimization should not fail the build over it.

Two notes: the placeholder stands for the absolute workspace path from the real error output, and I kept the lazy-chunk condition in ("more than 3 lazy chunks") since the optimizer only runs above that threshold — without it their triage can't repro.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: @angular/buildgemini-triagedLabel noting that an issue has been triaged by geminineeds: repro stepsWe cannot reproduce the issue with the information given

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions