sitegen/framework/esbuild-support.ts

118 lines
3 KiB
TypeScript
Raw Normal View History

2025-08-01 20:16:21 -07:00
type Awaitable<T> = T | Promise<T>;
2025-07-07 20:58:02 -07:00
export function virtualFiles(
2025-08-01 20:16:21 -07:00
map: Record<string, string | esbuild.OnLoadResult | (() => Awaitable<string | esbuild.OnLoadResult>)>,
2025-07-07 20:58:02 -07:00
) {
return {
name: "clover vfs",
setup(b) {
b.onResolve(
{
filter: new RegExp(
`^(?:${
Object.keys(map).map((file) => string.escapeRegExp(file)).join(
"|",
)
})\$`,
),
},
({ path }) => ({ path, namespace: "vfs" }),
);
b.onLoad(
{ filter: /./, namespace: "vfs" },
2025-08-01 20:16:21 -07:00
async ({ path }) => {
let entry = map[path];
if (typeof entry === 'function') entry = await entry();
2025-07-07 20:58:02 -07:00
return ({
resolveDir: ".",
loader: "ts",
...typeof entry === "string" ? { contents: entry } : entry,
});
},
);
},
} satisfies esbuild.Plugin;
}
export function banFiles(
files: string[],
) {
return {
name: "clover vfs",
setup(b) {
b.onResolve(
{
filter: new RegExp(
`^(?:${
files.map((file) => string.escapeRegExp(file)).join("|")
})\$`,
),
},
({ path, importer }) => {
throw new Error(
`Loading ${path} (from ${importer}) is banned!`,
);
},
);
},
} satisfies esbuild.Plugin;
}
export function projectRelativeResolution(root = process.cwd() + "/src") {
return {
name: "project relative resolution ('@/' prefix)",
setup(b) {
b.onResolve({ filter: /^@\// }, ({ path: id }) => {
return {
path: path.resolve(root, id.slice(2)),
};
});
b.onResolve({ filter: /^#/ }, ({ path: id, importer }) => {
return {
path: hot.resolveFrom(importer, id),
};
});
},
} satisfies esbuild.Plugin;
}
2025-07-31 21:35:36 -07:00
export function markoViaBuildCache(): esbuild.Plugin {
return {
name: "marko via build cache",
setup(b) {
b.onLoad(
{ filter: /\.marko$/ },
async ({ path: file }) => {
const cacheEntry = markoCache.get(file);
if (!cacheEntry) {
if (!fs.existsSync(file)) {
console.warn(`File does not exist: ${file}`);
}
console.log(markoCache.keys());
throw new Error("Marko file not in cache: " + file);
}
return ({
loader: "ts",
contents: cacheEntry.src,
resolveDir: path.dirname(file),
});
},
);
},
};
}
2025-08-01 20:16:21 -07:00
export function isIgnoredSource(source: string) {
return source.includes("<define:") ||
source.startsWith("vfs:") ||
source.startsWith("dropped:") ||
source.includes("node_modules")
}
2025-07-07 20:58:02 -07:00
import * as esbuild from "esbuild";
import * as string from "#sitegen/string";
import * as path from "node:path";
2025-07-31 21:35:36 -07:00
import * as fs from "#sitegen/fs";
import * as incr from "./incremental.ts";
import * as hot from "./hot.ts";import { markoCache } from "./marko.ts";