mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 06:05:24 +00:00
86 lines
2.8 KiB
JavaScript
86 lines
2.8 KiB
JavaScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import * as esbuild from "esbuild";
|
|
import { BACKEND_EXTERNALS, FRONTEND_EXTERNALS } from "../lib/externals.mjs";
|
|
import { staticUrlImports } from "../lib/static-url-imports.mjs";
|
|
import { readManifest, resolveEntry, copyDir } from "../lib/plugin-dir.mjs";
|
|
|
|
const BACKEND_ENTRIES = [
|
|
"src/backend/index.ts",
|
|
"src/backend/index.mjs",
|
|
"src/backend/index.js",
|
|
];
|
|
const FRONTEND_ENTRIES = [
|
|
"src/frontend/index.tsx",
|
|
"src/frontend/index.ts",
|
|
"src/frontend/index.mjs",
|
|
"src/frontend/index.js",
|
|
];
|
|
|
|
export async function build({ cwd }) {
|
|
const manifest = readManifest(cwd);
|
|
const pluginId = manifest.id ?? path.basename(cwd);
|
|
const outDir = path.join(cwd, "dist");
|
|
|
|
fs.rmSync(outDir, { recursive: true, force: true });
|
|
fs.mkdirSync(outDir, { recursive: true });
|
|
|
|
const backendEntry = resolveEntry(cwd, BACKEND_ENTRIES);
|
|
if (!backendEntry) {
|
|
throw new Error(
|
|
`${pluginId}: no backend entry (looked for ${BACKEND_ENTRIES.join(", ")})`,
|
|
);
|
|
}
|
|
|
|
await esbuild.build({
|
|
entryPoints: [backendEntry],
|
|
outfile: path.join(outDir, "backend.js"),
|
|
bundle: true,
|
|
format: "esm",
|
|
platform: "node",
|
|
target: "node22",
|
|
sourcemap: true,
|
|
logLevel: "warning",
|
|
// A native dependency's compiled .node binary is resolved by the
|
|
// package's own relative paths, which break once esbuild inlines its JS
|
|
// elsewhere. Declaring it in nativeDependencies keeps it a real
|
|
// node_modules import instead, resolved at runtime like a host-provided
|
|
// package.
|
|
external: [...BACKEND_EXTERNALS, ...(manifest.nativeDependencies ?? [])],
|
|
// Bundled CJS deps still call require() for Node builtins at runtime.
|
|
// ESM has no ambient require, so give esbuild's require shim a real one.
|
|
banner: {
|
|
js: "import { createRequire as __termixCreateRequire } from 'node:module'; const require = __termixCreateRequire(import.meta.url);",
|
|
},
|
|
});
|
|
|
|
// Without this Node finds the host's typeless package.json, tries backend.js
|
|
// as CommonJS first and warns before reparsing it as ESM.
|
|
fs.writeFileSync(
|
|
path.join(outDir, "package.json"),
|
|
`${JSON.stringify({ type: "module" }, null, 2)}\n`,
|
|
);
|
|
|
|
const frontendEntry = resolveEntry(cwd, FRONTEND_ENTRIES);
|
|
if (frontendEntry) {
|
|
await esbuild.build({
|
|
entryPoints: [frontendEntry],
|
|
outfile: path.join(outDir, "frontend.js"),
|
|
bundle: true,
|
|
format: "esm",
|
|
platform: "browser",
|
|
target: "es2022",
|
|
jsx: "automatic",
|
|
sourcemap: true,
|
|
logLevel: "warning",
|
|
external: FRONTEND_EXTERNALS,
|
|
plugins: [staticUrlImports({ outDir })],
|
|
});
|
|
}
|
|
|
|
copyDir(path.join(cwd, "locales"), path.join(outDir, "locales"));
|
|
copyDir(path.join(cwd, "migrations"), path.join(outDir, "migrations"));
|
|
|
|
console.log(`built ${pluginId}`);
|
|
}
|