@@ -22,11 +22,7 @@ interface ControllersJson {
2222/** The virtual module the runtime helper imports; provided by each bundler adapter. */
2323export const VIRTUAL_CONTROLLERS_ID = 'virtual:symfony/controllers' ;
2424
25- /**
26- * Shown when `virtual:symfony/controllers` is imported (typically via `startStimulusApp()`)
27- * while the `stimulus` option is unset — instead of the bundler's cryptic
28- * "failed to resolve" / "Unhandled scheme" error.
29- */
25+ /** Shown when the virtual module is imported while the `stimulus` option is unset. */
3026export const STIMULUS_NOT_ENABLED_MESSAGE =
3127 `[@symfony/reprise] "${ VIRTUAL_CONTROLLERS_ID } " was imported (this is what startStimulusApp() ` +
3228 `from "@symfony/reprise/stimulus" pulls in), but the Stimulus integration is not enabled. ` +
@@ -42,29 +38,18 @@ interface ResolvedController {
4238 autoimports : string [ ] ;
4339}
4440
45- // A controller opts into lazy loading with a `stimulusFetch: 'lazy'` comment placed *directly
46- // above the class declaration* — after the imports, like a decorator:
47- //
48- // import { Controller } from '@hotwired/stimulus'
41+ // A controller opts into lazy loading with a `stimulusFetch: 'lazy'` comment directly above the
42+ // class (line/block comment, either quotes, `/*!...*/` survives minification) — recognised only
43+ // when the class is the very next code, so a stray marker elsewhere doesn't count:
4944//
5045// /* stimulusFetch: 'lazy' */
5146// export default class extends Controller {}
52- //
53- // The marker is recognised only when the very next code is the class (`[export [default]] class`),
54- // which is why a stray `stimulusFetch: 'lazy'` sitting above the imports (or anywhere else) does
55- // NOT flip the controller to lazy. It may be a block comment or a single-line one, single or
56- // double quotes; a block comment may sit on the class's own line, a line comment must precede it.
57- // A preserved block comment (`/*! ... */`, the form tsc/esbuild keep so the marker survives
58- // minification) is recognised too.
5947const LAZY_COMMENT_RE =
6048 / (?: \/ \* ! ? \s * s t i m u l u s F e t c h : \s * [ ' " ] l a z y [ ' " ] \s * \* \/ | \/ \/ \s * s t i m u l u s F e t c h : \s * [ ' " ] l a z y [ ' " ] ) \s * (?: e x p o r t \s + (?: d e f a u l t \s + ) ? ) ? (?: a b s t r a c t \s + ) ? c l a s s \b / i;
6149const LOCAL_CONTROLLER_RE = / [ - _ ] c o n t r o l l e r \. [ j t ] s $ / ;
6250
6351export function generateControllersModule ( opts : ResolvedStimulusOptions , root : string , isDev : boolean ) : string {
64- // Collect controllers keyed by identifier. Third-party controllers are added first, local
65- // ones second, so a local controller sharing an identifier with a third-party one overrides
66- // it (last write wins) and each identifier ends up in exactly one of the two maps — never
67- // emitted twice, never registered twice.
52+ // Keyed by identifier; local added after third-party so a local override wins (last write wins).
6853 const controllers = new Map < string , ResolvedController > ( ) ;
6954
7055 const require = createRequire ( path . join ( root , 'noop.js' ) ) ;
@@ -108,8 +93,7 @@ export function generateControllersModule(opts: ResolvedStimulusOptions, root: s
10893 controllers . set ( identifier , {
10994 identifier,
11095 fetch : LAZY_COMMENT_RE . test ( readFileSync ( abs , 'utf8' ) ) ? 'lazy' : 'eager' ,
111- // Emit a forward-slash path: a valid ESM import specifier on every OS (a Windows
112- // backslash path would be escaped in the generated string and is not a portable specifier).
96+ // Forward slashes: a portable ESM specifier (a Windows backslash path isn't).
11397 main : abs . replace ( / \\ / g, '/' ) ,
11498 autoimports : [ ] ,
11599 } ) ;
@@ -179,8 +163,7 @@ function listLocalControllers(dir: string): string[] {
179163 entries
180164 . map ( ( e ) => String ( e ) . replace ( / \\ / g, '/' ) )
181165 . filter ( ( e ) => LOCAL_CONTROLLER_RE . test ( e ) )
182- // Sort so the generated module -- and therefore its content hash -- stays stable
183- // regardless of the filesystem's iteration order. See symfony/ux#3703.
166+ // Sort so the module (and its content hash) is stable across FS order. See symfony/ux#3703.
184167 . sort ( )
185168 ) ;
186169}
0 commit comments