WEB开发: Node.js路由之由浅入深(三)自动设置路由 - 全栈工程师入门 [复制链接]
发表于 2025-12-5 15:44:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
前面我们一起学习了Node.js路由的两个进阶,
(1)WEB开发: Node.js路由之由浅入深(一) - 全栈工程师入门
(2)WEB开发: Node.js路由之由浅入深(二)自动路由 - 全栈工程师入门
在第二进阶中,我们已经通过将路由布局模块化,实现了比力方便的而路由方法。
一、进阶分析

但是,你会发现这个文件必要手工去编写:
  1. /project
  2.   /routes
  3.     routesConfig.js
复制代码
对,就是这个routesConfig.js,每次新增大概删除、修改路由的控制文件,大概都要更改这个文件。
它的内容是如许的:
  1. // routesConfig.js
  2. module.exports = [
  3.     { method: 'get', path: '/auth/login', controller: 'authController', action: 'login' },
  4.     { method: 'get', path: '/user/:id', controller: 'userController', action: 'getUserById' },
  5.     { method: 'post', path: '/product', controller: 'productController', action: 'createProduct' },
  6.     { method: 'post', path: '/auth/login', controller: 'authController', action: 'login' }
  7.     // 更多路由...
  8. ];
  9. /*
  10. @method: 对应来自 访问端 的RESTful API 方法
  11. @path: 定义来自访问端的路径
  12. @controller 根据method 和 path  来定位使用什么控制器
  13. @action 定义使用控制器中的什么函数
  14. */
复制代码
过细观察你会发现,这内里的内容,和我们控制器以及控制器内的设置是存在对应关系的,也就是
method: 这个是api进来的哀求方式
controller: 这个是我们控制器的文件名
action: 这个是我们控制器内的函数名
唯逐一个没有对应关系的是 path。
那么搞清楚这个关系,就好办了。
二、更改控制器

既然path和控制器的文件名、内容都无关,那么我们是否可以将这个关系写到控制器内,然后通过自动读取文件夹、分析文件内容的方式,来自动天生这个routesConfig.js文件呢?
答案固然是可以的。
以是我们只必要修改下面两部分:

第一部分,修改控制器的写法,比如userController.js的写法,改成如许:
  1. // userController.js
  2. module.exports = {
  3.     get: {
  4.         getUserById: {
  5.             path: '/user/:id',
  6.             fn: (req, res) => {
  7.                 const userId = req.params.id;
  8.                 res.send(`User ID: ${userId}`);
  9.             },
  10.         }
  11.     },
  12.     post: {
  13.         getUserById: {
  14.             path: '/user/:id',
  15.             fn: (req, res) => {
  16.                 const userId = req.params.id;
  17.                 res.send(`User ID: ${userId}`);
  18.             }
  19.         },
  20.     }
  21.     // 更多方法...
  22. };
复制代码
看到了吗 ,我们把控制器分成了 get 和post 两类,固然你也可以加put  delete。
然后我们这内里到场了 path。 也就是说当你写控制器的时间,你就随手将path 写进去了,不必要去写其他的文件。fn就是我们之前的action。
以是这个路由的get调用就是: 控制器.get.getUserById.fn() ,路径就是: 控制器.get.getUserById.path
三、更改app.js

以是我们必要更改一下app.js 的动态路由方法,改动后如下:
  1. // 动态加载路由
  2. routesConfig.forEach(route => {
  3.     const controller = require(`./controllers/${route.controller}`);  // 动态加载控制器
  4.     app[route.method](route.path, controller[route.method][route.action].fn);  // 将路由与控制器方法绑定
  5.     console.log('for review route:', route.method, route.path, controller[route.method][route.action].fn)
  6. });
复制代码
看到了吗,route.path, controller[route.method][route.action].fn 对应了我上面的表明。
四、自动天生路由设置

到这里,整个路由逻辑完成了,但是我们必要自动天生路由设置文件,而不是手写。
以是我们必要增长一个routesConfigMake 的脚本: rcMake.js:
  1. const fs = require('fs');
  2. const path = require('path');
  3. const rcMake = () => {
  4.     // 定义 controllers 目录
  5.     const controllersDir = path.join(__dirname, 'controllers');
  6.     // 获取 controllers 目录下的所有文件(同步方法)
  7.     let files;
  8.     try {
  9.         files = fs.readdirSync(controllersDir);
  10.     } catch (err) {
  11.         console.error('无法读取 controllers 目录:', err);
  12.         return;
  13.     }
  14.     // 用于保存所有路由信息的数组
  15.     const routes = [];
  16.     // 逐一处理每个文件
  17.     files.forEach(file => {
  18.         const filePath = path.join(controllersDir, file);
  19.         const fileName = path.basename(file, '.js'); // 去掉文件扩展名
  20.         // 只处理 .js 文件
  21.         if (path.extname(file) === '.js') {
  22.             let controller;
  23.             try {
  24.                 controller = require(filePath);
  25.             } catch (err) {
  26.                 console.error(`无法加载文件 ${file}:`, err);
  27.                 return;
  28.             }
  29.             // 遍历 controller 中的 HTTP 方法(get, post 等)
  30.             Object.keys(controller).forEach(method => {
  31.                 const methodRoutes = controller[method];
  32.                 // 遍历每个方法的路由
  33.                 Object.keys(methodRoutes).forEach(action => {
  34.                     const route = methodRoutes[action];
  35.                     routes.push({
  36.                         method: method,
  37.                         path: route.path,
  38.                         controller: fileName,
  39.                         action: action
  40.                     });
  41.                 });
  42.             });
  43.         }
  44.     });
  45.     // 生成 routes.js 文件的内容
  46.     const routesContent = `// routes.js\nmodule.exports = ${JSON.stringify(routes, null, 2)};\n`;
  47.     // 将生成的内容写入 routes.js 文件(同步方法)
  48.     try {
  49.         fs.writeFileSync(path.join(__dirname, '/routers/routesConfig.js'), routesContent);
  50.         console.log('routesConfig.js 文件已生成');
  51.     } catch (err) {
  52.         console.error('写入 routesConfig.js 文件失败:', err);
  53.     }
  54. };
  55. module.exports = rcMake;
复制代码
这个脚本放在和app.js 中 ,在app.js的最开始调用,自动将我们控制器内的设置写在这个设置文件中,实行后天生routesConfig.js文件,内容如下:
  1. // routes.js
  2. module.exports = [
  3.   {
  4.     "method": "get",
  5.     "path": "/auth/login",
  6.     "controller": "authController",
  7.     "action": "login"
  8.   },
  9.   {
  10.     "method": "post",
  11.     "path": "/auth/login",
  12.     "controller": "authController",
  13.     "action": "login"
  14.   },
  15.   {
  16.     "method": "get",
  17.     "path": "/product",
  18.     "controller": "productController",
  19.     "action": "createProduct"
  20.   },
  21.   {
  22.     "method": "post",
  23.     "path": "product",
  24.     "controller": "productController",
  25.     "action": "createProduct"
  26.   },
  27.   {
  28.     "method": "get",
  29.     "path": "/user/:id",
  30.     "controller": "userController",
  31.     "action": "getUserById"
  32.   },
  33.   {
  34.     "method": "post",
  35.     "path": "/user/:id",
  36.     "controller": "userController",
  37.     "action": "getUserById"
  38.   }
  39. ];
复制代码
请注意,这时间你必须全部的控制器都按照我前面提到的方式来改写,这里包罗了 get 和post 两类,其他本身可以加。,app.js 会自动调用这个设置的。
五、更新app.js

末了,app.js 必要加上这个脚本:
  1. const express = require('express');const app = express();//加上脚本 自动天生路由设置文件const rcMake = require('./rcMake.js')rcMake()const routesConfig = require('./routers/routesConfig');  // 导入路由设置文件// 动态加载路由
  2. routesConfig.forEach(route => {
  3.     const controller = require(`./controllers/${route.controller}`);  // 动态加载控制器
  4.     app[route.method](route.path, controller[route.method][route.action].fn);  // 将路由与控制器方法绑定
  5.     console.log('for review route:', route.method, route.path, controller[route.method][route.action].fn)
  6. });// 启动服务const port = 3000;app.listen(port, () => {    console.log(`Server is running on port ${port}`);});
复制代码
好了,如许,你的工作就只必要关注在写控制器上,而无需关注路由设置,由于路由设置都自动化了。如很多方便?
必要完备的项目文件,请给我留言。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表