UNPKG

@fourcels/vite-plugin-react-pages

Version:
139 lines (136 loc) 4.02 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // plugin/route.ts import fs from "node:fs"; import path from "node:path/posix"; var RouteData = class { constructor(options) { __publicField(this, "path"); __publicField(this, "lazy"); __publicField(this, "index"); __publicField(this, "children"); const { path: path2, lazy, index, children } = options; this.path = path2; this.lazy = lazy; this.index = index; this.children = children; } toString() { const res = []; res.push("{"); if (this.path) { res.push(`path: "${this.path}",`); } if (this.lazy) { res.push(`lazy: () => import("${this.lazy}"),`); } if (this.index) { res.push(`index: ${this.index},`); } if (this.children) { res.push(`children: [${this.children}],`); } res.push("}"); return res.join("\n"); } }; var Route = class _Route { constructor(baseDir, pathName = "/") { __publicField(this, "path"); __publicField(this, "page"); __publicField(this, "layout"); __publicField(this, "notFound"); __publicField(this, "children", []); this.path = pathName; const dirents = fs.readdirSync(baseDir, { withFileTypes: true }); for (const dirent of dirents) { const filePath = path.join(baseDir, dirent.name); if (dirent.isDirectory() && !dirent.name.startsWith("_")) { const pathName2 = dirent.name.trim().toLowerCase().replace(/^\[(\.{3}.+)\]$/, "*").replace(/^\[\[(.+)\]\]$/, ":$1?").replace(/^\[(.+)\]$/, ":$1").replace(/^\{(.+)\}$/, "$1?"); this.children.push(new _Route(filePath, pathName2)); } else if (/^layout\./i.test(dirent.name)) { this.layout = "/" + filePath; } else if (/^page\./i.test(dirent.name)) { this.page = "/" + filePath; } else if (/^404\./i.test(dirent.name)) { this.notFound = "/" + filePath; } } } get isPathless() { return /^\(.+\)$/.test(this.path); } getRouteData() { if (this.path === "*") { const data2 = new RouteData({ path: this.path, lazy: this.page }); return data2; } const children = this.children.map((item) => item.getRouteData()); if (this.page) { children.push(new RouteData({ index: true, lazy: this.page })); } if (this.notFound) { children.push(new RouteData({ path: "*", lazy: this.notFound })); } const data = new RouteData({ path: this.isPathless ? "" : this.path, lazy: this.layout, children }); return data; } }; // plugin/index.ts function pagesPlugin(baseDir = "src/pages") { const virtualModuleId = "~pages"; const resolvedVirtualModuleId = "\0" + virtualModuleId; baseDir = baseDir.replace(/^\/+|\/+$/g, ""); return { enforce: "pre", name: "vite-plugin-react-pages", // required, will show up in warnings and errors resolveId(id) { if (id === virtualModuleId) { return resolvedVirtualModuleId; } }, load(id) { if (id === resolvedVirtualModuleId) { const route = new Route(baseDir); const data = route.getRouteData(); return `export default [${data}]`; } }, configureServer({ watcher, moduleGraph }) { const reloadVirtualModule = (moduleId) => { const module = moduleGraph.getModuleById(moduleId); if (module) { moduleGraph.invalidateModule(module); watcher.emit("change", moduleId); } }; watcher.on("add", () => { reloadVirtualModule(resolvedVirtualModuleId); }); } }; } var plugin_default = pagesPlugin; export { plugin_default as default };