Amp-Thread-ID: https://ampcode.com/threads/T-01a0b382-1e79-712b-abd1-d29201c9bb5e Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
140 lines
4.2 KiB
JavaScript
140 lines
4.2 KiB
JavaScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import process from "node:process";
|
|
import { build } from "esbuild";
|
|
|
|
const [root, output] = process.argv.slice(2);
|
|
if (!root || !output)
|
|
throw new Error("usage: node build.mjs <repository> <output>");
|
|
|
|
const browser = {
|
|
bundle: true,
|
|
format: "esm",
|
|
legalComments: "none",
|
|
minify: true,
|
|
platform: "browser",
|
|
target: "es2022",
|
|
};
|
|
|
|
const fxNodeSource = path.join(root, "vendor", "fxnode", "src");
|
|
const fxNodeImports = {
|
|
name: "yawn-fxnode-imports",
|
|
setup(builder) {
|
|
builder.onResolve({ filter: /^fxnode$/ }, () => ({
|
|
path: path.join(fxNodeSource, "index.ts"),
|
|
}));
|
|
builder.onResolve({ filter: /\?worker&url$/ }, () => ({
|
|
path: "fxnode-worker-url",
|
|
namespace: "yawn-fxnode-worker",
|
|
}));
|
|
builder.onLoad({ filter: /.*/, namespace: "yawn-fxnode-worker" }, () => ({
|
|
contents: 'export default "./fxnode-worker.js";',
|
|
loader: "js",
|
|
}));
|
|
},
|
|
};
|
|
|
|
const coreWorker = await build({
|
|
...browser,
|
|
entryPoints: [path.join(root, "core", "worker.js")],
|
|
external: ["./pkg/yawn_core.js"],
|
|
write: false,
|
|
});
|
|
const coreWorkerSource = coreWorker.outputFiles[0].text;
|
|
|
|
const workerFiles = new Map([
|
|
[
|
|
path.join(root, "core", "index.js"),
|
|
{
|
|
url: "./worker.js",
|
|
source: coreWorkerSource,
|
|
},
|
|
],
|
|
[
|
|
path.join(root, "addons", "handles", "src", "importers", "gltf.ts"),
|
|
{ url: "./importer-worker.js" },
|
|
],
|
|
[
|
|
path.join(root, "addons", "handles", "src", "bvh", "picking.ts"),
|
|
{ url: "./bvh-worker.js" },
|
|
],
|
|
]);
|
|
|
|
const workerURLs = {
|
|
name: "yawn-worker-urls",
|
|
setup(builder) {
|
|
builder.onLoad({ filter: /\.(js|ts)$/ }, async ({ path: source }) => {
|
|
const worker = workerFiles.get(path.normalize(source));
|
|
if (!worker) return;
|
|
let contents = await fs.readFile(source, "utf8");
|
|
const transformed = contents.replace(
|
|
/new Worker\(new URL\("\.\/worker\.(?:js|ts)", import\.meta\.url\),/,
|
|
`createYawnWorker(new URL(${JSON.stringify(worker.url)}, import.meta.url), ${worker.source ? JSON.stringify(worker.source) : "undefined"},`,
|
|
);
|
|
if (transformed === contents)
|
|
throw new Error(`worker constructor not found in ${source}`);
|
|
contents = `
|
|
function createYawnWorker(url, embeddedSource, options) {
|
|
if (embeddedSource) {
|
|
const moduleUrl = new URL("./pkg/yawn_core.js", url);
|
|
const source = embeddedSource.replace("./pkg/yawn_core.js", moduleUrl.href);
|
|
const bootstrap = URL.createObjectURL(new Blob([source], { type: "text/javascript" }));
|
|
const worker = new Worker(bootstrap, options);
|
|
URL.revokeObjectURL(bootstrap);
|
|
return worker;
|
|
}
|
|
if (url.origin === globalThis.location.origin) return new Worker(url, options);
|
|
const source = "import " + JSON.stringify(url.href) + ";";
|
|
const bootstrap = URL.createObjectURL(new Blob([source], { type: "text/javascript" }));
|
|
const worker = new Worker(bootstrap, options);
|
|
URL.revokeObjectURL(bootstrap);
|
|
return worker;
|
|
}
|
|
${transformed}`;
|
|
return { contents, loader: path.extname(source) === ".ts" ? "ts" : "js" };
|
|
});
|
|
},
|
|
};
|
|
|
|
await Promise.all([
|
|
build({
|
|
...browser,
|
|
entryPoints: [path.join(root, "core", "index.js")],
|
|
outfile: path.join(output, "core.js"),
|
|
plugins: [workerURLs],
|
|
}),
|
|
build({
|
|
...browser,
|
|
entryPoints: [path.join(root, "addons", "handles", "src", "index.ts")],
|
|
external: ["@yawn/core"],
|
|
outfile: path.join(output, "handles.js"),
|
|
plugins: [workerURLs],
|
|
}),
|
|
build({
|
|
...browser,
|
|
entryPoints: [path.join(root, "addons", "fxnode_rg", "src", "index.ts")],
|
|
outfile: path.join(output, "fxnode-rg.js"),
|
|
plugins: [fxNodeImports],
|
|
}),
|
|
build({
|
|
...browser,
|
|
entryPoints: [path.join(fxNodeSource, "worker", "fxnode.worker.ts")],
|
|
outfile: path.join(output, "fxnode-worker.js"),
|
|
}),
|
|
fs.writeFile(path.join(output, "worker.js"), coreWorkerSource),
|
|
build({
|
|
...browser,
|
|
entryPoints: [
|
|
path.join(root, "addons", "handles", "src", "importers", "worker.ts"),
|
|
],
|
|
outfile: path.join(output, "importer-worker.js"),
|
|
}),
|
|
build({
|
|
...browser,
|
|
entryPoints: [
|
|
path.join(root, "addons", "handles", "src", "bvh", "worker.ts"),
|
|
],
|
|
outfile: path.join(output, "bvh-worker.js"),
|
|
}),
|
|
]);
|