waforth/build-web.js

173 lines
5.3 KiB
JavaScript
Raw Normal View History

2022-04-13 17:02:46 +02:00
#!/usr/bin/env node
/* eslint-env node */
2022-07-06 19:33:18 +02:00
/* eslint @typescript-eslint/no-var-requires:0 */
2022-04-13 17:02:46 +02:00
const esbuild = require("esbuild");
const path = require("path");
const fs = require("fs");
const { createServer } = require("http");
2022-11-20 08:47:27 +01:00
const { withWatcher } = require("./scripts/esbuild/watcher");
2022-04-14 08:53:53 +02:00
const { wasmTextPlugin } = require("./scripts/esbuild/wasm-text");
2022-04-13 17:02:46 +02:00
let dev = false;
let watch = false;
for (const arg of process.argv.slice(2)) {
switch (arg) {
case "--development":
dev = true;
break;
case "--watch":
watch = true;
break;
}
}
let buildConfig = {
bundle: true,
logLevel: "info",
entryPoints: [
2022-04-17 09:28:53 +02:00
path.join(__dirname, "src", "web", "shell", "shell"),
path.join(__dirname, "src", "web", "tests", "tests"),
path.join(__dirname, "src", "web", "benchmarks", "benchmarks"),
path.join(__dirname, "src", "web", "examples", "prompt", "prompt"),
2022-05-13 21:48:29 +02:00
path.join(__dirname, "src", "web", "examples", "fetch", "fetch"),
2022-05-08 18:46:50 +02:00
path.join(__dirname, "src", "web", "thurtle", "thurtle"),
2022-04-13 17:02:46 +02:00
],
entryNames: dev ? "[name]" : "[name]-c$[hash]",
assetNames: "[name]-c$[hash]",
// target: "es6",
outdir: path.join(__dirname, "public/waforth/dist"),
2022-05-08 18:46:50 +02:00
publicPath: "/waforth/dist",
2022-12-18 16:24:35 +01:00
external: ["fs", "stream", "util", "events", "path"],
2022-04-13 17:02:46 +02:00
minify: !dev,
loader: {
".wasm": "binary",
".js": "jsx",
2022-05-08 18:46:50 +02:00
".fs": "text",
".f": "text",
2022-05-27 19:43:34 +02:00
".fr": "text",
".fth": "text",
2022-05-08 18:46:50 +02:00
".svg": "file",
2022-04-13 17:02:46 +02:00
},
2022-04-18 14:41:52 +02:00
define: {
WAFORTH_VERSION: watch
? `"dev"`
2022-05-06 20:57:00 +02:00
: // : `"${new Date().toISOString().replace(/T.|)}>#g, "")}"`,
JSON.stringify(JSON.parse(fs.readFileSync("package.json")).version),
2022-04-18 14:41:52 +02:00
},
2022-04-13 17:02:46 +02:00
sourcemap: true,
metafile: true,
plugins: [
wasmTextPlugin({ debug: true }),
// Resolve 'waforth' to the main entrypoint (for examples)
{
name: "waforth",
setup: (build) => {
build.onResolve({ filter: /^waforth$/ }, () => {
return { path: path.join(__dirname, "src", "web", "waforth.ts") };
});
},
},
],
2022-04-13 17:02:46 +02:00
};
const INDEX_TEMPLATE = `<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
2022-05-05 22:35:34 +02:00
<link rel="shortcut icon" href="/waforth/favicon.ico" type="image/x-icon" />
<link rel="icon" href="/waforth/favicon.ico" type="image/x-icon" />
2022-10-02 11:04:01 +02:00
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="/waforth/apple-touch-icon.png" />
2022-04-13 17:02:46 +02:00
<link href="/waforth/dist/$BASE.css" rel="stylesheet" />
2022-05-10 22:45:17 +02:00
<title>$TITLE</title>
2022-04-13 17:02:46 +02:00
</head>
<body>
<script type="text/javascript" src="/waforth/dist/$BASE.js"></script>
</body>
</html>
`;
async function handleBuildFinished(result) {
2022-05-08 18:44:03 +02:00
const indexes = [
2022-05-10 22:45:17 +02:00
["WAForth", "shell", "public/waforth"],
["WAForth Tests", "tests", "public/waforth/tests"],
["WAForh Benchmarks", "benchmarks", "public/waforth/benchmarks"],
["WAForth Prompt Example", "prompt", "public/waforth/examples/prompt"],
2022-05-13 21:48:29 +02:00
["WAForth Fetch Example", "fetch", "public/waforth/examples/fetch"],
2023-03-18 09:30:15 +01:00
["Thurtle", "thurtle", "public/waforth/thurtle", true],
2022-05-08 18:44:03 +02:00
];
2022-05-10 22:45:17 +02:00
for (const [title, base, outpath, bs] of indexes) {
let index = INDEX_TEMPLATE.replace(/\$BASE/g, base).replace(
/\$TITLE/g,
title
);
2022-05-08 18:46:50 +02:00
if (bs) {
index = index.replace(
"<body>",
`<body>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
`
);
}
2022-05-08 18:44:03 +02:00
for (const [out] of Object.entries(result.metafile.outputs)) {
const outfile = path.basename(out);
const sourcefile = outfile.replace(/-c\$[^.]+\./, ".");
// console.log("%s -> %s", sourcefile, outfile);
index = index.replace(`/${sourcefile}`, `/${outfile}`);
}
await fs.promises.mkdir(outpath, { recursive: true });
await fs.promises.writeFile(path.join(outpath, "index.html"), index);
2022-04-13 17:02:46 +02:00
}
}
if (watch) {
2022-04-13 22:20:57 +02:00
// Simple static file server
2022-04-15 15:28:48 +02:00
createServer(async function (req, res) {
2022-05-20 20:30:56 +02:00
const url = req.url.replace(/\?.*/g, "");
let f = path.join(__dirname, "public", url);
2022-04-17 15:46:42 +02:00
try {
if ((await fs.promises.lstat(f)).isDirectory()) {
f = path.join(f, "index.html");
}
} catch (e) {
// pass
2022-04-13 22:20:57 +02:00
}
2022-04-15 15:28:48 +02:00
try {
const data = await fs.promises.readFile(f);
2022-05-08 18:46:50 +02:00
res.writeHead(
200,
2022-05-20 20:30:56 +02:00
url.endsWith(".svg")
2022-05-08 18:46:50 +02:00
? {
"Content-Type": "image/svg+xml",
}
: undefined
);
2022-04-13 22:20:57 +02:00
res.end(data);
2022-04-15 15:28:48 +02:00
} catch (err) {
res.writeHead(404);
res.end(JSON.stringify(err));
}
2022-04-13 17:02:46 +02:00
}).listen(8080);
2022-04-13 22:20:57 +02:00
2022-04-13 17:02:46 +02:00
console.log("listening on port 8080");
buildConfig = withWatcher(buildConfig, handleBuildFinished, 8081);
}
2022-04-15 15:28:48 +02:00
2022-05-05 22:35:34 +02:00
(async () => {
await fs.promises.mkdir("public/waforth", { recursive: true });
await fs.promises.copyFile(
"public/favicon.ico",
"public/waforth/favicon.ico"
);
try {
handleBuildFinished(await esbuild.build(buildConfig));
} catch (e) {
process.exit(1);
}
})();