老板:能不能别手动复制路由了?我:写个脚本自动扫描

起因

周五快下班,老板过来看权限配置页面。

"这个每次都要手动输路径?"

"对,现在是这样。"我打开给他看:

bash 复制代码
角色:运营专员
路由路径:[手动输入] /user/list
组件路径:[手动输入] @/views/user/List.vue

"上次运营配错了,/user/list 写成 /user/lists,页面打不开找了半天。能不能做个下拉框,直接选?"

我想了想:"可以,但得先有个页面列表。"

"那就搞一个,现在页面这么多,手动输容易出错。"

确实,项目现在几十个页面,每次配置权限都要翻代码找路径,复制粘贴,还担心复制错。

解决办法

周末琢磨了一下,其实就是缺个"页面清单"。views 目录下都是页面文件,扫描一遍不就有了?

写了个 Node 脚本,自动扫描 views 目录,生成路由映射表。配置权限的时候下拉框选,还能搜索。

实现

两步:扫描文件 + 生成映射。

扫描 .vue 文件

javascript 复制代码
function getAllVueFiles(dir, filesList = []) {
  const files = fs.readdirSync(dir);
  
  files.forEach((file) => {
    const filePath = path.join(dir, file);
    
    if (fs.statSync(filePath).isDirectory()) {
      getAllVueFiles(filePath, filesList);  // 递归子目录
    } else if (file.endsWith(".vue")) {
      filesList.push(filePath);  // 收集 .vue 文件
    }
  });
  
  return filesList;
}

生成映射文件

javascript 复制代码
function start() {
  const viewsDir = path.resolve(__dirname, "../views");
  let files = getAllVueFiles(viewsDir);
  
  // 兼容 Windows 路径
  files = files.map(item => item.replace(/\\/g, "/"));
  
  // 拼接成 import 映射
  let str = "";
  files.forEach(item => {
    let n = item.replace(/.*src\//, "@/");
    str += `"${n}":()=>import("${n}"),\r\n`;
  });
  
  // 写入文件
  fs.writeFileSync(
    path.resolve(__dirname, "../router/all.router.js"),
    `export const ROUTERSDATA = {\n${str}}`
  );
}

最后生成的文件大概是这样:

javascript 复制代码
// src/router/all.router.js
export const ROUTERSDATA = {
  "@/views/Home.vue": () => import("@/views/Home.vue"),
  "@/views/About.vue": () => import("@/views/About.vue"),
  "@/views/user/List.vue": () => import("@/views/user/List.vue"),
}

怎么用

权限配置页面

vue 复制代码
<template>
  <el-select 
    v-model="selectedRoute" 
    filterable 
    placeholder="搜索并选择页面">
    <el-option
      v-for="(component, path) in ROUTERSDATA"
      :key="path"
      :label="path"
      :value="path">
      {{ path }}
    </el-option>
  </el-select>
</template>

<script setup>
import { ROUTERSDATA } from '@/router/all.router.js'

// 后台返回的权限路由配置
const permissionRoutes = [
  { path: '/user/list', component: '@/views/user/List.vue' },
  { path: '/order/list', component: '@/views/order/List.vue' }
]

// 直接从映射表取组件
const routes = permissionRoutes.map(route => ({
  path: route.path,
  component: ROUTERSDATA[route.component]  // 这里直接用
}))
</script>

好处:

  • 下拉框自动包含所有页面
  • 支持搜索,输入 "user" 就能找到所有用户相关页面
  • 新加页面自动出现在列表里

动态路由

后台返回权限配置,前端从映射表取组件:

javascript 复制代码
function generateRoutes(backendConfig) {
  return backendConfig.map(item => ({
    path: item.path,
    component: ROUTERSDATA[item.component]  // 直接用
  }))
}

效果

周一把代码提上去,改了权限配置页面:

vue 复制代码
<!-- 配置页面 -->
<el-select v-model="route" filterable placeholder="搜索页面">
  <el-option 
    v-for="(component, path) in ROUTERSDATA" 
    :key="path" 
    :label="path" 
    :value="path" />
</el-select>

老板过来试了一下,在下拉框输入 "user" 就搜到所有用户相关页面。

"嗯,这个好用。新加页面也会自动出现在这里吧?"

"对,每次启动项目会自动扫描。"

"行,那就这样。"

后来发现还有些意外收获:

  • 新人看这个映射表就知道项目有哪些页面
  • 后台只存路径字符串,数据库干净
  • 顺带解决了手动 import 几十个路由的问题

package.json 加个脚本:

json 复制代码
{
  "scripts": {
    "dev": "node src/start/index.js && vite"
  }
}

每次 npm run dev 会先扫描 views 目录,生成最新的映射表。

完整代码

javascript 复制代码
// src/start/index.js
const fs = require("fs");
const path = require("path");

function getAllVueFiles(dir, filesList = []) {
  const files = fs.readdirSync(dir);

  files.forEach((file) => {
    const filePath = path.join(dir, file);
    const stat = fs.statSync(filePath);

    if (stat.isDirectory()) {
      getAllVueFiles(filePath, filesList);
    } else if (file.endsWith(".vue")) {
      filesList.push(filePath);
    }
  });

  return filesList;
}

function start() {
  console.log("[自动获取全部可显示页面]");

  const viewsDir = path.resolve(__dirname, "../views");
  let files = getAllVueFiles(viewsDir);

  // 统一路径分隔符,兼容 Windows 反斜杠
  files = files.map((item) => item.replace(/\\/g, "/"));

  let str = "";
  // 构造 import 映射:"@/views/xxx.vue": ()=>import("@/views/xxx.vue")
  files.forEach((item) => {
    let n = item.replace(/.*src\//, "@/"); 
    str += `"${n}":()=>import("${n}"),\r\n`;
  });

  const routerFilePath = path.resolve(__dirname, "../router/all.router.js");
  // 将映射写入路由聚合文件,供路由动态引用
  fs.writeFileSync(
    routerFilePath,
    `
    export const ROUTERSDATA = {
    ${str}
    }`,
  );
  console.log("[./src/router/all.router.js 写入]");
}

start();

注意事项

记得把生成的 src/router/all.router.js 加到 .gitignore,毕竟是自动生成的文件,没必要提交。

bash 复制代码
# .gitignore
src/router/all.router.js

后来

用了一个多月,运营配置权限再也没出过错。上周老板说:"这个功能不错,其他项目也加上。"

代码其实挺简单的,但确实解决了问题。

相关推荐
韭菜炒大葱8 分钟前
React Hooks :useRef、useState 与受控/非受控组件全解析
前端·react.js·前端框架
Cache技术分享12 分钟前
280. Java Stream API - Debugging Streams:如何调试 Java 流处理过程?
前端·后端
微爱帮监所写信寄信15 分钟前
微爱帮监狱寄信写信小程序信件内容实时保存技术方案
java·服务器·开发语言·前端·小程序
沛沛老爹15 分钟前
Web开发者实战A2A智能体交互协议:从Web API到AI Agent通信新范式
java·前端·人工智能·云原生·aigc·交互·发展趋势
这是个栗子21 分钟前
【Vue代码分析】vue方法的调用与命名问题
前端·javascript·vue.js·this
全栈前端老曹30 分钟前
【前端路由】Vue Router 动态导入与懒加载 - 使用 () => import(‘...‘) 实现按需加载组件
前端·javascript·vue.js·性能优化·spa·vue-router·懒加载
Zyx20071 小时前
构建现代 React 应用:从项目初始化到路由与数据获取
前端
大布布将军1 小时前
☁️ 自动化交付:CI/CD 流程与云端部署
运维·前端·程序人生·ci/cd·职场和发展·node.js·自动化
LYFlied1 小时前
Vue.js 中的 XSS 攻击防护机制详解
前端·vue.js·xss
七宝三叔1 小时前
C#,为什么要用LINQ?
前端