Page MenuHomeSealhub

build.ts
No OneTemporary

build.ts

import { build, BuildContext, BuildResult, context } from "esbuild";
import { promises as fs } from "fs";
import { extname } from "path";
import * as chokidar from "chokidar";
import { default as glob } from "tiny-glob";
import { generate_css_includes } from "./find-css-includes";
import { sleep } from "./utils/sleep";
import { generateCollections } from "./generate-collections";
import { generateRoutes } from "./generate-routes";
import { generateComponents } from "./generate-components";
import { make_notifier } from "./notifier";
const generate_names = (function* generate_names() {
const base_name = "____unique_import_";
let count = 0;
while (true) {
yield `${base_name}${count}`;
count++;
}
})();
async function build_ts() {
await Promise.all([
generateCollections(),
generateRoutes(),
generateComponents(),
]);
const entryPoints = (await glob("./src/back/**/*.{ts,tsx}")).filter(
(path) => !path.includes(".#")
);
try {
await build({
entryPoints,
sourcemap: true,
bundle: false,
jsxFactory: "TempstreamJSX.createElement",
outdir: "./dist/back",
logLevel: "info",
platform: "node",
target: "es2022",
format: "esm",
plugins: [
{
name: "remove-named-imports", // named imports sometime cause some esm incompatibilities, like the "is a CommonJS module, which may not support all module.exports as named exports." error
setup(build) {
build.onLoad({ filter: /.*/ }, async ({ path }) => {
const named_and_default_regex =
/^import\s+((\S+),\s+)?({\s*[^}]+})\s+from\s+("[^"]+");\s*$/gm;
const old_content = await fs.readFile(
path,
"utf-8"
);
const contents = old_content.replace(
named_and_default_regex,
(
_,
default_import_name,
__,
all_named,
module_path
) => {
/* eslint-disable */
const new_name =
generate_names.next().value;
const result =
`import * as ${new_name} from ${module_path}${
default_import_name
? `; const ${default_import_name.replace(
",",
""
)} = ${new_name}.default || ${new_name};`
: ""
};` +
all_named
.match(/[a-zA-Z_$][^,}]+/g)
.map((importname: string) => {
if (
importname.startsWith(
"default as"
)
) {
return `const ${importname.replace(
"default as ",
""
)} = ${new_name}?.default || ${new_name};`;
}
if (
importname.match(
/([^{]*)\sas\s([^}]*)/
)
) {
// is "import {asdfas as somethong_else}
const [_, original, named] =
importname.match(
/([^{]*)\sas\s([^}]*)/
) as string[];
return `const named = ${new_name}?.default.${original} || ${new_name}?.${original}`;
}
return `const ${importname} = ${new_name}?.default?.${importname} || ${new_name}?.${importname};`;
})
.join(" ");
return result;
/* eslint-enable */
}
);
return {
contents,
loader: extname(path) === ".tsx" ? "tsx" : "ts",
};
});
},
},
],
});
} catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
console.error(e.message);
}
}
async function complex_build(watch: boolean): Promise<void> {
const loader = Object.fromEntries(
(<const>["png", "svg", "jpg", "gif", "jpeg", "otf", "ttf"]).map(
(ext) => <const>["." + ext, "file"]
)
);
let css_build: BuildContext = await context({
entryPoints: ["./src/main.css"],
sourcemap: true,
bundle: true,
outdir: "./public/dist",
logLevel: "info",
// plugins: [sassPlugin()],
loader,
});
let ongoing_ts = false;
let ongoing_css = false;
if (watch) {
const watcher = chokidar.watch("src", { ignoreInitial: true });
const notifier = make_notifier(60808);
watcher.on("all", async (_, path) => {
if (!css_build) return;
if (path.includes(".#")) return;
if (path.endsWith(".css") && !path.endsWith("/includes.css")) {
if (ongoing_css) {
return;
}
ongoing_css = true;
// refresh the list of all css files in includes.css
await generate_css_includes();
try {
await css_build?.rebuild?.();
console.log(`Built main.css [on ${path}]`);
} catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
console.error(e.message);
await sleep(200);
css_build
?.rebuild?.()
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
.catch((e) => console.error(e?.message));
}
notifier("css");
ongoing_css = false;
}
if (
(path.endsWith(".ts") || path.endsWith(".tsx")) &&
!path.endsWith("src/back/collections/collections.ts") &&
!path.endsWith("src/back/routes/routes.ts") &&
!path.endsWith("src/back/routes/urls.ts")
) {
if (ongoing_ts) {
return;
}
ongoing_ts = true;
await build_ts();
console.log(`Finished TS build [on ${path}]`);
ongoing_ts = false;
}
});
}
await generate_css_includes();
await Promise.all([css_build.rebuild(), build_ts()]);
watch && css_build?.rebuild?.();
}
export async function buildProject({
watch,
}: {
watch: boolean;
}): Promise<void> {
try {
await build({
entryPoints: ["./src/front/index.ts"],
sourcemap: true,
outfile: "./public/dist/bundle.js",
logLevel: "info",
bundle: true,
});
await complex_build(watch);
} catch (e) {
console.log("CAUGHT!");
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
console.error(e.message);
}
}

File Metadata

Mime Type
text/x-java
Expires
Tue, Jul 8, 07:52 (23 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
809350
Default Alt Text
build.ts (5 KB)

Event Timeline