@@ -177,20 +177,6 @@ export interface PluginOptions {
177177 experimental ?: {
178178 useAngularCompilationAPI ?: boolean ;
179179 useAnalogCompiler ?: boolean ;
180- /**
181- * Controls Angular's experimental selectorless compilation mode.
182- *
183- * Defaults to `true` only when Angular 20+ applications use file-based
184- * pages or route entry points that rely on selectorless compilation.
185- * That auto mode is preserved for backwards compatibility with existing
186- * Analog route files that intentionally omit `selector`.
187- * Angular treats this as a compiler-wide mode, so once enabled it applies
188- * to the whole program, including workspace libraries pulled in through
189- * `include` globs or tsconfig references.
190- * Set this explicitly to pin behavior when route discovery would otherwise
191- * auto-enable selectorless for a larger app graph than intended.
192- */
193- enableSelectorless ?: boolean ;
194180 /**
195181 * Compilation output mode for the Analog compiler.
196182 * - `'full'` (default): Emit final Ivy definitions for application builds.
@@ -317,55 +303,6 @@ export function normalizeIncludeGlob(
317303 return normalizePath ( resolve ( normalizedWorkspaceRoot , normalizedGlob ) ) ;
318304}
319305
320- function isSelectorlessRouteFile ( file : string ) : boolean {
321- const normalized = normalizePath ( file ) ;
322- return (
323- normalized . endsWith ( '.page.ts' ) ||
324- normalized . includes ( '/src/app/routes/' ) ||
325- normalized . includes ( '/app/routes/' )
326- ) ;
327- }
328-
329- /**
330- * Infer selectorless support from route/page entry points.
331- *
332- * This heuristic is intentionally broad because file-based routing commonly
333- * relies on selectorless components. The resulting Angular compiler flag is
334- * program-wide, not route-scoped, so a matching route-like include can affect
335- * every file in the current Angular program.
336- */
337- function detectSelectorlessRouteUsage (
338- root : string ,
339- workspaceRoot : string ,
340- includeGlobs : string [ ] ,
341- ) : { enabled : boolean ; routeFileCount : number } {
342- const normalizedRoot = normalizePath ( resolve ( root ) ) ;
343- const normalizedWorkspaceRoot = normalizePath ( resolve ( workspaceRoot ) ) ;
344- const appRouteGlobs = [
345- `${ normalizedRoot } /src/app/pages/**/*.page.ts` ,
346- `${ normalizedRoot } /src/app/routes/**/*.ts` ,
347- `${ normalizedRoot } /app/routes/**/*.ts` ,
348- ] ;
349- const routeLikeIncludeGlobs = includeGlobs
350- . map ( ( glob ) => normalizeIncludeGlob ( normalizedWorkspaceRoot , glob ) )
351- . filter (
352- ( glob ) =>
353- glob . includes ( '.page.' ) ||
354- glob . includes ( '/pages/' ) ||
355- glob . includes ( '/app/routes/' ) ||
356- glob . includes ( '/src/app/routes/' ) ,
357- ) ;
358- const routeFiles = globSync ( [ ...appRouteGlobs , ...routeLikeIncludeGlobs ] , {
359- absolute : true ,
360- dot : true ,
361- onlyFiles : true ,
362- } ) . filter ( isSelectorlessRouteFile ) ;
363-
364- return {
365- enabled : routeFiles . length > 0 ,
366- routeFileCount : routeFiles . length ,
367- } ;
368- }
369306const classNames = new Map ( ) ;
370307export function evictDeletedFileMetadata (
371308 file : string ,
@@ -508,7 +445,6 @@ export function buildStylePreprocessor(
508445export function angular ( options ?: PluginOptions ) : Plugin [ ] {
509446 applyDebugOption ( options ?. debug , options ?. workspaceRoot ) ;
510447 const liveReload = options ?. liveReload ?? true ;
511- const explicitEnableSelectorless = options ?. experimental ?. enableSelectorless ;
512448
513449 /**
514450 * Normalize plugin options so defaults
@@ -535,7 +471,6 @@ export function angular(options?: PluginOptions): Plugin[] {
535471 fileReplacements : options ?. fileReplacements ?? [ ] ,
536472 useAngularCompilationAPI :
537473 options ?. experimental ?. useAngularCompilationAPI ?? false ,
538- enableSelectorless : explicitEnableSelectorless ,
539474 hasTailwindCss : ! ! options ?. tailwindCss ,
540475 tailwindCss : options ?. tailwindCss ,
541476 stylePreprocessor : buildStylePreprocessor ( options ) ,
@@ -1080,34 +1015,6 @@ export function angular(options?: PluginOptions): Plugin[] {
10801015 configResolved ( config ) {
10811016 resolvedConfig = config ;
10821017
1083- if ( typeof pluginOptions . enableSelectorless === 'undefined' ) {
1084- // Preserve the explicit option as the authoritative value. The route
1085- // scan is only a default because Angular applies selectorless to the
1086- // whole program once the compiler option is enabled. We still keep
1087- // the heuristic default for compatibility with checked-in Analog apps
1088- // and tests that use selectorless route components without an
1089- // explicit flag.
1090- const selectorlessRouteUsage = detectSelectorlessRouteUsage (
1091- config . root ,
1092- pluginOptions . workspaceRoot ,
1093- pluginOptions . include ,
1094- ) ;
1095- pluginOptions . enableSelectorless =
1096- angularFullVersion >= 200000 && selectorlessRouteUsage . enabled ;
1097- debugCompilationApi ( 'selectorless default resolved' , {
1098- angularVersion : angularFullVersion ,
1099- root : config . root ,
1100- routeFileCount : selectorlessRouteUsage . routeFileCount ,
1101- selectorlessEnabled : pluginOptions . enableSelectorless ,
1102- } ) ;
1103- } else {
1104- debugCompilationApi ( 'selectorless resolved from explicit option' , {
1105- angularVersion : angularFullVersion ,
1106- root : config . root ,
1107- selectorlessEnabled : pluginOptions . enableSelectorless ,
1108- } ) ;
1109- }
1110-
11111018 if ( pluginOptions . hasTailwindCss ) {
11121019 validateTailwindConfig ( config , watchMode ) ;
11131020 }
@@ -2890,7 +2797,6 @@ export function angular(options?: PluginOptions): Plugin[] {
28902797 shouldExternalize : shouldExternalizeStyles ( ) ,
28912798 externalRuntimeStyles : ! ! tsCompilerOptions [ 'externalRuntimeStyles' ] ,
28922799 hmrEnabled : ! ! tsCompilerOptions [ '_enableHmr' ] ,
2893- selectorlessEnabled : pluginOptions . enableSelectorless ,
28942800 } ) ;
28952801
28962802 if ( tsCompilerOptions . compilationMode === 'partial' ) {
@@ -2899,13 +2805,6 @@ export function angular(options?: PluginOptions): Plugin[] {
28992805 tsCompilerOptions [ 'supportJitMode' ] = true ;
29002806 }
29012807
2902- if ( pluginOptions . enableSelectorless ) {
2903- // Angular reads selectorless as a compiler-wide mode rather than a
2904- // per-route transform, so keep this mutation in sync with every
2905- // compilation path that feeds Angular compiler options.
2906- tsCompilerOptions [ '_enableSelectorless' ] = true ;
2907- }
2908-
29092808 if ( ! isTest && config . build ?. lib ) {
29102809 tsCompilerOptions [ 'declaration' ] = true ;
29112810 tsCompilerOptions [ 'declarationMap' ] = watchMode ;
@@ -3193,7 +3092,6 @@ export function angular(options?: PluginOptions): Plugin[] {
31933092 shouldExternalize : shouldExternalizeStyles ( ) ,
31943093 externalRuntimeStyles : ! ! tsCompilerOptions [ 'externalRuntimeStyles' ] ,
31953094 hmrEnabled : ! ! tsCompilerOptions [ '_enableHmr' ] ,
3196- selectorlessEnabled : pluginOptions . enableSelectorless ,
31973095 } ) ;
31983096
31993097 if ( tsCompilerOptions [ 'compilationMode' ] === 'partial' ) {
@@ -3202,12 +3100,6 @@ export function angular(options?: PluginOptions): Plugin[] {
32023100 tsCompilerOptions [ 'supportJitMode' ] = true ;
32033101 }
32043102
3205- if ( pluginOptions . enableSelectorless ) {
3206- // Keep the legacy NgtscProgram path aligned with the Compilation API
3207- // path above. Selectorless is still compiler-wide here.
3208- tsCompilerOptions [ '_enableSelectorless' ] = true ;
3209- }
3210-
32113103 if ( ! isTest && config . build ?. lib ) {
32123104 tsCompilerOptions [ 'declaration' ] = true ;
32133105 tsCompilerOptions [ 'declarationMap' ] = watchMode ;
0 commit comments