@hf-/vite-plugin-auto-router
Version:
A Vite plugin for auto-generating Vue router configuration based on file system
123 lines (109 loc) • 4.37 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
default: () => autoRouter
});
module.exports = __toCommonJS(index_exports);
var import_path2 = require("path");
// src/utils/fs.ts
var import_path = require("path");
var import_fs = require("fs");
async function ensureDir(dir) {
try {
await import_fs.promises.access(dir);
} catch {
await import_fs.promises.mkdir(dir, { recursive: true });
}
}
async function writeFile(filePath, content) {
const dir = (0, import_path.dirname)(filePath);
await ensureDir(dir);
await import_fs.promises.writeFile(filePath, content, "utf-8");
}
// src/index.ts
function autoRouter(options = {}) {
const {
viewsDir = "src/views",
outputPath = "src/router/routes.ts",
dynamicRouteFromUnderscore = true,
removeRedundantSegments = true
} = options;
return {
name: "vite-plugin-auto-router",
configureServer(server) {
server.watcher.add((0, import_path2.resolve)(server.config.root, viewsDir));
server.watcher.on("add", () => generateRoutes());
server.watcher.on("unlink", () => generateRoutes());
},
async buildStart() {
await generateRoutes();
}
};
async function generateRoutes() {
const routeTemplate = `
// \u6B64\u6587\u4EF6\u7531 vite-plugin-auto-router \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u4FEE\u6539
import { RouteRecordRaw } from 'vue-router'
// \u52A8\u6001\u5BFC\u5165\u6240\u6709\u9875\u9762\u7EC4\u4EF6
const modules = import.meta.glob('${viewsDir}/**/*.vue', { eager: false })
// \u52A8\u6001\u5BFC\u5165\u6240\u6709\u5143\u6570\u636E\u6587\u4EF6
const metaModules = import.meta.glob('${viewsDir}/**/*.meta.js', { eager: true })
// \u751F\u6210\u8DEF\u7531\u914D\u7F6E
const routes: RouteRecordRaw[] = Object.keys(modules).map((filePath) => {
// \u751F\u6210\u8DEF\u7531\u8DEF\u5F84
let routePath = filePath
.replace('${viewsDir}/', '')
.replace(/.vue$/, '')
${dynamicRouteFromUnderscore ? ".replace(/\\/_/g, '/:')" : ""} // \u5C06\u6587\u4EF6\u540D\u4E2D\u7684\u4E0B\u5212\u7EBF\u8F6C\u6362\u4E3A\u52A8\u6001\u8DEF\u7531\u53C2\u6570
// \u62C6\u5206\u8DEF\u5F84\u5E76\u5904\u7406
const parts = routePath.split('/').filter(Boolean)
${removeRedundantSegments ? `
// \u79FB\u9664\u91CD\u590D\u7684\u76EE\u5F55\u540D\u548C\u6587\u4EF6\u540D
if (parts.length > 1 && parts[parts.length - 1] === parts[parts.length - 2]) {
parts.pop()
}
if (parts.length > 1 && parts[parts.length - 1].toLowerCase() === 'index') {
parts.pop()
}
` : ""}
routePath = '/' + parts.join('/').toLowerCase()
// \u5BFC\u5165\u5143\u6570\u636E\u6587\u4EF6
const metaFilePath = filePath.replace('.vue', '.meta.js')
const meta = metaModules[metaFilePath] ? metaModules[metaFilePath].default : {}
return {
path: routePath,
component: modules[filePath],
...meta
}
})
// \u786E\u4FDD\u6709\u4E00\u4E2A\u6839\u8DEF\u5F84\uFF08'/'\uFF09\u7684\u8DEF\u7531
if (!routes.some((route) => route.path === '/')) {
routes.push({
path: '/',
component: () => import('${viewsDir}/Home/Home.vue'),
meta: { title: 'Home' }
})
}
export default routes
`;
const outputFilePath = (0, import_path2.resolve)(process.cwd(), outputPath);
await writeFile(outputFilePath, routeTemplate);
}
}