71 lines
1.9 KiB
JavaScript

#!/usr/bin/env node
/**
* Build script — compiles each app in src/apps/* into a single HTML file at dist/app-ui/{name}.html
* Uses Vite + vite-plugin-singlefile to inline all JS/CSS/assets.
*/
import { build } from 'vite';
import { viteSingleFile } from 'vite-plugin-singlefile';
import { readdirSync, existsSync, mkdirSync } from 'fs';
import { resolve, join } from 'path';
const appsDir = resolve('src/apps');
const distDir = resolve('dist/app-ui');
if (!existsSync(distDir)) mkdirSync(distDir, { recursive: true });
const apps = readdirSync(appsDir).filter(d => {
const indexHtml = join(appsDir, d, 'index.html');
return existsSync(indexHtml);
});
console.log(`Building ${apps.length} MCP Apps...\n`);
for (const app of apps) {
const appDir = join(appsDir, app);
const outDir = join(distDir);
console.log(` Building: ${app}...`);
try {
await build({
root: appDir,
plugins: [viteSingleFile()],
build: {
outDir,
emptyOutDir: false,
rollupOptions: {
input: join(appDir, 'index.html'),
output: {
entryFileNames: `${app}.js`,
assetFileNames: `${app}.[ext]`,
}
},
minify: 'esbuild',
},
resolve: {
alias: {
'@components': resolve('src/components'),
'@hooks': resolve('src/hooks'),
'@styles': resolve('src/styles'),
'@utils': resolve('src/utils'),
}
},
logLevel: 'warn',
});
// Rename index.html to {app-name}.html
const { renameSync } = await import('fs');
const srcPath = join(outDir, 'index.html');
const destPath = join(outDir, `${app}.html`);
if (existsSync(srcPath) && srcPath !== destPath) {
renameSync(srcPath, destPath);
}
console.log(`${app} → dist/app-ui/${app}.html`);
} catch (err) {
console.error(`${app} failed:`, err.message);
}
}
console.log(`\nDone! ${apps.length} apps built.`);