Skip to content

Commit 93b52a6

Browse files
Claudehotlong
andauthored
fix(server): replace Function constructor with proper dynamic imports for esbuild bundling
Replace `new Function('s', 'return import(s)')` with standard `import()` statements in bootstrap.ts to allow esbuild to analyze and bundle the config files. The Function constructor pattern bypassed static analysis, preventing esbuild from including objectstack.config.ts and example configs in the Vercel bundle. This caused runtime module resolution errors when the source .ts files weren't deployed. With proper dynamic imports, esbuild can now: - Analyze imports at build time - Resolve and bundle objectstack.config.ts - Include example app configs when needed - Produce a self-contained _handler.js bundle Fixes: Cannot find module '/var/task/apps/server/objectstack.config.ts' Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/6b0db307-90c8-4fdd-8603-d1b61f3373da Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 7e85490 commit 93b52a6

1 file changed

Lines changed: 14 additions & 13 deletions

File tree

apps/server/server/bootstrap.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,12 @@ async function bootstrapSingle(): Promise<BootstrapResult> {
9090
// apps/plugins it references. A schema drift in one of the examples
9191
// shouldn't crash multi-project boots (or the E2E test harness) when
9292
// they don't need those bundles at all.
93-
const dyn = (spec: string) =>
94-
(new Function('s', 'return import(s)') as (s: string) => Promise<any>)(spec);
95-
const stackConfig = (await dyn('../objectstack.config.ts')).default;
93+
//
94+
// Use a proper dynamic import (not Function constructor) so esbuild can
95+
// bundle the config into the Vercel handler. The Function constructor
96+
// bypasses static analysis and prevents bundling, causing runtime errors
97+
// when the source .ts file isn't deployed.
98+
const stackConfig = (await import('../objectstack.config.js')).default;
9699

97100
if (!stackConfig.plugins || stackConfig.plugins.length === 0) {
98101
throw new Error('[Bootstrap] No plugins found in stackConfig');
@@ -214,17 +217,15 @@ async function bootstrapMultiProject(
214217
if (process.env.OBJECTSTACK_BUNDLE_EXAMPLES !== 'true') {
215218
return [];
216219
}
217-
// Dynamic `new Function('return import(...)')(…)` sidesteps
218-
// TypeScript's static rootDir analysis — the example configs
219-
// live outside apps/server's tsconfig rootDir but are still
220-
// resolvable at runtime. Kept here intentionally so the tsc
221-
// typecheck doesn't need a dedicated include for examples.
222-
const dyn = (spec: string) =>
223-
(new Function('s', 'return import(s)') as (s: string) => Promise<any>)(spec);
220+
// Use proper dynamic imports so esbuild can bundle the example configs.
221+
// The Function constructor would bypass static analysis and prevent
222+
// bundling, causing runtime errors when source .ts files aren't
223+
// deployed. esbuild will inline these imports even though they're
224+
// outside the apps/server directory.
224225
const [crm, todo, bi] = await Promise.all([
225-
dyn('../../../examples/app-crm/objectstack.config.ts'),
226-
dyn('../../../examples/app-todo/objectstack.config.ts'),
227-
dyn('../../../examples/plugin-bi/objectstack.config.ts'),
226+
import('../../../examples/app-crm/objectstack.config.js'),
227+
import('../../../examples/app-todo/objectstack.config.js'),
228+
import('../../../examples/plugin-bi/objectstack.config.js'),
228229
]);
229230
return [crm.default, todo.default, bi.default];
230231
},

0 commit comments

Comments
 (0)