11import { watch } from "node:fs" ;
2+ import { copyFile } from "node:fs/promises" ;
3+ import { join } from "node:path" ;
24import chalk from "chalk" ;
5+ import { BuildConfig } from "bun" ;
36
4- const runBuild = async ( ) => {
5- const result = await Bun . build ( {
6- entrypoints : [ "./src/cli/index.ts" ] ,
7- outdir : "./dist/cli" ,
7+ const runBuild = async ( config : BuildConfig ) => {
8+ const defaultBuildOptions : Partial < BuildConfig > = {
89 target : "node" ,
910 format : "esm" ,
1011 sourcemap : "external" ,
12+ external : [
13+ // Optional deps of Ink. Needed for Dev mode only, which we don't support.
14+ "react-devtools-core"
15+ ] ,
16+ plugins : [ {
17+ name : 'exclude-devtools' ,
18+ setup ( build ) {
19+ build . onResolve ( { filter : / ^ r e a c t - d e v t o o l s - c o r e $ / } , ( ) => ( {
20+ path : 'react-devtools-core' ,
21+ namespace : 'empty-module' ,
22+ } ) ) ;
23+ build . onLoad ( { filter : / .* / , namespace : 'empty-module' } , ( ) => ( {
24+ contents : 'module.exports = {};' ,
25+ loader : 'js' ,
26+ } ) ) ;
27+ } ,
28+ } ] ,
29+ } ;
30+
31+ const result = await Bun . build ( {
32+ ...defaultBuildOptions ,
33+ ...config ,
1134 } ) ;
1235
1336 if ( ! result . success ) {
@@ -21,36 +44,69 @@ const runBuild = async () => {
2144 return result ;
2245} ;
2346
47+ const runAllBuilds = async ( ) => {
48+ const outdir = "./dist/cli" ;
49+ const cli = await runBuild ( {
50+ entrypoints : [ "./src/cli/index.ts" ] ,
51+ outdir,
52+ } ) ;
53+ /**
54+ * This is a dep of Ink. This package imports the wasm file via (fs.readFile).
55+ * We need to copy it to the build folder, so it will be available at runtime
56+ * after the build. 'esbuild' doesn't handle this automatically.
57+ */
58+ await copyFile (
59+ Bun . resolveSync ( "yoga-wasm-web/dist/yoga.wasm" , process . cwd ( ) ) ,
60+ join ( outdir , "yoga.wasm" ) ,
61+ ) ;
62+ const denoRuntime = await runBuild ( {
63+ entrypoints : [ "./deno-runtime/main.ts" ] ,
64+ outdir : "./dist/deno-runtime" ,
65+ } ) ;
66+ return {
67+ cli,
68+ denoRuntime,
69+ } ;
70+ } ;
71+
2472const formatOutput = ( outputs : { path : string } [ ] ) => {
2573 return outputs . map ( ( o ) => chalk . cyan ( o . path ) ) . join ( "\n " ) ;
2674} ;
2775
2876if ( process . argv . includes ( "--watch" ) ) {
2977 console . log ( chalk . yellow ( "Watching for changes..." ) ) ;
3078
31- const changeHandler = async ( event : "rename" | "change" , filename : string | null ) => {
79+ const changeHandler = async (
80+ event : "rename" | "change" ,
81+ filename : string | null
82+ ) => {
3283 const time = new Date ( ) . toLocaleTimeString ( ) ;
3384 console . log ( chalk . dim ( `[${ time } ]` ) , chalk . gray ( `${ filename } ${ event } d` ) ) ;
3485
35- const result = await runBuild ( ) ;
36- console . log (
37- chalk . green ( ` ✓ Rebuilt` ) ,
38- chalk . dim ( `→` ) ,
39- formatOutput ( result . outputs )
40- ) ;
86+ const { cli, denoRuntime } = await runAllBuilds ( ) ;
87+ for ( const result of [ cli , denoRuntime ] ) {
88+ if ( result . success && result . outputs . length > 0 ) {
89+ console . log (
90+ chalk . green ( ` ✓ Rebuilt` ) ,
91+ chalk . dim ( `→` ) ,
92+ formatOutput ( result . outputs )
93+ ) ;
94+ }
95+ }
4196 } ;
4297
43- await runBuild ( ) ;
98+ await runAllBuilds ( ) ;
4499
45- for ( const dir of [ "./src" ] ) {
100+ for ( const dir of [ "./src" , "./deno-runtime" ] ) {
46101 watch ( dir , { recursive : true } , changeHandler ) ;
47102 }
48103
49104 // Keep process alive
50105 await new Promise ( ( ) => { } ) ;
51106} else {
52- const result = await runBuild ( ) ;
107+ const { cli , denoRuntime } = await runAllBuilds ( ) ;
53108 console . log ( chalk . green . bold ( `\n✓ Build complete\n` ) ) ;
54109 console . log ( chalk . dim ( " Output:" ) ) ;
55- console . log ( ` ${ formatOutput ( result . outputs ) } \n` ) ;
110+ console . log ( ` ${ formatOutput ( cli . outputs ) } ` ) ;
111+ console . log ( ` ${ formatOutput ( denoRuntime . outputs ) } \n` ) ;
56112}
0 commit comments