1- import { BuildOptions , build } from "esbuild" ;
1+ import { BuildOptions , build , type Metafile } from "esbuild" ;
22import { sassPlugin } from "esbuild-sass-plugin" ;
33import * as fs from "node:fs/promises" ;
44
55let minify = true ;
6+ let metafile = true ;
67process . argv . forEach ( ( val , index ) => {
78 if ( val === "--minify=false" ) {
89 console . log ( "Disabling minification" ) ;
910 minify = false ;
1011 }
12+ if ( val === "--metafile=false" ) {
13+ console . log ( "Disabling metafile generation" ) ;
14+ metafile = false ;
15+ }
1116} ) ;
1217
1318const outDir = "../shiny/www/py-shiny" ;
1419
20+ const allEsbuildMetadata : Array < Metafile > = [ ] ;
21+
22+ function mergeMetadatas ( metadatas : Array < Metafile > ) : Metafile {
23+ // Merge all the metafile objects together
24+ const mergedMetadata : Metafile = {
25+ inputs : { } ,
26+ outputs : { } ,
27+ } ;
28+
29+ metadatas . forEach ( ( metafile ) => {
30+ Object . entries ( metafile . inputs ) . forEach ( ( [ key , value ] ) => {
31+ if (
32+ mergedMetadata . inputs [ key ] &&
33+ JSON . stringify ( mergedMetadata . inputs [ key ] ) !== JSON . stringify ( value )
34+ ) {
35+ // It's very possible for multiple MetaFile objects to refer to the same input.
36+ // But if that input has different values in the different Metafile objects,
37+ // that could cause inaccuracies when we merge them. I think it's possible they
38+ // could have different values if tree-shaking is enabled -- this will detect
39+ // those cases and warn the user, and if it happens we can figure out how to
40+ // handle it.
41+ console . error (
42+ `Different values found for key in metadata: ${ key } . Overwriting.`
43+ ) ;
44+ }
45+ mergedMetadata . inputs [ key ] = value ;
46+ } ) ;
47+ Object . entries ( metafile . outputs ) . forEach ( ( [ key , value ] ) => {
48+ if ( mergedMetadata . outputs [ key ] ) {
49+ console . error ( `Duplicate key found in metadata: ${ key } . Overwriting.` ) ;
50+ }
51+ mergedMetadata . outputs [ key ] = value ;
52+ } ) ;
53+ } ) ;
54+
55+ return mergedMetadata ;
56+ }
1557async function bundle_helper (
1658 options : BuildOptions
1759) : Promise < ReturnType < typeof build > | undefined > {
@@ -20,8 +62,10 @@ async function bundle_helper(
2062 format : "esm" ,
2163 bundle : true ,
2264 minify : minify ,
23- sourcemap : true ,
24- metafile : false ,
65+ // No need to clean up old source maps, as `minify==false` only during `npm run watch-fast`
66+ // GHA will run `npm run build` which will minify
67+ sourcemap : minify ,
68+ metafile : metafile ,
2569 outdir : outDir ,
2670 ...options ,
2771 } ) ;
@@ -34,15 +78,10 @@ async function bundle_helper(
3478 }
3579 ) ;
3680
37- if ( options . metafile ) {
38- // Save metafile
39- const data_frame_results = result ;
40- await fs . writeFile (
41- "esbuild-metadata.json" ,
42- JSON . stringify ( data_frame_results . metafile )
43- ) ;
44- console . log ( "Metadata file written to esbuild-metadata.json" ) ;
81+ if ( result . metafile ) {
82+ allEsbuildMetadata . push ( result . metafile ) ;
4583 }
84+
4685 return result ;
4786 } catch ( error ) {
4887 console . error ( "Build failed:" , error ) ;
@@ -53,57 +92,49 @@ const opts: Array<BuildOptions> = [
5392 {
5493 entryPoints : { "data-frame/data-frame" : "data-frame/index.tsx" } ,
5594 plugins : [ sassPlugin ( { type : "css-text" , sourceMap : false } ) ] ,
56- metafile : true ,
5795 } ,
5896 {
5997 entryPoints : {
6098 "text-area/textarea-autoresize" : "text-area/textarea-autoresize.ts" ,
6199 } ,
62- minify : false ,
63- sourcemap : false ,
64100 } ,
65101 {
66102 entryPoints : {
67103 "page-output/page-output" : "page-output/page-output.ts" ,
68104 } ,
69- minify : false ,
70- sourcemap : false ,
71105 } ,
72106 {
73107 entryPoints : { "spin/spin" : "spin/spin.scss" } ,
74108 plugins : [ sassPlugin ( { type : "css" , sourceMap : false } ) ] ,
75- metafile : true ,
76109 } ,
77110 {
78111 entryPoints : {
79112 "markdown-stream/markdown-stream" : "markdown-stream/markdown-stream.ts" ,
80113 } ,
81- minify : true ,
82- sourcemap : true ,
83114 } ,
84115 {
85116 entryPoints : {
86117 "markdown-stream/markdown-stream" : "markdown-stream/markdown-stream.scss" ,
87118 } ,
88119 plugins : [ sassPlugin ( { type : "css" , sourceMap : false } ) ] ,
89- metafile : true ,
90120 } ,
91121 {
92122 entryPoints : {
93123 "chat/chat" : "chat/chat.ts" ,
94124 } ,
95- minify : true ,
96- sourcemap : true ,
97125 } ,
98126 {
99127 entryPoints : { "chat/chat" : "chat/chat.scss" } ,
100128 plugins : [ sassPlugin ( { type : "css" , sourceMap : false } ) ] ,
101- metafile : true ,
102129 } ,
103130] ;
104131
105- // Run function to avoid top level await
106- async function main ( ) : Promise < void > {
132+ ( async ( ) => {
107133 await Promise . all ( opts . map ( bundle_helper ) ) ;
108- }
109- main ( ) ;
134+
135+ if ( metafile ) {
136+ const mergedMetadata = mergeMetadatas ( allEsbuildMetadata ) ;
137+ await fs . writeFile ( "esbuild-metadata.json" , JSON . stringify ( mergedMetadata ) ) ;
138+ console . log ( "Metadata file written to esbuild-metadata.json" ) ;
139+ }
140+ } ) ( ) ;
0 commit comments