@@ -17,6 +17,7 @@ import {
1717 telemetryEntryPoint ,
1818} from "./packageModules.js" ;
1919import { buildPlugins } from "./plugins.js" ;
20+ import { createEntryPointManager } from "./entryPoints.js" ;
2021
2122export interface BundleOptions {
2223 target : BuildTarget ;
@@ -45,12 +46,30 @@ export type BundleResult = {
4546export async function bundleWorker ( options : BundleOptions ) : Promise < BundleResult > {
4647 const { resolvedConfig } = options ;
4748
48- // We need to add the package entry points here somehow
49- // Then we need to get them out of the build result into the build manifest
50- // taskhero/dist/esm/workers/dev.js
51- // taskhero/dist/esm/telemetry/loader.js
52- const entryPoints = await getEntryPoints ( options . target , resolvedConfig ) ;
53- const $buildPlugins = await buildPlugins ( options . target , resolvedConfig ) ;
49+ let currentContext : esbuild . BuildContext | undefined ;
50+
51+ const entryPointManager = await createEntryPointManager (
52+ resolvedConfig . dirs ,
53+ resolvedConfig ,
54+ options . target ,
55+ typeof options . watch === "boolean" ? options . watch : false ,
56+ async ( newEntryPoints ) => {
57+ if ( currentContext ) {
58+ // Rebuild with new entry points
59+ await currentContext . cancel ( ) ;
60+ await currentContext . dispose ( ) ;
61+ const buildOptions = await createBuildOptions ( {
62+ ...options ,
63+ entryPoints : newEntryPoints ,
64+ } ) ;
65+
66+ logger . debug ( "Rebuilding worker with options" , buildOptions ) ;
67+
68+ currentContext = await esbuild . context ( buildOptions ) ;
69+ await currentContext . watch ( ) ;
70+ }
71+ }
72+ ) ;
5473
5574 let initialBuildResult : ( result : esbuild . BuildResult ) => void ;
5675 const initialBuildResultPromise = new Promise < esbuild . BuildResult > (
@@ -63,12 +82,63 @@ export async function bundleWorker(options: BundleOptions): Promise<BundleResult
6382 } ,
6483 } ;
6584
85+ const buildOptions = await createBuildOptions ( {
86+ ...options ,
87+ entryPoints : entryPointManager . entryPoints ,
88+ buildResultPlugin,
89+ } ) ;
90+
91+ let result : esbuild . BuildResult < typeof buildOptions > ;
92+ let stop : BundleResult [ "stop" ] ;
93+
94+ logger . debug ( "Building worker with options" , buildOptions ) ;
95+
96+ if ( options . watch ) {
97+ currentContext = await esbuild . context ( buildOptions ) ;
98+ await currentContext . watch ( ) ;
99+ result = await initialBuildResultPromise ;
100+ if ( result . errors . length > 0 ) {
101+ throw new Error ( "Failed to build" ) ;
102+ }
103+
104+ stop = async function ( ) {
105+ await entryPointManager . stop ( ) ;
106+ await currentContext ?. dispose ( ) ;
107+ } ;
108+ } else {
109+ result = await esbuild . build ( buildOptions ) ;
110+
111+ stop = async function ( ) {
112+ await entryPointManager . stop ( ) ;
113+ } ;
114+ }
115+
116+ const bundleResult = await getBundleResultFromBuild (
117+ options . target ,
118+ options . cwd ,
119+ options . resolvedConfig ,
120+ result
121+ ) ;
122+
123+ if ( ! bundleResult ) {
124+ throw new Error ( "Failed to get bundle result" ) ;
125+ }
126+
127+ return { ...bundleResult , stop } ;
128+ }
129+
130+ // Helper function to create build options
131+ async function createBuildOptions (
132+ options : BundleOptions & { entryPoints : string [ ] ; buildResultPlugin ?: esbuild . Plugin }
133+ ) : Promise < esbuild . BuildOptions & { metafile : true } > {
66134 const customConditions = options . resolvedConfig . build ?. conditions ?? [ ] ;
67135
68136 const conditions = [ ...customConditions , "trigger.dev" , "module" , "node" ] ;
69137
70- const buildOptions : esbuild . BuildOptions & { metafile : true } = {
71- entryPoints,
138+ const $buildPlugins = await buildPlugins ( options . target , options . resolvedConfig ) ;
139+
140+ return {
141+ entryPoints : options . entryPoints ,
72142 outdir : options . destination ,
73143 absWorkingDir : options . cwd ,
74144 bundle : true ,
@@ -93,50 +163,18 @@ export async function bundleWorker(options: BundleOptions): Promise<BundleResult
93163 inject : [ ...shims ] , // TODO: copy this into the working dir to work with Yarn PnP
94164 jsx : options . jsxAutomatic ? "automatic" : undefined ,
95165 jsxDev : options . jsxAutomatic && options . target === "dev" ? true : undefined ,
96- plugins : [ ...$buildPlugins , ...( options . plugins ?? [ ] ) , buildResultPlugin ] ,
166+ plugins : [
167+ ...$buildPlugins ,
168+ ...( options . plugins ?? [ ] ) ,
169+ ...( options . buildResultPlugin ? [ options . buildResultPlugin ] : [ ] ) ,
170+ ] ,
97171 ...( options . jsxFactory && { jsxFactory : options . jsxFactory } ) ,
98172 ...( options . jsxFragment && { jsxFragment : options . jsxFragment } ) ,
99173 logLevel : "silent" ,
100174 logOverride : {
101175 "empty-glob" : "silent" ,
102176 } ,
103177 } ;
104-
105- let result : esbuild . BuildResult < typeof buildOptions > ;
106- let stop : BundleResult [ "stop" ] ;
107-
108- logger . debug ( "Building worker with options" , buildOptions ) ;
109-
110- if ( options . watch ) {
111- const ctx = await esbuild . context ( buildOptions ) ;
112- await ctx . watch ( ) ;
113- result = await initialBuildResultPromise ;
114- if ( result . errors . length > 0 ) {
115- throw new Error ( "Failed to build" ) ;
116- }
117-
118- stop = async function ( ) {
119- await ctx . dispose ( ) ;
120- } ;
121- } else {
122- result = await esbuild . build ( buildOptions ) ;
123- // Even when we're not watching, we still want some way of cleaning up the
124- // temporary directory when we don't need it anymore
125- stop = async function ( ) { } ;
126- }
127-
128- const bundleResult = await getBundleResultFromBuild (
129- options . target ,
130- options . cwd ,
131- options . resolvedConfig ,
132- result
133- ) ;
134-
135- if ( ! bundleResult ) {
136- throw new Error ( "Failed to get bundle result" ) ;
137- }
138-
139- return { ...bundleResult , stop } ;
140178}
141179
142180export async function getBundleResultFromBuild (
0 commit comments