UNPKG

@vaadin/hilla-file-router

Version:

Hilla file-based router

83 lines 3.27 kB
import { basename } from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; import { generateRuntimeFiles } from "./vite-plugin/generateRuntimeFiles.js"; const INJECTION = "if (Object.keys(nextExports).length === 2 && 'default' in nextExports && 'config' in nextExports) {nextExports = { ...nextExports, config: currentExports.config };}"; /** * A Vite plugin that generates a router from the files in the specific directory. * * @param options - The plugin options. * @returns A Vite plugin. */ export default function vitePluginFileSystemRouter({ viewsDir = "frontend/views/", generatedDir = "frontend/generated/", extensions = [".tsx", ".jsx"], isDevMode = false, debug = false } = {}) { let _viewsDir; let _outDir; let _logger; let runtimeUrls; return { name: "vite-plugin-file-router", configResolved({ logger, root, build: { outDir } }) { const _root = pathToFileURL(root); const _generatedDir = new URL(generatedDir, _root); _viewsDir = new URL(viewsDir, _root); _outDir = pathToFileURL(outDir); _logger = logger; if (debug) { _logger.info(`The directory of route files: ${String(_viewsDir)}`); _logger.info(`The directory of generated files: ${String(_generatedDir)}`); _logger.info(`The output directory: ${String(_outDir)}`); } runtimeUrls = { json: new URL("file-routes.json", isDevMode ? _generatedDir : _outDir), code: new URL("file-routes.ts", _generatedDir), layouts: new URL("layouts.json", _generatedDir) }; }, async buildStart() { try { await generateRuntimeFiles(_viewsDir, runtimeUrls, extensions, _logger, debug); } catch (e) { _logger.error(String(e)); } }, configureServer(server) { const dir = fileURLToPath(_viewsDir); const changeListener = (file) => { if (!file.startsWith(dir)) { if (file === fileURLToPath(runtimeUrls.json)) { server.hot.send({ type: "custom", event: "fs-route-update" }); } else if (file !== fileURLToPath(runtimeUrls.layouts)) { return; } } generateRuntimeFiles(_viewsDir, runtimeUrls, extensions, _logger, debug).catch((e) => _logger.error(String(e))); }; server.watcher.on("add", changeListener); server.watcher.on("change", changeListener); server.watcher.on("unlink", changeListener); }, transform(code, id) { let modifiedCode = code; const viewsDirUsingSlashes = fileURLToPath(_viewsDir).replaceAll("\\", "/"); if (id.startsWith(viewsDirUsingSlashes) && !basename(id).startsWith("_")) { if (isDevMode) { const injectionPattern = /import\.meta\.hot\.accept[\s\S]+if\s\(!nextExports\)\s+return;/gu; if (injectionPattern.test(modifiedCode)) { modifiedCode = `${modifiedCode.substring(0, injectionPattern.lastIndex)}${INJECTION}${modifiedCode.substring(injectionPattern.lastIndex)}`; } } else { const functionNames = /export\s+default\s+(?:function\s+)?(\w+)/u.exec(modifiedCode); if (functionNames?.length) { const [, functionName] = functionNames; modifiedCode += `Object.defineProperty(${functionName}, 'name', { value: '${functionName}' });\n`; } } return { code: modifiedCode }; } return undefined; } }; } //# sourceMappingURL=./vite-plugin.js.map