make esbuild run serverless
This commit is contained in:
parent
3053e11beb
commit
c2e411b100
18
package-lock.json
generated
18
package-lock.json
generated
@ -1872,6 +1872,18 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-wasm": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.12.tgz",
|
||||
"integrity": "sha512-rZqkjL3Y6FwLpSHzLnaEy8Ps6veCNo1kZa9EOfJvmWtBq5dJH4iVjfmOO6Mlkv9B0tt9WFPFmb/VxlgJOnueNg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
@ -3526,7 +3538,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mcp-ui/server": "^5.15.0",
|
||||
"esbuild": "^0.25.0"
|
||||
"esbuild-wasm": "^0.25.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.10.0",
|
||||
@ -3539,6 +3551,9 @@
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"esbuild": "^0.25.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.0.0",
|
||||
"react-dom": ">=18.0.0"
|
||||
@ -3584,6 +3599,7 @@
|
||||
"integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
|
||||
@ -47,6 +47,9 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mcp-ui/server": "^5.15.0",
|
||||
"esbuild-wasm": "^0.25.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"esbuild": "^0.25.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@ -1,12 +1,38 @@
|
||||
import * as esbuild from 'esbuild';
|
||||
|
||||
// Cache bundled JS per entry path (only used in production)
|
||||
const bundleCache = new Map<string, string>();
|
||||
|
||||
// In development mode, skip cache to allow hot-reloading of component changes
|
||||
const isDev = process.env.NODE_ENV !== 'production';
|
||||
|
||||
async function runBuild(entryPath: string): Promise<esbuild.BuildResult<{ write: false }>> {
|
||||
// Dynamic esbuild loader - tries native first, falls back to wasm for serverless
|
||||
let esbuildModule: typeof import('esbuild') | null = null;
|
||||
let wasmInitialized = false;
|
||||
|
||||
async function getEsbuild(): Promise<typeof import('esbuild')> {
|
||||
if (esbuildModule) return esbuildModule;
|
||||
|
||||
// Try native esbuild first (faster, works locally)
|
||||
try {
|
||||
esbuildModule = await import('esbuild');
|
||||
// Test if native binary works
|
||||
await esbuildModule.transform('', { loader: 'js' });
|
||||
return esbuildModule;
|
||||
} catch {
|
||||
// Fall back to wasm (works on serverless without native binaries)
|
||||
const wasm = await import('esbuild-wasm');
|
||||
if (!wasmInitialized) {
|
||||
await wasm.initialize({
|
||||
wasmURL: `https://unpkg.com/esbuild-wasm@${wasm.version}/esbuild.wasm`,
|
||||
});
|
||||
wasmInitialized = true;
|
||||
}
|
||||
esbuildModule = wasm as typeof import('esbuild');
|
||||
return esbuildModule;
|
||||
}
|
||||
}
|
||||
|
||||
async function runBuild(entryPath: string): Promise<import('esbuild').BuildResult<{ write: false }>> {
|
||||
const esbuild = await getEsbuild();
|
||||
return esbuild.build({
|
||||
entryPoints: [entryPath],
|
||||
bundle: true,
|
||||
@ -27,7 +53,7 @@ export async function bundleComponent(entryPath: string): Promise<string> {
|
||||
return bundleCache.get(entryPath)!;
|
||||
}
|
||||
|
||||
let result: esbuild.BuildResult<{ write: false }>;
|
||||
let result: import('esbuild').BuildResult<{ write: false }>;
|
||||
|
||||
try {
|
||||
result = await runBuild(entryPath);
|
||||
@ -41,6 +67,7 @@ export async function bundleComponent(entryPath: string): Promise<string> {
|
||||
);
|
||||
if (isServiceError) {
|
||||
// Force stop the dead service, then retry - esbuild will start fresh
|
||||
const esbuild = await getEsbuild();
|
||||
await esbuild.stop();
|
||||
result = await runBuild(entryPath);
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user