UNPKG

@feoe/fs-router

Version:
699 lines (697 loc) 30.9 kB
import * as __WEBPACK_EXTERNAL_MODULE_unplugin__ from "unplugin"; import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path"; import * as __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__ from "node:fs/promises"; import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs"; import * as __WEBPACK_EXTERNAL_MODULE_glob__ from "glob"; const NESTED_ROUTE = { LAYOUT_FILE: 'layout', LAYOUT_CONFIG_FILE: 'layout.config', LAYOUT_LOADER_FILE: 'layout.loader', LAYOUT_DATA_FILE: 'layout.data', LAYOUT_CLIENT_LOADER: 'layout.data.client', PAGE_FILE: 'page', PAGE_CONFIG_FILE: 'page.config', PAGE_LOADER_FILE: 'page.loader', PAGE_DATA_FILE: 'page.data', PAGE_CLIENT_LOADER: 'page.data.client', SPLATE_FILE: '$', SPLATE_CONFIG_FILE: '$.config', SPLATE_LOADER_FILE: '$.loader', SPLATE_DATA_FILE: '$.data', SPLATE_CLIENT_DATA: '$.data.client', LOADING_FILE: 'loading', ERROR_FILE: 'error', LOADER_FILE: 'loader' }; const JS_EXTENSIONS = [ '.js', '.jsx', '.ts', '.tsx' ]; const getPathWithoutExt = (filepath)=>filepath.replace(/\.[^/.]+$/, ''); const hasAction = async (filepath)=>{ const content = await __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.promises.readFile(filepath, 'utf-8'); return content.includes('export const action') || content.includes('export let action'); }; const replaceWithAlias = (basePath, filePath, alias)=>{ const relativePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.relative(basePath, filePath); return __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(alias, relativePath); }; const normalizeToPosixPath = (str)=>str.replace(/\\/g, '/'); function _define_property(obj, key, value) { if (key in obj) Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); else obj[key] = value; return obj; } const conventionNames = Object.values(NESTED_ROUTE); class RouteExtractor { async extract() { const route = await this.walkDirectory(this.routesDir); if (!route) return []; return this.optimizeRoute(route); } async walkDirectory(dirname) { var _finalRoute_children; if (!await __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.promises.access(dirname).then(()=>true).catch(()=>false)) return null; const stats = await __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.promises.stat(dirname); if (!stats.isDirectory()) return null; const alias = this.alias; const relativeDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.relative(this.routesDir, dirname); const pathSegments = relativeDir.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.sep); const lastSegment = pathSegments[pathSegments.length - 1]; const isRoot = "" === lastSegment; const isPathlessLayout = lastSegment.startsWith("__"); const isWithoutLayoutPath = lastSegment.includes("."); let routePath = isRoot || isPathlessLayout ? "/" : `${lastSegment}`; if (isWithoutLayoutPath) routePath = lastSegment.split(".").join("/"); routePath = this.replaceDynamicPath(routePath); const route = { path: null == routePath ? void 0 : routePath.replace(/\$$/, "?"), children: [], isRoot, type: "nested" }; let pageLoaderFile = ""; let pageRoute = null; let pageConfigFile = ""; let pageClientData = ""; let pageData = ""; let pageAction = ""; let splatLoaderFile = ""; let splatRoute = null; let splatConfigFile = ""; let splatClientData = ""; let splatData = ""; let splatAction = ""; const entries = await __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.promises.readdir(dirname); for (const entry of entries){ const entryPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(dirname, entry); const entryPathWithAlias = getPathWithoutExt(replaceWithAlias(alias.basename, entryPath, alias.name)); const extname = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.extname(entry); const entryWithoutExt = entry.slice(0, -extname.length); const isDirectory = (await __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.promises.stat(entryPath)).isDirectory(); if (isDirectory) { const childRoute = await this.walkDirectory(entryPath); if (childRoute && !Array.isArray(childRoute)) { var _route_children; null === (_route_children = route.children) || void 0 === _route_children || _route_children.push(childRoute); } } if (!extname || !!JS_EXTENSIONS.includes(extname) && !!conventionNames.includes(entryWithoutExt)) { if (entryWithoutExt === NESTED_ROUTE.LAYOUT_LOADER_FILE) { if (!route.loader) route.loader = entryPathWithAlias; } if (entryWithoutExt === NESTED_ROUTE.LAYOUT_CLIENT_LOADER) route.clientData = entryPathWithAlias; if (entryWithoutExt === NESTED_ROUTE.LAYOUT_DATA_FILE) { route.data = entryPathWithAlias; if (await hasAction(entryPath)) route.action = entryPathWithAlias; } if (entryWithoutExt === NESTED_ROUTE.LAYOUT_CONFIG_FILE) { if (!route.config) route.config = entryPathWithAlias; } if (entryWithoutExt === NESTED_ROUTE.LAYOUT_FILE) route._component = entryPathWithAlias; if (entryWithoutExt === NESTED_ROUTE.PAGE_LOADER_FILE) pageLoaderFile = entryPathWithAlias; if (entryWithoutExt === NESTED_ROUTE.PAGE_CLIENT_LOADER) pageClientData = entryPathWithAlias; if (entryWithoutExt === NESTED_ROUTE.PAGE_DATA_FILE) { pageData = entryPathWithAlias; if (await hasAction(entryPath)) pageAction = entryPathWithAlias; } if (entryWithoutExt === NESTED_ROUTE.PAGE_CONFIG_FILE) pageConfigFile = entryPathWithAlias; if (entryWithoutExt === NESTED_ROUTE.PAGE_FILE) { var _route_children1; pageRoute = this.createIndexRoute({ _component: entryPathWithAlias }, entryPath); if (pageLoaderFile) pageRoute.loader = pageLoaderFile; if (pageConfigFile) pageRoute.config = pageConfigFile; if (pageData) pageRoute.data = pageData; if (pageClientData) pageRoute.clientData = pageClientData; if (pageAction) pageRoute.action = pageAction; null === (_route_children1 = route.children) || void 0 === _route_children1 || _route_children1.unshift(pageRoute); } if (entryWithoutExt === NESTED_ROUTE.SPLATE_LOADER_FILE) splatLoaderFile = entryPathWithAlias; if (entryWithoutExt === NESTED_ROUTE.SPLATE_CLIENT_DATA) splatClientData = entryPathWithAlias; if (entryWithoutExt === NESTED_ROUTE.SPLATE_CONFIG_FILE) { if (!route.config) splatConfigFile = replaceWithAlias(alias.basename, entryPath, alias.name); } if (entryWithoutExt === NESTED_ROUTE.SPLATE_DATA_FILE) { splatData = entryPathWithAlias; if (await hasAction(entryPath)) splatAction = entryPathWithAlias; } if (entryWithoutExt === NESTED_ROUTE.SPLATE_FILE) { var _route_children2; splatRoute = this.createRoute({ _component: entryPathWithAlias, path: "*" }, entryPath); if (splatLoaderFile) splatRoute.loader = splatLoaderFile; if (splatClientData) splatRoute.clientData = splatClientData; if (splatData) splatRoute.data = splatData; if (splatConfigFile) splatRoute.config = splatConfigFile; if (splatAction) splatRoute.action = splatAction; null === (_route_children2 = route.children) || void 0 === _route_children2 || _route_children2.push(splatRoute); } if (entryWithoutExt === NESTED_ROUTE.LOADING_FILE) route.loading = entryPathWithAlias; if (entryWithoutExt === NESTED_ROUTE.ERROR_FILE) route.error = entryPathWithAlias; } } let finalRoute = this.createRoute(route, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(dirname, `${NESTED_ROUTE.LAYOUT_FILE}.ts`)); if (isPathlessLayout) delete finalRoute.path; const childRoutes = finalRoute.children = null === (_finalRoute_children = finalRoute.children) || void 0 === _finalRoute_children ? void 0 : _finalRoute_children.filter((childRoute)=>childRoute); if (childRoutes && 0 === childRoutes.length && !finalRoute.index && !finalRoute._component) return null; if (childRoutes && 1 === childRoutes.length && !finalRoute._component) { const childRoute = childRoutes[0]; if ("*" === childRoute.path) { const path = `${finalRoute.path || ""}/${childRoute.path || ""}`; finalRoute = { ...childRoute, path }; } } if (isRoot && !finalRoute._component) throw new Error("The root layout component is required, make sure the routes/layout.tsx file exists."); return finalRoute; } optimizeRoute(routeTree) { var _routeTree_children; if (!(null === (_routeTree_children = routeTree.children) || void 0 === _routeTree_children ? void 0 : _routeTree_children.length)) return [ routeTree ]; if (!routeTree._component && !routeTree.error && !routeTree.loading && !routeTree.config && !routeTree.clientData) { const newRoutes = routeTree.children.map((child)=>{ const routePath = `${routeTree.path || ""}${child.path ? `/${child.path}` : ""}`; const newRoute = { ...child, path: routePath.replace(/\/\//g, "/") }; if (routePath.length > 0) delete newRoute.index; else delete newRoute.path; return newRoute; }); return Array.from(new Set(newRoutes)).flatMap((route)=>this.optimizeRoute(route)); } return [ { ...routeTree, children: routeTree.children.flatMap((child)=>this.optimizeRoute(child)) } ]; } replaceDynamicPath(routePath) { return routePath.replace(/\[(.*?)\]/g, ":$1"); } getRouteId(componentPath) { const relativePath = normalizeToPosixPath(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.relative(this.routesDir, componentPath)); const pathWithoutExt = getPathWithoutExt(relativePath); let id = ""; id = this.isMainEntry ? pathWithoutExt : `${this.entryName}_${pathWithoutExt}`; return id.replace(/\[(.*?)\]/g, "($1)"); } isValidFile(filename) { const ext = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.extname(filename); return this.extensions.includes(ext); } getRelativePath(filepath) { if (!this.alias) return __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.relative(this.routesDir, filepath); return getPathWithoutExt(replaceWithAlias(this.alias.basename, filepath, this.alias.name)); } createRoute(routeInfo, componentPath) { const id = this.getRouteId(componentPath); return { ...routeInfo, id, type: "nested" }; } createIndexRoute(routeInfo, componentPath) { return this.createRoute({ ...routeInfo, index: true, children: void 0 }, componentPath); } createSplatRoute(splatFile, splatLoader, splatConfig, splatClientData, splatData, splatAction) { return { path: "*", _component: splatFile, loader: splatLoader, config: splatConfig, clientData: splatClientData, data: splatData, action: splatAction }; } constructor(options){ _define_property(this, "routesDir", void 0); _define_property(this, "extensions", JS_EXTENSIONS); _define_property(this, "entryName", void 0); _define_property(this, "isMainEntry", void 0); _define_property(this, "alias", void 0); this.routesDir = options.routesDir; this.entryName = options.entryName || "main"; this.isMainEntry = options.isMainEntry ?? true; this.alias = options.alias || { name: "", basename: "" }; } } function generator_define_property(obj, key, value) { if (key in obj) Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); else obj[key] = value; return obj; } class RouteCodeGenerator { generate(routes) { const routeCode = this.generateRouteCode(routes); return this.wrapWithImports(routeCode); } generateRouteCode(routes) { const code = `export const routes = [ ${routes.map((route)=>this.stringifyRoute(route)).join(",\n ")} ];`; return JSON.parse(JSON.stringify(code, null, 2)); } stringifyRoute(route) { var _route_children; const element = this.generateElementCode(route); const errorElement = this.generateErrorElement(route); const loader = this.generateLoaderCode(route); const action = this.generateActionCode(route); const routeObj = { path: route.path, index: route.index, errorElement: errorElement || void 0, loader: loader || void 0, element: element || void 0, action: action || void 0, children: void 0 }; const childrenStr = (null === (_route_children = route.children) || void 0 === _route_children ? void 0 : _route_children.length) ? `children: [${route.children.map((child)=>this.stringifyRoute(child)).join(",")}]` : ""; const routeEntries = Object.entries(routeObj).filter(([_, value])=>void 0 !== value).map(([key, value])=>{ if ("path" === key) return `${key}: '${value}'`; if ("element" === key) ; return `${key}: ${value}`; }); if (childrenStr) routeEntries.push(childrenStr); return `{ ${routeEntries.join(",\n ")} }`; } generateElementCode(route) { if (!route._component) return ""; const chunkName = route.id || __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.basename(route._component, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.extname(route._component)); if (route.isRoot) { this.runtimeImports.add(`import RootLayout from '${route._component}';`); return "<RootLayout />"; } if (this.options.splitting) { const importPath = route._component; const componentName = `Component_${this.componentDeclarations.size}`; let loadingComponent = ''; if (route.loading) { const loadingName = `Loading_${this.loadingImports.size}`; this.loadingImports.add(`import ${loadingName} from '${route.loading}';`); loadingComponent = `, { fallback: <${loadingName} /> }`; } this.componentDeclarations.add(`const ${componentName} = loadable(() => import(/* webpackChunkName: "${chunkName}" */ '${importPath}')${loadingComponent});`); return `<${componentName} />`; } const componentName = `Component_${this.componentDeclarations.size}`; this.componentDeclarations.add(`import ${componentName} from '${route._component}';`); return `<${componentName} />`; } generateErrorElement(route) { if (!route.error) return ""; const errorName = `Error_${this.errorImports.size}`; this.errorImports.add(`import ${errorName} from '${route.error}';`); return `<${errorName} />`; } generateActionCode(route) { if (!route.action) return ""; const actionName = `action_${this.loaderImports.size}`; this.loaderImports.add(`import ${actionName} from '${route.action}';`); return actionName; } generateConfigCode(route) { if (!route.config) return ""; const configName = `config_${this.configImports.size}`; this.configImports.add(`import * as ${configName} from '${route.config}';`); return configName; } generateLoaderCode(route) { const loaders = []; if (route.data) { const loaderName = `loader_${this.loaderImports.size}`; this.loaderImports.add(`import { loader as ${loaderName}${route.action ? `, action as ${loaderName}_action` : ""} } from '${route.data}';`); loaders.push(loaderName); } if (route.clientData) { const clientDataName = `clientData_${this.loaderImports.size}`; this.loaderImports.add(`import { loader as ${clientDataName} } from '${route.clientData}';`); loaders.push(clientDataName); } if (route.loader) { const loaderName = `loader_${this.loaderImports.size}`; this.loaderImports.add(`import ${loaderName} from '${route.loader}';`); loaders.push(loaderName); } if (0 === loaders.length) return ""; if (loaders.length > 1) return `async (...args) => { const [${loaders.join(", ")}] = await Promise.all([${loaders.map((l)=>`${l}(...args)`).join(", ")}]); return { ...${loaders.join(", ...")} }; }`; return loaders[0]; } wrapWithImports(routeCode) { const runtimeImports = [ ...Array.from(this.runtimeImports), ...Array.from(this.loaderImports), ...Array.from(this.configImports), ...Array.from(this.loadingImports), ...Array.from(this.errorImports) ]; return ` ${runtimeImports.join("\n")} ${this.componentDeclarations.size ? Array.from(this.componentDeclarations).join("\n") : ""} ${routeCode}`; } constructor(options){ generator_define_property(this, "options", void 0); generator_define_property(this, "runtimeImports", new Set([ "import loadable from '@loadable/component';" ])); generator_define_property(this, "loaderImports", new Set()); generator_define_property(this, "loadingImports", new Set()); generator_define_property(this, "errorImports", new Set()); generator_define_property(this, "configImports", new Set()); generator_define_property(this, "componentDeclarations", new Set()); this.options = { splitting: true, ...options }; } } function pathParser(path) { const normalizedPath = path.replace(/^\/+|\/+$/g, ""); const pathWithoutExt = normalizedPath.replace(/\.[jt]sx?$/, ""); const pathSegments = pathWithoutExt.split("/"); const params = []; const processedSegments = pathSegments.filter((segment)=>!segment.startsWith("(") && !segment.endsWith(")") && !segment.startsWith("__")).map((segment)=>{ const optionalMatch = segment.match(/^\[([.\w]+)\$\]$/); if (optionalMatch) { const name = optionalMatch[1]; params.push({ name, optional: true }); return `:${name}?`; } if ("$" === segment) { params.push({ name: "*", optional: false }); return "*"; } const optionalBracketMatch = segment.match(/^\[\[([.\w]+)\]\]$/); if (optionalBracketMatch) { const name = optionalBracketMatch[1]; if (name.startsWith("...")) { params.push({ name: "*", optional: true }); return "*?"; } params.push({ name, optional: true }); return `:${name}?`; } const requiredMatch = segment.match(/^\[([.\w]+)\]$/); if (requiredMatch) { const name = requiredMatch[1]; if (name.startsWith("...")) { params.push({ name: "*", optional: false }); return "*"; } params.push({ name }); return `:${name}`; } return segment; }); if ("page" === processedSegments[processedSegments.length - 1]) processedSegments.pop(); return { route: processedSegments.join("/"), params }; } const GlobPattern = "**/page.{jsx,tsx}"; async function generateRouteType(options) { const { routesTypeFile, routesDirectories = [] } = options; const allFiles = []; for (const route of routesDirectories){ const relatedFiles = await (0, __WEBPACK_EXTERNAL_MODULE_glob__.glob)(GlobPattern, { cwd: route.path }); allFiles.push(...relatedFiles.map((file)=>route.prefix ? __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(route.prefix, file) : file)); } const routeTypes = allFiles.map((path)=>{ const { route, params } = pathParser(path); return { route: route.startsWith("/") ? route : `/${route}`, params }; }); const routeTypesContent = [ 'declare module "@feoe/fs-router" {', " interface RouteTypes {", ...routeTypes.map((routeType)=>` "${routeType.route}": {};`), " }", " };", "export {};" ].join("\n"); __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(routesTypeFile, routeTypesContent); } async function generator_generator(config) { const extractor = new RouteExtractor({ routesDir: config.routesDirectory, alias: config.alias }); const routes = await extractor.extract(); const generator = new RouteCodeGenerator({ splitting: config.splitting }); const code = generator.generate(routes); if (config.enableGeneration) { await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__.mkdir(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.dirname(config.generatedRoutesPath), { recursive: true }); await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__.writeFile(config.generatedRoutesPath, code, "utf-8"); } if (config.typeGenerateOptions) { const { routesTypeFile, routesDirectories = [] } = config.typeGenerateOptions; if (routesDirectories.length > 0) await generateRouteType({ routesTypeFile, routesDirectories }); } return code; } const defaultConfig = { routesDirectory: "src/routes", generatedRoutesPath: "src/routes.tsx", routeExtensions: [ ".js", ".jsx", ".ts", ".tsx" ], splitting: true, alias: { name: "@", basename: "src" }, enableGeneration: true, defaultErrorBoundary: false, typeGenerateOptions: { routesTypeFile: "src/routes-type.ts", generateRouteParams: true, generateLoaderTypes: true, routesDirectories: [] } }; const getConfig = (options, root)=>{ const config = { ...defaultConfig, ...options }; config.routesDirectory = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.isAbsolute)(config.routesDirectory) ? config.routesDirectory : (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve)(root, config.routesDirectory); config.generatedRoutesPath = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.isAbsolute)(config.generatedRoutesPath) ? config.generatedRoutesPath : (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve)(root, config.generatedRoutesPath); if (config.typeGenerateOptions) { const { routesTypeFile } = config.typeGenerateOptions; config.typeGenerateOptions.routesTypeFile = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.isAbsolute)(routesTypeFile) ? routesTypeFile : (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve)(root, routesTypeFile); } return config; }; const PLUGIN_NAME = "unplugin:file-based-router-generator"; const unpluginRouterGeneratorFactory = (userOptions = {})=>{ const ctx = { root: process.cwd(), config: getConfig(userOptions, process.cwd()), watcher: null, lock: false, generated: false }; const getRoutesDirectoryPath = ()=>(0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.isAbsolute)(ctx.config.routesDirectory) ? ctx.config.routesDirectory : (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join)(ctx.root, ctx.config.routesDirectory); const generate = async ()=>{ if (ctx.lock) return; ctx.lock = true; try { const content = await generator_generator(ctx.config); ctx.generated = true; return content; } catch (err) { console.error(`❌ [${PLUGIN_NAME}] Route generation failed:`, err); return "export const routes = [];"; } finally{ ctx.lock = false; } }; const run = async (cb)=>{ if (ctx.config.enableGeneration ?? true) await cb(); }; const handleFile = async (file, event)=>{ const filePath = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.normalize)(file); if ("update" === event && filePath === (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve)(ctx.config.generatedRoutesPath)) return; const routesDirectoryPath = getRoutesDirectoryPath(); const relative = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(routesDirectoryPath, filePath); const fileInRoutesDirectory = "" !== relative && !relative.startsWith(".."); if (fileInRoutesDirectory) await run(generate); }; const setupWatcher = async ()=>{ const { watch } = await import("chokidar"); const routesDirectoryPath = getRoutesDirectoryPath(); const watchOptions = { ignored: [ /(^|[\/\\])\../, "node_modules", "**/*.d.ts", "**/styles/**", "**/*.css", "**/*.less", "**/*.sass", "**/*.scss" ], ignoreInitial: true, ignorePermissionErrors: true }; ctx.watcher = watch(routesDirectoryPath, watchOptions); const debounce = (fn, delay)=>{ let timeout; return (...args)=>{ clearTimeout(timeout); timeout = setTimeout(()=>fn(...args), delay); }; }; const debouncedGenerate = debounce(()=>run(generate), 300); ctx.watcher.on("add", debouncedGenerate).on("unlink", debouncedGenerate).on("change", debouncedGenerate).on("error", (error)=>{ console.error(`❌ [${PLUGIN_NAME}] Watcher error:`, error); }); }; return { name: PLUGIN_NAME, buildStart () { ctx.config = getConfig(userOptions, ctx.root); if (!(0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.isAbsolute)(ctx.config.routesDirectory)) ctx.config.routesDirectory = (0, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.resolve)(ctx.root, ctx.config.routesDirectory); }, async watchChange (id, { event }) { await run(async ()=>{ await handleFile(id, event); }); }, vite: { async configResolved (config) { ctx.root = config.root; ctx.config = getConfig(userOptions, ctx.root); await run(generate); }, configureServer () { return ()=>{ console.info(`✅ [${PLUGIN_NAME}] Routes generated successfully`); }; }, handleHotUpdate ({ file }) { if (file.startsWith(ctx.config.routesDirectory)) return []; } }, webpack (compiler) { if ("production" === compiler.options.mode) { compiler.hooks.beforeRun.tapPromise(PLUGIN_NAME, async ()=>{ await run(generate); }); compiler.hooks.done.tap(PLUGIN_NAME, ()=>{ console.info(`✅ ${PLUGIN_NAME}: Routes generated successfully`); setTimeout(()=>{ process.exit(0); }); }); } else { setupWatcher(); let generated = false; compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, async ()=>{ if (!generated) { generated = true; return run(generate); } }); } }, rspack (compiler) { if ("production" === compiler.options.mode) { compiler.hooks.beforeRun.tapPromise(PLUGIN_NAME, async ()=>{ await run(generate); }); compiler.hooks.done.tap(PLUGIN_NAME, ()=>{ console.info(`✅ [${PLUGIN_NAME}] Routes generated successfully`); }); } else { setupWatcher(); let generated = false; compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, async ()=>{ if (!generated) { generated = true; return run(generate); } }); } }, async buildEnd () { if (ctx.watcher) { await ctx.watcher.close(); ctx.watcher = null; } } }; }; const FileBasedRouterRspack = (0, __WEBPACK_EXTERNAL_MODULE_unplugin__.createRspackPlugin)(unpluginRouterGeneratorFactory); const rspack_rslib_entry_ = FileBasedRouterRspack; export { FileBasedRouterRspack, rspack_rslib_entry_ as default };