用PHP实现前端路由表自动生成,无需手工维护
互联网产品迭代有个很实在的痛点:前端路由几乎是“改一次需求,动一次页面”,而路由表文件如果靠手工维护,稍微复杂一点的业务很快就会失控。尤其是当项目里存在大量动态页面、多人协作、甚至同一套代码要打包成不同产品线的时候,路由配置经常会出现漏配、错配、或是在代码评审时为了一个path字段反复battle。很多团队想到了用Node写脚本去扫描目录生成路由,这当然可行,但如果你的团队本身就是PHP技术栈,或者构建环境里本来就有PHP CLI,那么用PHP来实现路由表自动生成,会是一条更轻、更贴合现有设施的路径。
先从需求说起
“路由表自动生成”并不是指前端运行时去动态请求接口拿路由,而是在构建时自动生成一份前端可用的路由配置文件。所谓“无需手工维护”,指的是开发者在新增页面时,只需要按既定规则放好文件,剩下的交给机器。
比如一个典型场景,项目使用Vue/React SPA,路由定义通常长这样:
{
path: '/user/list',
component: () => import('@/views/user/List.vue'),
meta: { title: '用户列表' }
}
如果页面数量从十几个涨到几十个,问题就来了:路由表和真实的文件结构容易脱节。
PHP方案的思路
要让PHP(CLI)来生成前端路由表,核心在于一套约定优于配置的规则:把路由的元信息(path、参数、权限标识、标题等)写在每个视图文件头部,PHP脚本在构建时扫描页面目录,抽取元信息并组装成前端路由数组。
例如每个页面的PHP注释块:
<?php
/**
* @route /user/list
* @title 用户列表
* @permission user:list
*/
而后PHP扫描代码则可以落在框架的Command里,或者作为一个独立的`router-build.php`文件:
$viewDir = __DIR__ . '/frontend/views';
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($viewDir)
);
$routes = [];
foreach ($iterator as $file) {
if ($file->isDir() || $file->getExtension() !== 'vue') {
continue;
}
$doc = $file->getContents();
// 利用正则从文件头部注释中提取元数据
preg_match('/@route\s+([^\s]+)/', $doc, $match);
if (!$match) {
continue; // 没标记 route 的跳过或警告
}
$route = [
'path' => $match[1],
'component' => str_replace([$viewDir . '/', '\\'], ['', '/'], $file->getRealPath()),
'meta' => [
'title' => extractTag($doc, '@title'),
...
]
];
$routes[] = $route;
}
最终把`$routes`通过`json_encode`输出到`frontend/routes/routes.json`,前端在编译时用打包器读取这个JSON,或者直接出现在一个`routes.js`文件里作为配置引入。
目录分组与优先级
实践中你会遇到两种比较棘手的情况:目录路径与URL路径不一致,以及多级分组嵌套路由。
解决办法是在扫描目录时,把路径层级映射成路由前缀。假定`views/`下的目录命名为业务功能名称,比如:`views/sale/order/List.vue`,很自然我们想要一段路由`/sale/order/list`。这个路径可以直接从文件位置推断,而在做法上,把`$route`里的嵌套关系打平,交由前端构建时用`path`字段自行拼接,反而比让PHP生成嵌套对象更简便。
处理打平其实不复杂:
$relativePath = ltrim(
str_replace([$viewDir, '/', '.vue'], ['', '/', ''], $file->getRealPath()),
'/'
);
$route['path'] = '/' . dirname($relativePath) . '/' .
strtolower(pathinfo($relativePath, PATHINFO_FILENAME));
再用`usort`按照path的深度和字母排个序,保持输出的稳定,避免因为是随机扫描导致生成的配置在每次跑批时顺序乱变。
从“生成”到“不再维护”
一旦这种模式跑顺,你会发现路由表已经不是一份需要维护的代码,而是一个构建的副产品。新页面只需在文件头部写好注释,并保证文件放置在既定目录里,路由自动就有了。
而且这份JSON还能被复用:比如后端权限系统校验路由白名单时,直接读取这个文件;或者运维资产盘点时,用来输出页面清单;甚至可以用它生成一份Swagger风格的内部接口页面列表。一个构建时的小工序,换来的却是很多手工同步的零成本替换。
好的技术方案不一定要大动干戈地引入重型工程体系。很多时候,在自己的技术栈里找一个合理工具,就能解决跨端、跨维护模型的问题。如果你的团队是PHP主力、前端小步快跑,不妨试一下用PHP扫描视图来驱动路由表生产,把这个恼人的日常维护项一次性自动化掉。
年卡会员