@@ -166,6 +166,7 @@ function stringifyExports(
166166 unusedCompositionRegex : RegExp | null ,
167167 key : string ,
168168 exportLookup : Map < any , string > ,
169+ exportDependencyGraph : DependencyGraph ,
169170) : any {
170171 return stringify (
171172 value ,
@@ -185,6 +186,7 @@ function stringifyExports(
185186 const reusedExport = exportLookup . get ( value ) ;
186187
187188 if ( reusedExport && reusedExport !== key ) {
189+ exportDependencyGraph . addDependency ( key , reusedExport ) ;
188190 return reusedExport ;
189191 }
190192 return next ( value ) ;
@@ -236,6 +238,7 @@ function stringifyExports(
236238 unusedCompositionRegex ,
237239 key ,
238240 exportLookup ,
241+ exportDependencyGraph ,
239242 ) ,
240243 )
241244 . join ( ',' ) } )`;
@@ -263,6 +266,48 @@ function stringifyExports(
263266
264267const defaultExportName = '__default__' ;
265268
269+ class DependencyGraph {
270+ graph : Map < string , Set < string > > ;
271+
272+ public constructor ( ) {
273+ this . graph = new Map ( ) ;
274+ }
275+
276+ /**
277+ * Creates a "depends on" relationship between `key` and `dependency`
278+ */
279+ public addDependency ( key : string , dependency : string ) {
280+ const dependencies = this . graph . get ( key ) ;
281+
282+ if ( dependencies ) {
283+ dependencies . add ( dependency ) ;
284+ } else {
285+ this . graph . set ( key , new Set ( [ dependency ] ) ) ;
286+ }
287+ }
288+
289+ /**
290+ * Whether or not `key` depends on `dependency`
291+ */
292+ public dependsOn ( key : string , dependency : string ) : boolean {
293+ const dependencies = this . graph . get ( key ) ;
294+
295+ if ( dependencies ) {
296+ if ( dependencies ?. has ( dependency ) ) {
297+ return true ;
298+ }
299+
300+ for ( const [ dep ] of dependencies . entries ( ) ) {
301+ if ( this . dependsOn ( dep , dependency ) ) {
302+ return true ;
303+ }
304+ }
305+ }
306+
307+ return false ;
308+ }
309+ }
310+
266311export function serializeVanillaModule (
267312 cssImports : Array < string > ,
268313 exports : Record < string , unknown > ,
@@ -276,29 +321,49 @@ export function serializeVanillaModule(
276321 ] ) ,
277322 ) ;
278323
279- const moduleExports = Object . keys ( exports ) . map ( ( key ) => {
324+ const exportDependencyGraph = new DependencyGraph ( ) ;
325+
326+ const moduleExports = Object . entries ( exports ) . map ( ( [ key , value ] ) => {
280327 const serializedExport = stringifyExports (
281328 functionSerializationImports ,
282- exports [ key ] ,
329+ value ,
283330 unusedCompositionRegex ,
284331 key === 'default' ? defaultExportName : key ,
285332 exportLookup ,
333+ exportDependencyGraph ,
286334 ) ;
287335
288336 if ( key === 'default' ) {
289337 return [
290- `var ${ defaultExportName } = ${ serializedExport } ;` ,
291- `export default ${ defaultExportName } ;` ,
292- ] . join ( '\n' ) ;
338+ defaultExportName ,
339+ [
340+ `var ${ defaultExportName } = ${ serializedExport } ;` ,
341+ `export default ${ defaultExportName } ;` ,
342+ ] . join ( '\n' ) ,
343+ ] ;
293344 }
294345
295- return `export var ${ key } = ${ serializedExport } ;` ;
346+ return [ key , `export var ${ key } = ${ serializedExport } ;` ] ;
296347 } ) ;
297348
349+ const sortedModuleExports = moduleExports
350+ . sort ( ( [ key1 ] , [ key2 ] ) => {
351+ if ( exportDependencyGraph . dependsOn ( key1 , key2 ) ) {
352+ return 1 ;
353+ }
354+
355+ if ( exportDependencyGraph . dependsOn ( key2 , key1 ) ) {
356+ return - 1 ;
357+ }
358+
359+ return 0 ;
360+ } )
361+ . map ( ( [ , s ] ) => s ) ;
362+
298363 const outputCode = [
299364 ...cssImports ,
300365 ...functionSerializationImports ,
301- ...moduleExports ,
366+ ...sortedModuleExports ,
302367 ] ;
303368
304369 return outputCode . join ( '\n' ) ;
0 commit comments