universal-autorouter-hono
Version:
An plugin for [Hono](https://hono.dev) to add HMR (Hot Module Replacement) to Hono routes development.
66 lines (63 loc) • 2.63 kB
JavaScript
import path from 'node:path';
import autoloadRoutes, { toPosix, DEFAULT_METHOD, DEFAULT_ROUTES_DIR, filepathToRoute } from 'universal-autorouter';
var index = async (app, options) => {
const {
prefix = "",
defaultMethod = DEFAULT_METHOD,
routesDir = DEFAULT_ROUTES_DIR,
viteDevServer,
externalDirs
} = options;
const entryDir = path.isAbsolute(routesDir) ? toPosix(routesDir) : path.posix.join(process.cwd(), routesDir);
app.use(`${prefix}/*`, async (c, next) => {
const { incoming: { method, url } } = c.env;
const handler = app.hmrRoutes[`${method}${url.split("?")[0]}`];
if (handler) {
return await handler(c);
}
await next();
});
await autoloadRoutes(app, options);
app.hmrRoutes = {};
app.injectHandler = function(method, route, handler) {
app.hmrRoutes[`${method.toUpperCase()}${route}`] = handler;
};
const updateHandler = async (filepath) => {
const { default: handler } = await viteDevServer.ssrLoadModule(filepath, { fixStacktrace: true });
const relativeFilepath = filepath.replace(entryDir, "");
const matchedFile = relativeFilepath.match(/\/?\((.*?)\)/);
const method = matchedFile ? matchedFile[1] : defaultMethod;
const route = `${prefix}${filepathToRoute(relativeFilepath)}`;
app.injectHandler(method, route, handler);
};
const externalDirsPaths = externalDirs?.map((dir) => path.isAbsolute(dir) ? toPosix(dir) : path.posix.join(process.cwd(), dir));
const updateExternal = async (filepath) => {
if (externalDirsPaths && !externalDirsPaths.some((dir) => filepath.startsWith(dir))) {
return;
}
const dependentModules = viteDevServer.moduleGraph.getModulesByFile(filepath) || [];
for (const mod of dependentModules) {
for (const importer of mod.importers) {
const importerFile = importer.file;
if (importerFile) {
await (importerFile.startsWith(entryDir) ? updateHandler(importerFile) : updateExternal(importerFile));
}
}
}
};
const log = (type, filepath) => {
viteDevServer.config.logger.info(`\x1B[2m${(/* @__PURE__ */ new Date()).toLocaleTimeString()}\x1B[22m \x1B[36m[autorouter]\x1B[39m \x1B[32mHMR update ${type}\x1B[39m \x1B[2m${filepath.replace(viteDevServer.config.root, ".")}\x1B[22m`);
};
viteDevServer.watcher.on("change", async (file) => {
const filepath = toPosix(file);
if (filepath.startsWith(entryDir)) {
await updateHandler(filepath);
log("route", filepath);
} else {
await updateExternal(filepath);
log("file", filepath);
}
});
return app;
};
export { index as default };