1
- import { BuildOptions , build } from "esbuild" ;
1
+ import { BuildOptions , build , type Metafile } from "esbuild" ;
2
2
import { sassPlugin } from "esbuild-sass-plugin" ;
3
3
import * as fs from "node:fs/promises" ;
4
4
5
5
let minify = true ;
6
+ let metafile = true ;
6
7
process . argv . forEach ( ( val , index ) => {
7
8
if ( val === "--minify=false" ) {
8
9
console . log ( "Disabling minification" ) ;
9
10
minify = false ;
10
11
}
12
+ if ( val === "--metafile=false" ) {
13
+ console . log ( "Disabling metafile generation" ) ;
14
+ metafile = false ;
15
+ }
11
16
} ) ;
12
17
13
18
const outDir = "../shiny/www/py-shiny" ;
14
19
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
+ }
15
57
async function bundle_helper (
16
58
options : BuildOptions
17
59
) : Promise < ReturnType < typeof build > | undefined > {
@@ -20,8 +62,10 @@ async function bundle_helper(
20
62
format : "esm" ,
21
63
bundle : true ,
22
64
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 ,
25
69
outdir : outDir ,
26
70
...options ,
27
71
} ) ;
@@ -34,15 +78,10 @@ async function bundle_helper(
34
78
}
35
79
) ;
36
80
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 ) ;
45
83
}
84
+
46
85
return result ;
47
86
} catch ( error ) {
48
87
console . error ( "Build failed:" , error ) ;
@@ -53,57 +92,49 @@ const opts: Array<BuildOptions> = [
53
92
{
54
93
entryPoints : { "data-frame/data-frame" : "data-frame/index.tsx" } ,
55
94
plugins : [ sassPlugin ( { type : "css-text" , sourceMap : false } ) ] ,
56
- metafile : true ,
57
95
} ,
58
96
{
59
97
entryPoints : {
60
98
"text-area/textarea-autoresize" : "text-area/textarea-autoresize.ts" ,
61
99
} ,
62
- minify : false ,
63
- sourcemap : false ,
64
100
} ,
65
101
{
66
102
entryPoints : {
67
103
"page-output/page-output" : "page-output/page-output.ts" ,
68
104
} ,
69
- minify : false ,
70
- sourcemap : false ,
71
105
} ,
72
106
{
73
107
entryPoints : { "spin/spin" : "spin/spin.scss" } ,
74
108
plugins : [ sassPlugin ( { type : "css" , sourceMap : false } ) ] ,
75
- metafile : true ,
76
109
} ,
77
110
{
78
111
entryPoints : {
79
112
"markdown-stream/markdown-stream" : "markdown-stream/markdown-stream.ts" ,
80
113
} ,
81
- minify : true ,
82
- sourcemap : true ,
83
114
} ,
84
115
{
85
116
entryPoints : {
86
117
"markdown-stream/markdown-stream" : "markdown-stream/markdown-stream.scss" ,
87
118
} ,
88
119
plugins : [ sassPlugin ( { type : "css" , sourceMap : false } ) ] ,
89
- metafile : true ,
90
120
} ,
91
121
{
92
122
entryPoints : {
93
123
"chat/chat" : "chat/chat.ts" ,
94
124
} ,
95
- minify : true ,
96
- sourcemap : true ,
97
125
} ,
98
126
{
99
127
entryPoints : { "chat/chat" : "chat/chat.scss" } ,
100
128
plugins : [ sassPlugin ( { type : "css" , sourceMap : false } ) ] ,
101
- metafile : true ,
102
129
} ,
103
130
] ;
104
131
105
- // Run function to avoid top level await
106
- async function main ( ) : Promise < void > {
132
+ ( async ( ) => {
107
133
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