From fc643c904447d4d36519409574104f0dba4cb74a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 29 Sep 2025 14:32:10 +0000 Subject: [PATCH] build: adopt `moduleResolution: "bundler"` (#64125) This commit updates the TypeScript configuration across the project to use `moduleResolution: "bundler"`. This modernizes our module resolution strategy to align with current TypeScript best practices and bundler behaviors. The following changes are included: - Updated `tsconfig.json` files to set `moduleResolution` to `"bundler"`. - Updated the `rules_angular` bazel dependency to a version compatible with these changes. - Adjusted related test files and golden files to reflect the new module resolution strategy. PR Close #64125 --- MODULE.bazel | 2 +- .../pipeline/examples/template/tsconfig.json | 2 +- .../pipeline/tutorials/common/tsconfig.json | 2 +- .../angular-compiler-options/tsconfig.json | 2 +- .../src/lib/component-tree/component-tree.ts | 4 +- devtools/tsconfig.json | 2 +- .../public-api/localize/tools/index.api.md | 38 +++++++++++-------- .../cli-hello-world-ivy-i18n/tsconfig.json | 2 +- .../cli-hello-world-lazy/tsconfig.json | 2 +- integration/cli-hello-world/tsconfig.json | 2 +- integration/cli-signal-inputs/tsconfig.json | 2 +- integration/defer/tsconfig.json | 2 +- .../legacy-animations-async/tsconfig.json | 2 +- integration/legacy-animations/tsconfig.json | 2 +- integration/ng-add-localize/tsconfig.json | 2 +- integration/ng_elements/tsconfig.json | 2 +- .../platform-server-zoneless/tsconfig.json | 2 +- integration/platform-server/tsconfig.json | 2 +- .../standalone-bootstrap/tsconfig.json | 2 +- integration/trusted-types/tsconfig.json | 2 +- integration/typings_test_rxjs7/tsconfig.json | 4 +- integration/typings_test_ts59/tsconfig.json | 4 +- .../src/ngtsc/testing/src/utils.ts | 2 +- .../src/ngtsc/typecheck/testing/index.ts | 2 +- .../compliance/test_helpers/compile_test.ts | 2 +- packages/compiler-cli/test/ngtsc/env.ts | 2 +- .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 8 ++-- .../language-service/test/definitions_spec.ts | 2 +- .../test/legacy/project/tsconfig.json | 2 +- .../test/references_and_rename_spec.ts | 4 +- .../test/type_definitions_spec.ts | 10 ++--- .../language-service/testing/src/project.ts | 2 +- packages/tsconfig-build.json | 2 +- .../integration/project/tsconfig.json | 2 +- .../integration/tsconfig.json | 2 +- .../integration/workspace/tsconfig.json | 2 +- 36 files changed, 70 insertions(+), 60 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 7fb97fc8e93..819d8bee555 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -18,7 +18,7 @@ bazel_dep(name = "yq.bzl", version = "0.2.0") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "2c348bf59a38d044f4d389290d597d94c0699607", + commit = "399f782a14ecfd7de7c2736ec7f4f631b6a1b582", remote = "https://github.com/devversion/rules_angular.git", ) diff --git a/adev/shared-docs/pipeline/examples/template/tsconfig.json b/adev/shared-docs/pipeline/examples/template/tsconfig.json index ae207fd9185..cfa07e82c5c 100644 --- a/adev/shared-docs/pipeline/examples/template/tsconfig.json +++ b/adev/shared-docs/pipeline/examples/template/tsconfig.json @@ -8,7 +8,7 @@ "declaration": false, "downlevelIteration": true, "experimentalDecorators": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "importHelpers": true, "target": "es2022", "module": "es2020", diff --git a/adev/shared-docs/pipeline/tutorials/common/tsconfig.json b/adev/shared-docs/pipeline/tutorials/common/tsconfig.json index bc12e24b138..cbac491fd85 100644 --- a/adev/shared-docs/pipeline/tutorials/common/tsconfig.json +++ b/adev/shared-docs/pipeline/tutorials/common/tsconfig.json @@ -14,7 +14,7 @@ "declaration": false, "downlevelIteration": true, "experimentalDecorators": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "importHelpers": true, "target": "ES2022", "module": "ES2022", diff --git a/adev/src/content/examples/angular-compiler-options/tsconfig.json b/adev/src/content/examples/angular-compiler-options/tsconfig.json index 19ce4d59d94..6a8ab189b33 100644 --- a/adev/src/content/examples/angular-compiler-options/tsconfig.json +++ b/adev/src/content/examples/angular-compiler-options/tsconfig.json @@ -17,7 +17,7 @@ "declaration": false, "downlevelIteration": true, "experimentalDecorators": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "importHelpers": true, "target": "es2020", "module": "es2020", diff --git a/devtools/projects/ng-devtools-backend/src/lib/component-tree/component-tree.ts b/devtools/projects/ng-devtools-backend/src/lib/component-tree/component-tree.ts index 850238b1291..66a6692f730 100644 --- a/devtools/projects/ng-devtools-backend/src/lib/component-tree/component-tree.ts +++ b/devtools/projects/ng-devtools-backend/src/lib/component-tree/component-tree.ts @@ -58,7 +58,9 @@ export function getInjectorId() { return `${injectorId++}`; } -export function getInjectorMetadata(injector: Injector) { +export function getInjectorMetadata( + injector: Injector, +): ReturnType['ɵgetInjectorMetadata']>> { return ngDebugClient().ɵgetInjectorMetadata?.(injector) ?? null; } diff --git a/devtools/tsconfig.json b/devtools/tsconfig.json index 09964910aa4..e9d8ba1ceae 100644 --- a/devtools/tsconfig.json +++ b/devtools/tsconfig.json @@ -10,7 +10,7 @@ "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "esModuleInterop": true, "importHelpers": true, "target": "es2020", diff --git a/goldens/public-api/localize/tools/index.api.md b/goldens/public-api/localize/tools/index.api.md index 5f03495ba68..c97343af6f5 100644 --- a/goldens/public-api/localize/tools/index.api.md +++ b/goldens/public-api/localize/tools/index.api.md @@ -7,12 +7,20 @@ import { AbsoluteFsPath } from '@angular/compiler-cli/private/localize'; import { Element as Element_2 } from '@angular/compiler'; import { Logger } from '@angular/compiler-cli/private/localize'; +import { MessageId } from '../../../../../index'; import { NodePath } from '@babel/core'; import { ParseError } from '@angular/compiler'; import { PathManipulation } from '@angular/compiler-cli/private/localize'; import { PluginObj } from '@babel/core'; import { ReadonlyFileSystem } from '@angular/compiler-cli/private/localize'; import { types } from '@babel/core'; +import { ɵParsedMessage } from '../../../index'; +import { ɵParsedMessage as ɵParsedMessage_2 } from '../../../../index'; +import { ɵParsedTranslation } from '../../index'; +import { ɵParsedTranslation as ɵParsedTranslation_2 } from '../../../../index'; +import { ɵParsedTranslation as ɵParsedTranslation_3 } from '../../../../../index'; +import { ɵSourceLocation } from '../../index'; +import { ɵSourceMessage } from '../../../../../index'; // @public export class ArbTranslationParser implements TranslationParser { @@ -26,14 +34,14 @@ export class ArbTranslationParser implements TranslationParser { export class ArbTranslationSerializer implements TranslationSerializer { constructor(sourceLocale: string, basePath: AbsoluteFsPath, fs: PathManipulation); // (undocumented) - serialize(messages: ParsedMessage[]): string; + serialize(messages: ɵParsedMessage_2[]): string; } // @public export function buildLocalizeReplacement(messageParts: TemplateStringsArray, substitutions: readonly types.Expression[]): types.Expression; // @public -export function checkDuplicateMessages(fs: PathManipulation, messages: ParsedMessage[], duplicateMessageHandling: DiagnosticHandlingStrategy, basePath: AbsoluteFsPath): Diagnostics; +export function checkDuplicateMessages(fs: PathManipulation, messages: ɵParsedMessage[], duplicateMessageHandling: DiagnosticHandlingStrategy, basePath: AbsoluteFsPath): Diagnostics; // @public export type DiagnosticHandlingStrategy = 'error' | 'warning' | 'ignore'; @@ -66,14 +74,14 @@ export function isGlobalIdentifier(identifier: NodePath): bool export class LegacyMessageIdMigrationSerializer implements TranslationSerializer { constructor(_diagnostics: Diagnostics); // (undocumented) - serialize(messages: ParsedMessage[]): string; + serialize(messages: ɵParsedMessage_2[]): string; } // @public -export function makeEs2015TranslatePlugin(diagnostics: Diagnostics, translations: Record, { missingTranslation, localizeName }?: TranslatePluginOptions, fs?: PathManipulation): PluginObj; +export function makeEs2015TranslatePlugin(diagnostics: Diagnostics, translations: Record, { missingTranslation, localizeName }?: TranslatePluginOptions, fs?: PathManipulation): PluginObj; // @public -export function makeEs5TranslatePlugin(diagnostics: Diagnostics, translations: Record, { missingTranslation, localizeName }?: TranslatePluginOptions, fs?: PathManipulation): PluginObj; +export function makeEs5TranslatePlugin(diagnostics: Diagnostics, translations: Record, { missingTranslation, localizeName }?: TranslatePluginOptions, fs?: PathManipulation): PluginObj; // @public export function makeLocalePlugin(locale: string, { localizeName }?: TranslatePluginOptions): PluginObj; @@ -82,7 +90,7 @@ export function makeLocalePlugin(locale: string, { localizeName }?: TranslatePlu export class MessageExtractor { constructor(fs: ReadonlyFileSystem, logger: Logger, { basePath, useSourceMaps, localizeName }: ExtractionOptions); // (undocumented) - extractMessages(filename: string): ParsedMessage[]; + extractMessages(filename: string): ɵParsedMessage[]; } // @public @@ -97,23 +105,23 @@ export class SimpleJsonTranslationParser implements TranslationParser, messageParts: TemplateStringsArray, substitutions: readonly any[], missingTranslation: DiagnosticHandlingStrategy): [TemplateStringsArray, readonly any[]]; +export function translate(diagnostics: Diagnostics, translations: Record, messageParts: TemplateStringsArray, substitutions: readonly any[], missingTranslation: DiagnosticHandlingStrategy): [TemplateStringsArray, readonly any[]]; // @public -export function unwrapExpressionsFromTemplateLiteral(quasi: NodePath, fs?: PathManipulation): [types.Expression[], (SourceLocation | undefined)[]]; +export function unwrapExpressionsFromTemplateLiteral(quasi: NodePath, fs?: PathManipulation): [types.Expression[], (ɵSourceLocation | undefined)[]]; // @public -export function unwrapMessagePartsFromLocalizeCall(call: NodePath, fs?: PathManipulation): [TemplateStringsArray, (SourceLocation | undefined)[]]; +export function unwrapMessagePartsFromLocalizeCall(call: NodePath, fs?: PathManipulation): [TemplateStringsArray, (ɵSourceLocation | undefined)[]]; // @public -export function unwrapMessagePartsFromTemplateLiteral(elements: NodePath[], fs?: PathManipulation): [TemplateStringsArray, (SourceLocation | undefined)[]]; +export function unwrapMessagePartsFromTemplateLiteral(elements: NodePath[], fs?: PathManipulation): [TemplateStringsArray, (ɵSourceLocation | undefined)[]]; // @public -export function unwrapSubstitutionsFromLocalizeCall(call: NodePath, fs?: PathManipulation): [types.Expression[], (SourceLocation | undefined)[]]; +export function unwrapSubstitutionsFromLocalizeCall(call: NodePath, fs?: PathManipulation): [types.Expression[], (ɵSourceLocation | undefined)[]]; // @public export class Xliff1TranslationParser implements TranslationParser { @@ -127,7 +135,7 @@ export class Xliff1TranslationParser implements TranslationParser ({ + return (_angularCoreDts = ['package.json', ...dtsFiles].map((fileName) => ({ name: absoluteFrom(`/node_modules/@angular/core/${fileName}`), contents: readFileSync(path.join(directory, fileName), 'utf8'), }))); diff --git a/packages/compiler-cli/test/compliance/test_helpers/compile_test.ts b/packages/compiler-cli/test/compliance/test_helpers/compile_test.ts index 0df1b42f77a..23d34fc63af 100644 --- a/packages/compiler-cli/test/compliance/test_helpers/compile_test.ts +++ b/packages/compiler-cli/test/compliance/test_helpers/compile_test.ts @@ -132,7 +132,7 @@ function getOptions( target: ts.ScriptTarget.ES2015, newLine: ts.NewLineKind.LineFeed, module: ts.ModuleKind.ES2015, - moduleResolution: ts.ModuleResolutionKind.Node10, + moduleResolution: ts.ModuleResolutionKind.Bundler, typeRoots: ['node_modules/@types'], ...convertedCompilerOptions.options, enableI18nLegacyMessageIdFormat: false, diff --git a/packages/compiler-cli/test/ngtsc/env.ts b/packages/compiler-cli/test/ngtsc/env.ts index 8f8ecffe67a..4c3c7956c51 100644 --- a/packages/compiler-cli/test/ngtsc/env.ts +++ b/packages/compiler-cli/test/ngtsc/env.ts @@ -97,7 +97,7 @@ export class NgtscTestEnvironment { "target": "es2015", "newLine": "lf", "module": "es2015", - "moduleResolution": "node", + "moduleResolution": "bundler", "lib": ["es2015", "dom"], "typeRoots": ["node_modules/@types"] }, diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index c19095150af..d0a91d25190 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -10016,7 +10016,7 @@ runInEachFileSystem((os: string) => { it('should not error when an undecorated class from a declaration file is provided', () => { env.write( - 'node_modules/@angular/core/testing/index.d.ts', + 'node_modules/@angular/core/types/testing.d.ts', ` export declare class Testability { } @@ -10041,7 +10041,7 @@ runInEachFileSystem((os: string) => { it('should not error when an undecorated class without a constructor from a declaration file is provided via useClass', () => { env.write( - 'node_modules/@angular/core/testing/index.d.ts', + 'node_modules/@angular/core/types/testing.d.ts', ` export declare class Testability { } @@ -10097,7 +10097,7 @@ runInEachFileSystem((os: string) => { // can be updated. xit('should error when an undecorated class with a non-trivial constructor in a declaration file is provided via useClass', () => { env.write( - 'node_modules/@angular/core/testing/index.d.ts', + 'node_modules/@angular/core/types/testing.d.ts', ` export declare class NgZone {} @@ -10129,7 +10129,7 @@ runInEachFileSystem((os: string) => { it('should not error when an class with a factory definition and a non-trivial constructor in a declaration file is provided via useClass', () => { env.write( - 'node_modules/@angular/core/testing/index.d.ts', + 'node_modules/@angular/core/types/testing.d.ts', ` import * as i0 from '@angular/core'; diff --git a/packages/language-service/test/definitions_spec.ts b/packages/language-service/test/definitions_spec.ts index 81bb653674f..a47a4c93039 100644 --- a/packages/language-service/test/definitions_spec.ts +++ b/packages/language-service/test/definitions_spec.ts @@ -78,7 +78,7 @@ describe('definitions', () => { ); expect(definitions.length).toEqual(3); assertTextSpans(definitions, ['transform']); - assertFileNames(definitions, ['index.d.ts']); + assertFileNames(definitions, ['fake_common.d.ts']); }); it('gets definitions for all inputs when attribute matches more than one', () => { diff --git a/packages/language-service/test/legacy/project/tsconfig.json b/packages/language-service/test/legacy/project/tsconfig.json index 0bf2016d2ba..36d6c348cf6 100644 --- a/packages/language-service/test/legacy/project/tsconfig.json +++ b/packages/language-service/test/legacy/project/tsconfig.json @@ -20,4 +20,4 @@ "strictTemplates": true, "strictInjectionParameters": true } -} \ No newline at end of file +} diff --git a/packages/language-service/test/references_and_rename_spec.ts b/packages/language-service/test/references_and_rename_spec.ts index 08d91bb11b7..cfd032a4a93 100644 --- a/packages/language-service/test/references_and_rename_spec.ts +++ b/packages/language-service/test/references_and_rename_spec.ts @@ -905,7 +905,7 @@ describe('find references and rename locations', () => { it('should find references', () => { const refs = getReferencesAtPosition(file)!; - assertFileNames(refs, ['index.d.ts', 'prefix-pipe.ts', 'app.ts']); + assertFileNames(refs, ['core.d.ts', 'prefix-pipe.ts', 'app.ts']); assertTextSpans(refs, ['transform', 'prefixPipe']); }); @@ -1830,7 +1830,7 @@ describe('find references and rename locations', () => { const refs = getReferencesAtPosition(file)!; expect(refs.length).toBe(7); assertTextSpans(refs, ['
', 'NgForOf']); - assertFileNames(refs, ['index.d.ts', 'app.ts']); + assertFileNames(refs, ['fake_common.d.ts', 'app.ts']); }); it('should not support rename if directive is in a dts file', () => { diff --git a/packages/language-service/test/type_definitions_spec.ts b/packages/language-service/test/type_definitions_spec.ts index d86bc098ec5..fcad771eb17 100644 --- a/packages/language-service/test/type_definitions_spec.ts +++ b/packages/language-service/test/type_definitions_spec.ts @@ -47,7 +47,7 @@ describe('type definitions', () => { expect(definitions!.length).toEqual(3); assertTextSpans(definitions, ['transform']); - assertFileNames(definitions, ['index.d.ts']); + assertFileNames(definitions, ['fake_common.d.ts']); }); describe('inputs', () => { @@ -80,7 +80,7 @@ describe('type definitions', () => { expect(definitions!.length).toEqual(1); assertTextSpans(definitions, ['InputSignal']); - assertFileNames(definitions, ['index.d.ts']); + assertFileNames(definitions, ['core.d.ts']); }); }); @@ -189,7 +189,7 @@ describe('type definitions', () => { expect(definitions.length).toBe(1); assertTextSpans(definitions, ['ModelSignal']); - assertFileNames(definitions, ['index.d.ts']); + assertFileNames(definitions, ['core.d.ts']); }); it('should return the definition for the event side of a two-way binding', () => { @@ -202,7 +202,7 @@ describe('type definitions', () => { expect(definitions.length).toBe(1); assertTextSpans(definitions, ['ModelSignal']); - assertFileNames(definitions, ['index.d.ts']); + assertFileNames(definitions, ['core.d.ts']); }); it('should return the definition of a two-way binding', () => { @@ -215,7 +215,7 @@ describe('type definitions', () => { expect(definitions.length).toBe(1); assertTextSpans(definitions, ['ModelSignal']); - assertFileNames(definitions, ['index.d.ts']); + assertFileNames(definitions, ['core.d.ts']); }); }); diff --git a/packages/language-service/testing/src/project.ts b/packages/language-service/testing/src/project.ts index 6d9c39ab8ab..6e28ab6e7d4 100644 --- a/packages/language-service/testing/src/project.ts +++ b/packages/language-service/testing/src/project.ts @@ -45,7 +45,7 @@ function writeTsconfig( compilerOptions: { strict: true, experimentalDecorators: true, - moduleResolution: 'node', + moduleResolution: 'bundler', target: 'es2015', rootDir: '.', lib: ['dom', 'es2015'], diff --git a/packages/tsconfig-build.json b/packages/tsconfig-build.json index 766e1838e79..ea0e84bc1e4 100644 --- a/packages/tsconfig-build.json +++ b/packages/tsconfig-build.json @@ -16,7 +16,7 @@ "strict": true, "strictPropertyInitialization": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "module": "esnext", "target": "es2022", "lib": ["es2020", "es2022", "dom", "dom.iterable"], diff --git a/vscode-ng-language-service/integration/project/tsconfig.json b/vscode-ng-language-service/integration/project/tsconfig.json index cfecdf22a23..85ad31d1edf 100644 --- a/vscode-ng-language-service/integration/project/tsconfig.json +++ b/vscode-ng-language-service/integration/project/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "moduleResolution": "node", + "moduleResolution": "bundler", "experimentalDecorators": true, "target": "es2015", "strict": true, diff --git a/vscode-ng-language-service/integration/tsconfig.json b/vscode-ng-language-service/integration/tsconfig.json index cbbad09fd92..615564c3482 100644 --- a/vscode-ng-language-service/integration/tsconfig.json +++ b/vscode-ng-language-service/integration/tsconfig.json @@ -6,4 +6,4 @@ "dist" ] }, -} \ No newline at end of file +} diff --git a/vscode-ng-language-service/integration/workspace/tsconfig.json b/vscode-ng-language-service/integration/workspace/tsconfig.json index a1df478821c..603c2185c3d 100644 --- a/vscode-ng-language-service/integration/workspace/tsconfig.json +++ b/vscode-ng-language-service/integration/workspace/tsconfig.json @@ -12,7 +12,7 @@ "declaration": false, "downlevelIteration": true, "experimentalDecorators": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "importHelpers": true, "target": "es2015", "module": "es2020",