diff --git a/packages/compiler-cli/src/ngtsc/annotations/component/src/hmr.ts b/packages/compiler-cli/src/ngtsc/annotations/component/src/hmr.ts index cb5a2424e95..dd9b6d3ce36 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/component/src/hmr.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/component/src/hmr.ts @@ -32,7 +32,6 @@ export function extractHmrInitializerMeta( const meta: R3HmrInitializerMetadata = { type: new WrappedNodeExpr(clazz.name), className: clazz.name.text, - timestamp: Date.now() + '', filePath, }; diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 74cb1964fe4..c24070546ff 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -10798,8 +10798,9 @@ runInEachFileSystem((os: string) => { /import\.meta\.hot && import\.meta\.hot\.on\("angular:component-update", d => { if \(d\.id == "test\.ts%40Cmp"\) {/, ); expect(jsContents).toMatch( - /import\("\/@ng\/component\?c=test\.ts%40Cmp&t=\d+"\).then\(m => i0\.ɵɵreplaceMetadata\(Cmp, m\.default\)\);/, + /import\(\s*\/\* @vite-ignore \*\/\s+"\/@ng\/component\?c=test\.ts%40Cmp&t=" \+ encodeURIComponent\(d.timestamp\)/, ); + expect(jsContents).toMatch(/\).then\(m => i0\.ɵɵreplaceMetadata\(Cmp, m\.default\)\);/); }); }); diff --git a/packages/compiler/src/render3/r3_hmr_compiler.ts b/packages/compiler/src/render3/r3_hmr_compiler.ts index 5e3ae3a3096..fc7144c30dd 100644 --- a/packages/compiler/src/render3/r3_hmr_compiler.ts +++ b/packages/compiler/src/render3/r3_hmr_compiler.ts @@ -20,19 +20,12 @@ export interface R3HmrInitializerMetadata { /** File path of the component class. */ filePath: string; - - /** - * Timestamp when the compilation took place. - * Necessary to invalidate the browser cache. - */ - timestamp: string; } /** Compiles the HMR initializer expression. */ export function compileClassHmrInitializer(meta: R3HmrInitializerMetadata): o.Expression { const id = encodeURIComponent(`${meta.filePath}@${meta.className}`); - const timestamp = encodeURIComponent(meta.timestamp); - const url = `/@ng/component?c=${id}&t=${timestamp}`; + const urlPartial = `/@ng/component?c=${id}&t=`; const moduleName = 'm'; const dataName = 'd'; @@ -44,8 +37,18 @@ export function compileClassHmrInitializer(meta: R3HmrInitializerMetadata): o.Ex // (m) => ɵɵreplaceMetadata(...) const replaceCallback = o.arrowFn([new o.FnParam(moduleName)], replaceMetadata); - // import(url).then(() => replaceMetadata(...)); - const dynamicImport = new o.DynamicImportExpr(url).prop('then').callFn([replaceCallback]); + // '' + encodeURIComponent(d.timestamp) + const urlValue = o + .literal(urlPartial) + .plus(o.variable('encodeURIComponent').callFn([o.variable(dataName).prop('timestamp')])); + + // import(/* @vite-ignore */ url).then(() => replaceMetadata(...)); + // The vite-ignore special comment is required to avoid Vite from generating a superfluous + // warning for each usage within the development code. If Vite provides a method to + // programmatically avoid this warning in the future, this added comment can be removed here. + const dynamicImport = new o.DynamicImportExpr(urlValue, null, '@vite-ignore') + .prop('then') + .callFn([replaceCallback]); // (d) => { if (d.id === ) { replaceMetadata(...) } } const listenerCallback = o.arrowFn(