@@ -74,47 +74,63 @@ const visitors: Visitors = {
7474 return ;
7575 }
7676 const source = path . node ! . source ! ;
77- // 1. insert `import { load as __load } from '${loader}'` at top of program
78- importManager . add ( { load : '__load' } , loader ) ;
79- // 2. replace this import with `__load(${source})`
80- path . replaceWith ( b . callExpression ( b . identifier ( '__load' ) , [ structuredClone ( source ) ] ) ) ;
77+ // 1. insert `import { load as __lwcLoad } from '${loader}'` at top of program
78+ importManager . add ( { load : '__lwcLoad' } , loader ) ;
79+ // 2. replace this `import(source)` with `__lwcLoad(source)`
80+ const load = b . identifier ( '__lwcLoad' ) ;
81+ state . trustedLwcIdentifiers . add ( load ) ;
82+ path . replaceWith ( b . callExpression ( load , [ structuredClone ( source ) ] ) ) ;
8183 } ,
82- ClassDeclaration ( path , state ) {
83- const { node } = path ;
84- if (
85- node ?. superClass &&
86- // export default class extends LightningElement {}
87- ( is . exportDefaultDeclaration ( path . parentPath ) ||
88- // class Cmp extends LightningElement {}; export default Cmp
89- path . scope
90- ?. getBinding ( node . id . name )
91- ?. references . some ( ( ref ) => is . exportDefaultDeclaration ( ref . parent ) ) )
92- ) {
93- // If it's a default-exported class with a superclass, then it's an LWC component!
94- state . isLWC = true ;
95- if ( node . id ) {
96- state . lwcClassName = node . id . name ;
97- } else {
98- node . id = b . identifier ( 'DefaultComponentName' ) ;
99- state . lwcClassName = 'DefaultComponentName' ;
100- }
84+ ClassDeclaration : {
85+ enter ( path , state ) {
86+ const { node } = path ;
87+ if (
88+ node ?. superClass &&
89+ // export default class extends LightningElement {}
90+ ( is . exportDefaultDeclaration ( path . parentPath ) ||
91+ // class Cmp extends LightningElement {}; export default Cmp
92+ path . scope
93+ ?. getBinding ( node . id . name )
94+ ?. references . some ( ( ref ) => is . exportDefaultDeclaration ( ref . parent ) ) )
95+ ) {
96+ // If it's a default-exported class with a superclass, then it's an LWC component!
97+ state . isLWC = true ;
98+ state . currentComponent = node ;
99+ if ( node . id ) {
100+ state . lwcClassName = node . id . name ;
101+ } else {
102+ node . id = b . identifier ( 'DefaultComponentName' ) ;
103+ state . lwcClassName = 'DefaultComponentName' ;
104+ }
101105
102- // There's no builder for comment nodes :\
103- const lwcVersionComment : EsComment = {
104- type : 'Block' ,
105- value : LWC_VERSION_COMMENT ,
106- } ;
106+ // There's no builder for comment nodes :\
107+ const lwcVersionComment : EsComment = {
108+ type : 'Block' ,
109+ value : LWC_VERSION_COMMENT ,
110+ } ;
107111
108- // Add LWC version comment to end of class body
109- const { body } = node ;
110- if ( body . trailingComments ) {
111- body . trailingComments . push ( lwcVersionComment ) ;
112- } else {
113- body . trailingComments = [ lwcVersionComment ] ;
112+ // Add LWC version comment to end of class body
113+ const { body } = node ;
114+ if ( body . trailingComments ) {
115+ body . trailingComments . push ( lwcVersionComment ) ;
116+ } else {
117+ body . trailingComments = [ lwcVersionComment ] ;
118+ }
114119 }
115- }
120+ } ,
121+ leave ( path , state ) {
122+ // Indicate that we're no longer traversing an LWC component
123+ if ( state . currentComponent && path . node === state . currentComponent ) {
124+ state . currentComponent = null ;
125+ }
126+ } ,
116127 } ,
117128 PropertyDefinition ( path , state ) {
129+ // Don't do anything unless we're in a component
130+ if ( ! state . currentComponent ) {
131+ return ;
132+ }
133+
118134 const node = path . node ;
119135 if ( ! node ?. key ) {
120136 // Seems to occur for `@wire() [symbol];` -- not sure why
@@ -155,7 +171,7 @@ const visitors: Visitors = {
155171 }
156172 // If we mutate any class-methods that are piped through this compiler, then we'll be
157173 // inadvertently mutating things like Wire adapters.
158- if ( ! state . isLWC ) {
174+ if ( ! state . currentComponent ) {
159175 return ;
160176 }
161177
@@ -218,7 +234,7 @@ const visitors: Visitors = {
218234 Super ( path , state ) {
219235 // If we mutate any super calls that are piped through this compiler, then we'll be
220236 // inadvertently mutating things like Wire adapters.
221- if ( ! state . isLWC ) {
237+ if ( ! state . currentComponent ) {
222238 return ;
223239 }
224240
@@ -246,9 +262,9 @@ const visitors: Visitors = {
246262 }
247263 } ,
248264 } ,
249- Identifier ( path , _state ) {
265+ Identifier ( path , state ) {
250266 const { node } = path ;
251- if ( node ?. name . startsWith ( '__lwc' ) ) {
267+ if ( node ?. name . startsWith ( '__lwc' ) && ! state . trustedLwcIdentifiers . has ( node ) ) {
252268 throw generateError ( node , SsrCompilerErrors . RESERVED_IDENTIFIER_PREFIX ) ;
253269 }
254270 } ,
@@ -271,6 +287,7 @@ export default function compileJS(
271287
272288 const state : ComponentMetaState = {
273289 isLWC : false ,
290+ currentComponent : null ,
274291 hasConstructor : false ,
275292 hasConnectedCallback : false ,
276293 hadRenderedCallback : false ,
@@ -286,6 +303,7 @@ export default function compileJS(
286303 wireAdapters : [ ] ,
287304 experimentalDynamicComponent : options . experimentalDynamicComponent ,
288305 importManager : new ImportManager ( ) ,
306+ trustedLwcIdentifiers : new WeakSet ( ) ,
289307 } ;
290308
291309 traverse ( ast , visitors , state ) ;
0 commit comments