Skip to content

Commit e799d30

Browse files
committed
Some more build cleanup
1 parent 0cc7091 commit e799d30

File tree

8 files changed

+141
-143
lines changed

8 files changed

+141
-143
lines changed

build_client.ts renamed to build/build_client.ts

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,14 @@
11
import { cp, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
22
import { fileURLToPath } from "node:url";
3-
import { dirname } from "node:path";
43
import * as sass from "sass";
54

65
import * as esbuild from "esbuild";
76

8-
import { patchBundledJS } from "./client/plugos/plug_compile.ts";
9-
10-
const __filename = fileURLToPath(import.meta.url);
11-
const __dirname = dirname(__filename);
7+
import { patchBundledJS } from "../client/plugos/plug_compile.ts";
128

139
// This builds the client and puts it into client_bundle/client
1410

15-
export async function bundleAll(): Promise<void> {
16-
await buildCopyBundleAssets();
17-
}
18-
19-
export async function copyAssets(dist: string) {
20-
await mkdir(dist, { recursive: true });
21-
await cp("client/fonts", `${dist}`, { recursive: true });
22-
await cp("client/html/index.html", `${dist}/index.html`);
23-
await cp("client/html/auth.html", `${dist}/auth.html`);
24-
await cp("client/images/favicon.png", `${dist}/favicon.png`);
25-
await cp("client/images/logo.png", `${dist}/logo.png`);
26-
await cp("client/images/logo-dock.png", `${dist}/logo-dock.png`);
27-
28-
const scssContent = await readFile("client/styles/main.scss", "utf-8");
29-
const result = sass.compileString(scssContent, {
30-
loadPaths: ["client/styles"],
31-
style: "compressed",
32-
});
33-
await writeFile(`${dist}/main.css`, result.css, "utf-8");
34-
35-
// HACK: Patch the JS by removing an invalid regex
36-
let bundleJs = await readFile(`${dist}/client.js`, "utf-8");
37-
bundleJs = patchBundledJS(bundleJs);
38-
await writeFile(`${dist}/client.js`, bundleJs, "utf-8");
39-
}
40-
41-
async function buildCopyBundleAssets() {
11+
export async function buildClient(): Promise<void> {
4212
await mkdir("client_bundle/client", { recursive: true });
4313
await mkdir("client_bundle/base_fs", { recursive: true });
4414

@@ -77,7 +47,33 @@ async function buildCopyBundleAssets() {
7747
}
7848

7949
await copyAssets("client_bundle/client/.client");
50+
await patchServiceWorker();
51+
52+
console.log("Built!");
53+
}
54+
55+
async function copyAssets(dist: string) {
56+
await mkdir(dist, { recursive: true });
57+
await cp("client/fonts", dist, { recursive: true });
58+
await cp("client/html", dist, { recursive: true });
59+
await cp("client/images/favicon.png", `${dist}/favicon.png`);
60+
await cp("client/images/logo.png", `${dist}/logo.png`);
61+
await cp("client/images/logo-dock.png", `${dist}/logo-dock.png`);
62+
63+
const scssContent = await readFile("client/styles/main.scss", "utf-8");
64+
const result = sass.compileString(scssContent, {
65+
loadPaths: ["client/styles"],
66+
style: "compressed",
67+
});
68+
await writeFile(`${dist}/main.css`, result.css, "utf-8");
8069

70+
// HACK: Patch the JS by removing an invalid regex
71+
let bundleJs = await readFile(`${dist}/client.js`, "utf-8");
72+
bundleJs = patchBundledJS(bundleJs);
73+
await writeFile(`${dist}/client.js`, bundleJs, "utf-8");
74+
}
75+
76+
async function patchServiceWorker() {
8177
// Scan .client/ directory to build the full precache file list
8278
const clientDir = "client_bundle/client/.client";
8379
const allFiles = await readdir(clientDir);
@@ -104,12 +100,10 @@ async function buildCopyBundleAssets() {
104100
swCode = swCode.replaceAll("{{CACHE_NAME}}", `cache-${Date.now()}`);
105101
swCode = swCode.replaceAll("{{PRECACHE_FILES}}", precacheFilesStr);
106102
await writeFile("client_bundle/client/service_worker.js", swCode, "utf-8");
107-
108-
console.log("Built!");
109103
}
110104

111105
const isMain = process.argv[1] === fileURLToPath(import.meta.url);
112106
if (isMain) {
113-
await bundleAll();
107+
await buildClient();
114108
await esbuild.stop();
115109
}

build/build_plug_compile.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { mkdir } from "node:fs/promises";
2+
import { fileURLToPath } from "node:url";
3+
import * as esbuild from "esbuild";
4+
5+
export async function buildPlugCompile(): Promise<void> {
6+
await mkdir("dist", { recursive: true });
7+
8+
// Pre-bundle the worker runtime so it can be embedded into plug-compile.js
9+
// as a string constant. This way the bundled CLI is fully self-contained.
10+
const workerBuild = await esbuild.build({
11+
entryPoints: ["client/plugos/worker_runtime.ts"],
12+
bundle: true,
13+
format: "esm",
14+
platform: "browser",
15+
write: false,
16+
treeShaking: true,
17+
});
18+
const workerRuntimeJS = workerBuild.outputFiles[0].text;
19+
20+
const result = await esbuild.build({
21+
entryPoints: ["./bin/plug-compile.ts"],
22+
outfile: "dist/plug-compile.js",
23+
format: "esm",
24+
banner: {
25+
js: "#!/usr/bin/env node",
26+
},
27+
platform: "node",
28+
absWorkingDir: process.cwd(),
29+
bundle: true,
30+
metafile: false,
31+
treeShaking: true,
32+
logLevel: "error",
33+
minify: false, // Don't minify for better debugging
34+
define: {
35+
__EMBEDDED_WORKER_RUNTIME_JS__: JSON.stringify(workerRuntimeJS),
36+
},
37+
// Mark all npm packages as external - they'll be installed by npm
38+
external: [
39+
"esbuild",
40+
"commander",
41+
"js-yaml",
42+
"sass",
43+
],
44+
});
45+
if (result.metafile) {
46+
const text = await esbuild.analyzeMetafile(result.metafile!);
47+
console.log("Bundle info", text);
48+
}
49+
}
50+
51+
const isMain = process.argv[1] === fileURLToPath(import.meta.url);
52+
if (isMain) {
53+
await buildPlugCompile();
54+
await esbuild.stop();
55+
}
Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,16 @@ import { fileURLToPath } from "node:url";
66
import { spawn } from "node:child_process";
77
import * as esbuild from "esbuild";
88

9-
import { compileManifests } from "./client/plugos/plug_compile.ts";
10-
import { builtinPlugNames } from "./plugs/builtin_plugs.ts";
11-
import { version } from "./version.ts";
9+
import { compileManifests } from "../client/plugos/plug_compile.ts";
10+
import { builtinPlugNames } from "../plugs/builtin_plugs.ts";
11+
import { version } from "../version.ts";
1212

1313
// This builds all built-in plugs and libraries and puts them into client_bundle/base_fs
1414

15-
const isMain = process.argv[1] === fileURLToPath(import.meta.url);
16-
if (isMain) {
17-
await updateVersionFile();
18-
const { values: args } = parseArgs({
19-
args: process.argv.slice(2),
20-
options: {
21-
debug: { type: "boolean" },
22-
reload: { type: "boolean" },
23-
info: { type: "boolean" },
24-
watch: { type: "boolean", short: "w" },
25-
},
26-
strict: false,
27-
});
28-
15+
export async function buildPlugsAndLibraries(options?: {
16+
debug?: boolean;
17+
info?: boolean;
18+
}): Promise<void> {
2919
const manifests = builtinPlugNames.map(
3020
(name) => `./plugs/${name}/${name}.plug.yaml`,
3121
);
@@ -45,13 +35,12 @@ if (isMain) {
4535

4636
// Build the plugs
4737
await compileManifests(manifests, targetDir, {
48-
debug: args.debug as boolean | undefined,
49-
info: args.info as boolean | undefined,
38+
debug: options?.debug,
39+
info: options?.info,
5040
});
51-
await esbuild.stop();
5241
}
5342

54-
export async function updateVersionFile() {
43+
export function updateVersionFile(): Promise<void> {
5544
return new Promise<void>((resolve, reject) => {
5645
const gitProcess = spawn("git", ["describe", "--tags", "--long"], {
5746
stdio: ["ignore", "pipe", "pipe"],
@@ -90,3 +79,22 @@ export async function updateVersionFile() {
9079
gitProcess.on("error", reject);
9180
});
9281
}
82+
83+
const isMain = process.argv[1] === fileURLToPath(import.meta.url);
84+
if (isMain) {
85+
const { values: args } = parseArgs({
86+
args: process.argv.slice(2),
87+
options: {
88+
debug: { type: "boolean" },
89+
info: { type: "boolean" },
90+
},
91+
strict: false,
92+
});
93+
94+
await updateVersionFile();
95+
await buildPlugsAndLibraries({
96+
debug: args.debug as boolean | undefined,
97+
info: args.info as boolean | undefined,
98+
});
99+
await esbuild.stop();
100+
}

build_plug_compile.ts

Lines changed: 0 additions & 41 deletions
This file was deleted.

build_worker_runtime.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

client/asset_bundle/builder.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import picomatch from "picomatch";
21
import { readFile, readdir } from "node:fs/promises";
3-
import { join } from "node:path";
2+
import { join, matchesGlob } from "node:path";
43
import mime from "mime";
54

65
import { AssetBundle } from "./bundle.ts";
@@ -25,11 +24,9 @@ export async function bundleAssets(
2524
if (patterns.length === 0) {
2625
return bundle;
2726
}
28-
const isMatch = picomatch(patterns);
2927
for await (const file of walk(rootPath)) {
3028
const cleanPath = file.path.substring(rootPath.length + 1);
31-
// console.log("Considering", rootPath, file.path, cleanPath);
32-
if (isMatch(cleanPath)) {
29+
if (patterns.some((p) => matchesGlob(cleanPath, p))) {
3330
bundle.writeFileSync(
3431
cleanPath,
3532
mime.getType(cleanPath) || "application/octet-stream",

client/plugos/plug_compile.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,30 @@ import * as esbuild from "esbuild";
77
import { bundleAssets } from "../asset_bundle/builder.ts";
88
import type { Manifest } from "./types.ts";
99

10-
import { existsSync } from "node:fs";
11-
12-
// Resolve the pre-built worker_runtime bundle path
13-
// When running from source: ../../dist/worker_runtime_bundle.js (from client/plugos/)
14-
// When bundled: ./worker_runtime_bundle.js (from dist/)
15-
const currentDir = import.meta.dirname;
16-
const bundledPath = path.join(currentDir, "worker_runtime_bundle.js");
17-
const sourcePath = path.join(currentDir, "../../dist/worker_runtime_bundle.js");
18-
const workerRuntimeBundlePath = existsSync(bundledPath)
19-
? bundledPath
20-
: sourcePath;
10+
// When bundled by build_plug_compile.ts, this is replaced with the pre-bundled
11+
// worker runtime JS. When running from source, it's undefined and esbuild
12+
// resolves the .ts file directly (it handles TypeScript natively).
13+
declare const __EMBEDDED_WORKER_RUNTIME_JS__: string | undefined;
2114

2215
const workerRuntimePlugin: esbuild.Plugin = {
2316
name: "worker-runtime",
2417
setup(build) {
25-
build.onResolve({ filter: /^worker-runtime$/ }, () => ({
26-
path: workerRuntimeBundlePath,
27-
}));
18+
if (typeof __EMBEDDED_WORKER_RUNTIME_JS__ !== "undefined") {
19+
// Bundled CLI: serve pre-bundled JS from the embedded constant
20+
build.onResolve({ filter: /^worker-runtime$/ }, () => ({
21+
path: "worker-runtime",
22+
namespace: "worker-runtime",
23+
}));
24+
build.onLoad(
25+
{ filter: /.*/, namespace: "worker-runtime" },
26+
() => ({ contents: __EMBEDDED_WORKER_RUNTIME_JS__, loader: "js" }),
27+
);
28+
} else {
29+
// From source: point directly at the .ts file, esbuild handles it
30+
build.onResolve({ filter: /^worker-runtime$/ }, () => ({
31+
path: path.join(import.meta.dirname, "worker_runtime.ts"),
32+
}));
33+
}
2834
},
2935
};
3036

package.json

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,13 @@
4747
"!client/space_lua/**/*.bench.ts",
4848
"client/markdown_parser/constants.ts",
4949
"plugs/builtin_plugs.ts",
50-
"dist/plug-compile.js",
51-
"dist/worker_runtime_bundle.js"
50+
"dist/plug-compile.js"
5251
],
5352
"scripts": {
54-
"build": "tsx build_worker_runtime.ts && npm run build:plugs && npm run build:client",
55-
"build:plugs": "tsx build_plugs_libraries.ts",
56-
"build:client": "tsx build_client.ts",
57-
"build:plug-compile": "tsx build_worker_runtime.ts && tsx build_plug_compile.ts",
53+
"build": "npm run build:plugs && npm run build:client",
54+
"build:plugs": "tsx build/build_plugs.ts",
55+
"build:client": "tsx build/build_client.ts",
56+
"build:plug-compile": "tsx build/build_plug_compile.ts",
5857
"prepublishOnly": "npm run build:plug-compile",
5958
"test": "vitest run",
6059
"check": "tsc --noEmit",
@@ -98,7 +97,6 @@
9897
"idb": "8.0.3",
9998
"js-yaml": "^4.1.1",
10099
"mime": "4.1.0",
101-
"picomatch": "^4.0.3",
102100
"preact": "10.28.2",
103101
"preact-feather": "4.2.1",
104102
"react-icons": "5.5.0",
@@ -112,7 +110,7 @@
112110
"@types/gitignore-parser": "^0.0.3",
113111
"@types/js-yaml": "^4.0.9",
114112
"@types/node": "^22.0.0",
115-
"@types/picomatch": "^4.0.2",
113+
116114
"@types/turndown": "^5.0.6",
117115
"fake-indexeddb": "6.0.1",
118116
"tsx": "^4.19.0",

0 commit comments

Comments
 (0)