diff --git a/packages/vite/src/node/__tests__/build.spec.ts b/packages/vite/src/node/__tests__/build.spec.ts index 79e2a612c274e5..024bba0322a447 100644 --- a/packages/vite/src/node/__tests__/build.spec.ts +++ b/packages/vite/src/node/__tests__/build.spec.ts @@ -144,6 +144,33 @@ describe('build', () => { assertOutputHashContentChange(result[0], result[1]) }) + test('css entries with the same basename should not cross-link manifest assets', async () => { + const root = resolve(dirname, 'fixtures/css-entry-same-basename') + const result = (await build({ + root, + logLevel: 'silent', + build: { + write: false, + manifest: true, + assetsInlineLimit: 0, + rollupOptions: { + input: [resolve(root, 'a/index.css'), resolve(root, 'b/index.css')], + }, + }, + })) as RolldownOutput + + const manifest = JSON.parse( + (result.output.find((o) => o.fileName === '.vite/manifest.json') as any) + .source, + ) + expect(manifest['a/index.css']).toMatchObject({ + isEntry: true, + }) + expect(manifest['b/index.css']).toMatchObject({ + isEntry: true, + }) + }) + test.for([ [true, true], [true, false], diff --git a/packages/vite/src/node/__tests__/fixtures/css-entry-same-basename/a/index.css b/packages/vite/src/node/__tests__/fixtures/css-entry-same-basename/a/index.css new file mode 100644 index 00000000000000..98b1044b009ca5 --- /dev/null +++ b/packages/vite/src/node/__tests__/fixtures/css-entry-same-basename/a/index.css @@ -0,0 +1,3 @@ +.entry-a { + background-color: red; +} diff --git a/packages/vite/src/node/__tests__/fixtures/css-entry-same-basename/b/index.css b/packages/vite/src/node/__tests__/fixtures/css-entry-same-basename/b/index.css new file mode 100644 index 00000000000000..ad560331d88c6d --- /dev/null +++ b/packages/vite/src/node/__tests__/fixtures/css-entry-same-basename/b/index.css @@ -0,0 +1,3 @@ +.entry-b { + background-color: blue; +} diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index b5e2b652da3cbc..7604e848cc472a 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -56,7 +56,7 @@ const assetCache = new WeakMap>() /** a set of referenceId for entry CSS assets for each environment */ export const cssEntriesMap: WeakMap< Environment, - Map + Map > = new WeakMap() // add own dictionary entry by directly assigning mrmime diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 0b5f800408d986..596caaef46e28f 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -914,7 +914,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { if (isEntry) { cssEntriesMap .get(this.environment)! - .set(chunk.name, referenceId) + .set(chunk.fileName, { referenceId, name: chunk.name }) } chunk.viteMetadata!.importedCss.add( this.getFileName(referenceId), @@ -1103,13 +1103,13 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { const removedPureCssFiles = removedPureCssFilesCache.get(config)! pureCssChunkNames.forEach((fileName) => { - const emptyJsPlaceholder = bundle[fileName] as RenderedChunk + const emptyJsPlaceholder = bundle[fileName] as OutputChunk if (emptyJsPlaceholder.isEntry) { const { importedAssets, importedCss } = emptyJsPlaceholder.viteMetadata! const cssReferenceId = cssEntriesMap .get(this.environment)! - .get(emptyJsPlaceholder.name)! + .get(emptyJsPlaceholder.preliminaryFileName)!.referenceId const realCssEntryName = this.getFileName(cssReferenceId) const realCssEntry = bundle[realCssEntryName]! importedCss.delete(realCssEntryName) diff --git a/packages/vite/src/node/plugins/manifest.ts b/packages/vite/src/node/plugins/manifest.ts index 70ec394874663a..feff710a7bc9f0 100644 --- a/packages/vite/src/node/plugins/manifest.ts +++ b/packages/vite/src/node/plugins/manifest.ts @@ -100,7 +100,11 @@ export function manifestPlugin(): Plugin { environment.config.isOutputOptionsForLegacyChunks, cssEntries() { return Object.fromEntries( - cssEntriesMap.get(envs[environment.name])!.entries(), + [...cssEntriesMap.get(envs[environment.name])!.values()].map( + ({ name, referenceId }) => { + return [referenceId, name] + }, + ), ) }, }),