diff --git a/packages/vite/src/node/plugins/reporter.ts b/packages/vite/src/node/plugins/reporter.ts index f36081041ca1c5..0135f552e8845d 100644 --- a/packages/vite/src/node/plugins/reporter.ts +++ b/packages/vite/src/node/plugins/reporter.ts @@ -111,7 +111,35 @@ export function buildReporterPlugin(config: ResolvedConfig): Plugin { compressedCount = 0 }, - renderChunk() { + renderChunk(code, chunk) { + for (const id of chunk.moduleIds) { + const module = this.getModuleInfo(id) + if (!module) continue + // When a dynamic importer shares a chunk with the imported module, + // warn that the dynamic imported module will not be moved to another chunk (#12850). + if (module.importers.length && module.dynamicImporters.length) { + // Filter out the intersection of dynamic importers and sibling modules in + // the same chunk. The intersecting dynamic importers' dynamic import is not + // expected to work. Note we're only detecting the direct ineffective + // dynamic import here. + if ( + module.dynamicImporters.some((m) => chunk.moduleIds.includes(m)) + ) { + this.warn( + `\n(!) ${ + module.id + } is dynamically imported by ${module.dynamicImporters + .map((m) => m) + .join(', ')} but also statically imported by ${module.importers + .map((m) => m) + .join( + ', ', + )}, dynamic import will not move module into another chunk.\n`, + ) + } + } + } + chunkCount++ if (shouldLogInfo) { if (!tty) { diff --git a/playground/dynamic-import/__tests__/dynamic-import.spec.ts b/playground/dynamic-import/__tests__/dynamic-import.spec.ts index 91e7ae35d0afaf..daa378da6ef1af 100644 --- a/playground/dynamic-import/__tests__/dynamic-import.spec.ts +++ b/playground/dynamic-import/__tests__/dynamic-import.spec.ts @@ -129,3 +129,22 @@ test('should work with load ../ and contain itself directory', async () => { true, ) }) + +test.runIf(isBuild)( + 'should rollup warn when static and dynamic import a module in same chunk', + async () => { + const log = serverLogs.join('\n') + expect(log).toContain( + 'dynamic import will not move module into another chunk', + ) + expect(log).toMatch( + /\(!\).*\/dynamic-import\/files\/mxd\.js is dynamically imported by/, + ) + expect(log).toMatch( + /\(!\).*\/dynamic-import\/files\/mxd\.json is dynamically imported by/, + ) + expect(log).not.toMatch( + /\(!\).*\/dynamic-import\/nested\/shared\.js is dynamically imported by/, + ) + }, +)