【问题标题】:Dynamically load routes with express.js使用 express.js 动态加载路由
【发布时间】:2013-05-22 22:57:46
【问题描述】:

我正在使用 express.js 作为网络服务器,并且想要一种简单的方法来将所有“app.get”和“app.post”函数分隔为单独的文件。例如,如果我想为登录页面指定 get 和 post 函数,我想在动态加载的 routes 文件夹中有一个 login.js 文件(将自动添加所有文件而无需指定每个文件) 当我运行 node app.js

我已经尝试过这个this solution!,但它不适合我。

【问题讨论】:

  • 链接的解决方案看起来应该可以工作;你能粘贴你的实现吗?

标签: node.js express routes


【解决方案1】:

打字稿

routes/testroute.ts

import { Router } from 'express';

const router = Router();
router.get('/test',() => {
    // Do your stuffs Here
});



export = router;

index.ts

let app = express() 

const routePath = path.join(__dirname, 'routes');

fs.readdirSync(routePath).forEach(async (filename) => {
    let route = path.join(routePath, filename);
    try {
        const item = await import(route);
        app.use('/api', item.default);
    } catch (error) {
        console.log(error.message);
    }
});

app.listen()

【讨论】:

    【解决方案2】:

    使用这种方法,无需手动编写路由。只需设置一个目录结构,如 URL 路径。示例路由为/routes/user/table/table.get.js,API 路由为/user/table

    import app from './app'
    import fs from 'fs-readdir-recursive'
    import each from 'lodash/each'
    import nth from 'lodash/nth'
    import join from 'lodash/join'
    import initial from 'lodash/initial'
    
    const routes = fs(`${__dirname}/routes`)
    each(routes, route => {
      let paths = route.split('/')
    
      // An entity has several HTTP verbs
      let entity = `/api/${join(initial(paths), '/')}`
      // The action contains a HTTP verb
      let action = nth(paths, -1)
    
      // Remove the last element to correctly apply action
      paths.pop()
      action = `./routes/${join(paths, '/')}/${action.slice(0, -3)}`
    
      app.use(entity, require(action))
    })
    

    示例路线:

    import { Router } from 'express'
    import Table from '@models/table.model'
    
    const routes = Router()
    
    routes.get('/', (req, res, next) => {   
      Table
        .find({user: userIdentifier})
        .select('-user')
        .lean()
        .then(table => res.json(table))
        .catch(error => next(error))
    })
    
    module.exports = routes
    

    【讨论】:

    • 大声笑,lodash 只是用于加载路线。他永远不会在他的应用程序的其他任何地方使用它,所以我认为这是对整个库的浪费。
    • 正如@user6516765 所说。只做一些可以在 vanilla javascript 中轻松复制的事情是浪费内存。
    • lodash 是对内存和时间的巨大浪费。像 .forEach 这样的原生 JavaScript 函数在这里可以接受
    【解决方案3】:

    我最终使用递归方法来保持代码的可读性和异步性:

    // routes     
    processRoutePath(__dirname + "/routes");
    
    function processRoutePath(route_path) {
        fs.readdirSync(route_path).forEach(function(file) {
            var filepath = route_path + '/' + file;
            fs.stat(filepath, function(err,stat) {
                if (stat.isDirectory()) {
                    processRoutePath(filepath);
                } else {
                    console.info('Loading route: ' + filepath);
                    require(filepath)(app, passport);
                }
            });
        });
    }
    

    这可以通过检查正确的文件扩展名等来变得更加健壮,但我保持我的路由文件夹干净并且不希望增加复杂性

    【讨论】:

      【解决方案4】:

      app.js

      var express=require("express");
      var app=express();
      var fs=require("fs");
      var routePath="./routers/"; //add one folder then put your route files there my router folder name is routers
      fs.readdirSync(routePath).forEach(function(file) {
          var route=routePath+file;
          require(route)(app);
      });
      app.listen(9123);
      

      我在该文件夹下放了两个路由器

      route1.js

      module.exports=function(app){
        app.get('/',function(req,res){
           res.send('/ called successfully...');
        });
      }
      

      route2.js

      module.exports=function(app){
      app.get('/upload',function(req,res){
        res.send('/upload called successfully...');
      });
      }
      

      【讨论】:

      • @anonymousfox 有任何困难请告诉我。
      • 感谢@sachin 的帮助。我设法让一些工作,但它与您提供的解决方案有点不同。当我尝试将相对路由“./routers/”传递给 fs.readdirSync 时,我收到一条错误消息,指出该目录不存在。如果我做了同样的事情,但使用了 __dirname + "/routes",它就可以工作了。我遇到的第二个问题是 mac osx 在我的路由文件夹中创建 .DS_Store 文件。添加路由时,正在解析此文件并最终引发错误。为了解决这个问题,我添加了一个检查以查看是否有 .js 分机。
      猜你喜欢
      • 2016-05-28
      • 1970-01-01
      • 2014-10-26
      • 2020-09-22
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 2013-02-26
      相关资源
      最近更新 更多