UNPKG

winterspec

Version:

Write Winter-CG compatible routes with filesystem routing and tons of features

73 lines (72 loc) 2.44 kB
import Watcher from "watcher"; import * as esbuild from "esbuild"; import fs from "node:fs/promises"; import path from "node:path"; import { constructManifest } from "./construct-manifest.js"; import { getTempPathInApp } from "./get-temp-path-in-app.js"; import { isGitIgnored } from "globby"; /** * This does not directly provide a way to retrieve the contents or path of the bundle. You should provide a plugin in the `esbuild` option to do so. */ export const bundleAndWatch = async (options) => { const ignore = await isGitIgnored({ cwd: options.rootDirectory, }); const watcher = new Watcher(options.rootDirectory, { recursive: true, ignoreInitial: true, debounce: 0, ignore: (filePath) => { if (filePath.includes(".winterspec")) { return true; } // globby breaks when the path being tested is not within the current working directory (cwd/rootDirectory) if (!path.relative(options.rootDirectory, filePath).startsWith("..")) { return ignore(filePath); } return true; }, }); const tempDir = await getTempPathInApp(options.rootDirectory); const manifestPath = path.join(tempDir, "dev-manifest.ts"); const rebuildWithErrorHandling = async () => { try { await ctx?.rebuild(); } catch { // Error is ignored here because it's assumed the caller handles it in the build.onEnd() callback } }; const invalidateManifest = async () => { await fs.writeFile(manifestPath, await constructManifest(options), "utf-8"); await rebuildWithErrorHandling(); }; const ctx = await esbuild.context({ entryPoints: [manifestPath], bundle: true, format: "esm", write: false, sourcemap: "inline", logLevel: "silent", ...options.esbuild, }); await invalidateManifest(); watcher.on("change", async () => { await rebuildWithErrorHandling(); }); watcher.on("add", async () => { await invalidateManifest(); }); watcher.on("unlink", async () => { await invalidateManifest(); }); watcher.on("unlinkDir", async () => { await invalidateManifest(); }); return { stop: async () => { watcher.close(); await ctx.dispose(); }, }; };