diff --git a/goldens/public-api/compiler-cli/compiler_options.md b/goldens/public-api/compiler-cli/compiler_options.md index ba2aa5cd0fda5..5f8a9f7489a1b 100644 --- a/goldens/public-api/compiler-cli/compiler_options.md +++ b/goldens/public-api/compiler-cli/compiler_options.md @@ -55,6 +55,7 @@ export interface LegacyNgcOptions { export interface MiscOptions { compileNonExportedClasses?: boolean; disableTypeScriptVersionCheck?: boolean; + forbidOrphanComponents?: boolean; } // @public diff --git a/packages/compiler-cli/src/ngtsc/core/api/src/public_options.ts b/packages/compiler-cli/src/ngtsc/core/api/src/public_options.ts index 2eb52e7cf31a3..acf5b3c77ef93 100644 --- a/packages/compiler-cli/src/ngtsc/core/api/src/public_options.ts +++ b/packages/compiler-cli/src/ngtsc/core/api/src/public_options.ts @@ -411,4 +411,13 @@ export interface MiscOptions { * Disable TypeScript Version Check. */ disableTypeScriptVersionCheck?: boolean; + + /** + * Enables the runtime check to guard against rendering a component without first loading its + * NgModule. + * + * This check is only applied to the current compilation unit, i.e., a component imported from + * another library without option set will not issue error if rendered in orphan way. + */ + forbidOrphanComponents?: boolean; } diff --git a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts index 9d6cb002f2a79..65da121d4311d 100644 --- a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts +++ b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts @@ -1085,6 +1085,14 @@ export class NgCompiler { 'JIT mode support ("supportJitMode" option) cannot be disabled in partial compilation mode.'); } + // Currently forbidOrphanComponents depends on the code generated behind ngJitMode flag. Until + // we come up with a better design for these flags, it is necessary to have the JIT mode in + // order for forbidOrphanComponents to be able to work properly. + if (supportJitMode === false && this.options.forbidOrphanComponents) { + throw new Error( + 'JIT mode support ("supportJitMode" option) cannot be disabled when forbidOrphanComponents is set to true'); + } + // Set up the IvyCompilation, which manages state for the Ivy transformer. const handlers: DecoratorHandler[] = [ new ComponentDecoratorHandler( diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 595fea60b935a..135d50e72f152 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -537,6 +537,21 @@ function allTests(os: string) { 'never, never, never>'); }); + it('should error when supportJitMode is false and forbidOrphanComponents is true', () => { + env.tsconfig({ + supportJitMode: false, + forbidOrphanComponents: true, + }); + env.write('test.ts', ''); + + const diagnostics = env.driveDiagnostics(); + + expect(diagnostics).toEqual([jasmine.objectContaining({ + messageText: jasmine.stringMatching( + /JIT mode support \("supportJitMode" option\) cannot be disabled when forbidOrphanComponents is set to true/), + })]); + }); + // This test triggers the Tsickle compiler which asserts that the file-paths // are valid for the real OS. When on non-Windows systems it doesn't like paths // that start with `C:`.