@fourcels/vite-plugin-react-pages
Version:
File system base react-router plugin for Vite
139 lines (136 loc) • 4.02 kB
JavaScript
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
};