如何在 Express 的多个文件中包含路由处理程序?

发布于 2024-11-07 22:55:02 字数 223 浏览 2 评论 0原文

在我的 NodeJS express 应用程序中,我有 app.js ,它有一些常见的路由。然后在 wf.js 文件中我想定义更多路由。

如何让 app.js 识别 wf.js 文件中定义的其他路由处理程序?

一个简单的 require 似乎不起作用。

In my NodeJS express application I have app.js that has a few common routes. Then in a wf.js file I would like to define a few more routes.

How can I get app.js to recognize other route handlers defined in wf.js file?

A simple require does not seem to work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

∞觅青森が 2024-11-14 22:55:02

如果你想把路由放在一个单独的文件中,例如routes.js,你可以这样创建routes.js文件:

module.exports = function(app){

    app.get('/login', function(req, res){
        res.render('login', {
            title: 'Express Login'
        });
    });

    //other routes..
}

然后你可以要求它从 app.js 以这种方式传递 app 对象:

require('./routes')(app);

看看这些示例:https://github.com/visionmedia/express/tree/master/examples/route-separation

If you want to put the routes in a separate file, for example routes.js, you can create the routes.js file in this way:

module.exports = function(app){

    app.get('/login', function(req, res){
        res.render('login', {
            title: 'Express Login'
        });
    });

    //other routes..
}

And then you can require it from app.js passing the app object in this way:

require('./routes')(app);

Have a look at these examples: https://github.com/visionmedia/express/tree/master/examples/route-separation

油饼 2024-11-14 22:55:02

在 Express 4.x 中,您可以获得路由器对象的实例并导入包含更多路由的另一个文件。您甚至可以递归地执行此操作,以便您的路由导入其他路由,从而允许您创建易于维护的 URL 路径。

例如,如果我的 /tests 端点已经有一个单独的路由文件,并且想要为 /tests/automated 添加一组新的路由,我可能想打破这些/automated 路由到另一个文件,以保持我的 /test 文件小且易于管理。它还允许您按 URL 路径将路由逻辑分组在一起,这非常方便。

./app.js 的内容:

var express = require('express'),
    app = express();

var testRoutes = require('./routes/tests');

// Import my test routes into the path '/test'
app.use('/tests', testRoutes);

./routes/tests.js 的内容:

var express = require('express'),
    router = express.Router();

var automatedRoutes = require('./testRoutes/automated');

router
  // Add a binding to handle '/tests'
  .get('/', function(){
    // render the /tests view
  })

  // Import my automated routes into the path '/tests/automated'
  // This works because we're already within the '/tests' route 
  // so we're simply appending more routes to the '/tests' endpoint
  .use('/automated', automatedRoutes);
 
module.exports = router;

./routes/testRoutes/automated.js 的内容:

var express = require('express'),
    router = express.Router();

router
   // Add a binding for '/tests/automated/'
  .get('/', function(){
    // render the /tests/automated view
  })

module.exports = router;

In Express 4.x you can get an instance of the router object and import another file that contains more routes. You can even do this recursively so your routes import other routes allowing you to create easy-to-maintain URL paths.

For example, if I have a separate route file for my /tests endpoint already and want to add a new set of routes for /tests/automated I may want to break these /automated routes out into a another file to keep my /test file small and easy to manage. It also lets you logically group routes together by URL path which can be really convenient.

Contents of ./app.js:

var express = require('express'),
    app = express();

var testRoutes = require('./routes/tests');

// Import my test routes into the path '/test'
app.use('/tests', testRoutes);

Contents of ./routes/tests.js:

var express = require('express'),
    router = express.Router();

var automatedRoutes = require('./testRoutes/automated');

router
  // Add a binding to handle '/tests'
  .get('/', function(){
    // render the /tests view
  })

  // Import my automated routes into the path '/tests/automated'
  // This works because we're already within the '/tests' route 
  // so we're simply appending more routes to the '/tests' endpoint
  .use('/automated', automatedRoutes);
 
module.exports = router;

Contents of ./routes/testRoutes/automated.js:

var express = require('express'),
    router = express.Router();

router
   // Add a binding for '/tests/automated/'
  .get('/', function(){
    // render the /tests/automated view
  })

module.exports = router;
栀子花开つ 2024-11-14 22:55:02

在 @ShadowCloud 的示例的基础上,我能够动态地将所有路由包含在子目录中。

routes/index.js

var fs = require('fs');

module.exports = function(app){
    fs.readdirSync(__dirname).forEach(function(file) {
        if (file == "index.js") return;
        var name = file.substr(0, file.indexOf('.'));
        require('./' + name)(app);
    });
}

然后将路由文件放入路由目录中,如下所示:

routes/test1.js

module.exports = function(app){

    app.get('/test1/', function(req, res){
        //...
    });

    //other routes..
}

根据需要重复多次,最后放入 >app.js 放置

require('./routes')(app);

Building on @ShadowCloud 's example I was able to dynamically include all routes in a sub directory.

routes/index.js

var fs = require('fs');

module.exports = function(app){
    fs.readdirSync(__dirname).forEach(function(file) {
        if (file == "index.js") return;
        var name = file.substr(0, file.indexOf('.'));
        require('./' + name)(app);
    });
}

Then placing route files in the routes directory like so:

routes/test1.js

module.exports = function(app){

    app.get('/test1/', function(req, res){
        //...
    });

    //other routes..
}

Repeating that for as many times as I needed and then finally in app.js placing

require('./routes')(app);
演出会有结束 2024-11-14 22:55:02

如果您将 express-4.xTypeScript 和 ES6 一起使用,这将是最好使用的模板:

src/api/login.ts

import express, { Router, Request, Response } from "express";

const router: Router = express.Router();
// POST /user/signin
router.post('/signin', async (req: Request, res: Response) => {
    try {
        res.send('OK');
    } catch (e) {
        res.status(500).send(e.toString());
    }
});

export default router;

src/app.ts

import express, { Request, Response } from "express";
import compression from "compression";  // compresses requests
import expressValidator from "express-validator";
import bodyParser from "body-parser";
import login from './api/login';

const app = express();

app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator());

app.get('/public/hc', (req: Request, res: Response) => {
  res.send('OK');
});

app.use('/user', login);

app.listen(8080, () => {
    console.log("Press CTRL-C to stop\n");
});

比使用 varmodule.exports 干净得多。

If you're using express-4.x with TypeScript and ES6, this would be the best template to use:

src/api/login.ts

import express, { Router, Request, Response } from "express";

const router: Router = express.Router();
// POST /user/signin
router.post('/signin', async (req: Request, res: Response) => {
    try {
        res.send('OK');
    } catch (e) {
        res.status(500).send(e.toString());
    }
});

export default router;

src/app.ts

import express, { Request, Response } from "express";
import compression from "compression";  // compresses requests
import expressValidator from "express-validator";
import bodyParser from "body-parser";
import login from './api/login';

const app = express();

app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator());

app.get('/public/hc', (req: Request, res: Response) => {
  res.send('OK');
});

app.use('/user', login);

app.listen(8080, () => {
    console.log("Press CTRL-C to stop\n");
});

Much cleaner than using var and module.exports.

给妤﹃绝世温柔 2024-11-14 22:55:02

并在之前的答案的基础上进一步构建,此版本的routes/index.js将忽略任何不以.js(及其本身)结尾的文件

var fs = require('fs');

module.exports = function(app) {
    fs.readdirSync(__dirname).forEach(function(file) {
        if (file === "index.js" || file.substr(file.lastIndexOf('.') + 1) !== 'js')
            return;
        var name = file.substr(0, file.indexOf('.'));
        require('./' + name)(app);
    });
}

And build yet more on the previous answer, this version of routes/index.js will ignore any files not ending in .js (and itself)

var fs = require('fs');

module.exports = function(app) {
    fs.readdirSync(__dirname).forEach(function(file) {
        if (file === "index.js" || file.substr(file.lastIndexOf('.') + 1) !== 'js')
            return;
        var name = file.substr(0, file.indexOf('.'));
        require('./' + name)(app);
    });
}
向日葵 2024-11-14 22:55:02

/routes 文件夹中所有 .js 文件的完全递归路由,将其放入 app.js 中。

// Initialize ALL routes including subfolders
var fs = require('fs');
var path = require('path');

function recursiveRoutes(folderName) {
    fs.readdirSync(folderName).forEach(function(file) {

        var fullName = path.join(folderName, file);
        var stat = fs.lstatSync(fullName);

        if (stat.isDirectory()) {
            recursiveRoutes(fullName);
        } else if (file.toLowerCase().indexOf('.js')) {
            require('./' + fullName)(app);
            console.log("require('" + fullName + "')");
        }
    });
}
recursiveRoutes('routes'); // Initialize it

/routes 中,放置 whatevername.js 并初始化路由,如下所示:

module.exports = function(app) {
    app.get('/', function(req, res) {
        res.render('index', { title: 'index' });
    });

    app.get('/contactus', function(req, res) {
        res.render('contactus', { title: 'contactus' });
    });
}

Full recursive routing of all .js files inside /routes folder, put this in app.js.

// Initialize ALL routes including subfolders
var fs = require('fs');
var path = require('path');

function recursiveRoutes(folderName) {
    fs.readdirSync(folderName).forEach(function(file) {

        var fullName = path.join(folderName, file);
        var stat = fs.lstatSync(fullName);

        if (stat.isDirectory()) {
            recursiveRoutes(fullName);
        } else if (file.toLowerCase().indexOf('.js')) {
            require('./' + fullName)(app);
            console.log("require('" + fullName + "')");
        }
    });
}
recursiveRoutes('routes'); // Initialize it

in /routes you put whatevername.js and initialize your routes like this:

module.exports = function(app) {
    app.get('/', function(req, res) {
        res.render('index', { title: 'index' });
    });

    app.get('/contactus', function(req, res) {
        res.render('contactus', { title: 'contactus' });
    });
}
情栀口红 2024-11-14 22:55:02

我正在尝试使用 "express": "^4.16.3" 更新此答案。这个答案与 ShortRound1911 的答案类似。

server.js:

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const db = require('./src/config/db');
const routes = require('./src/routes');
const port = 3001;

const app = new express();

//...use body-parser
app.use(bodyParser.urlencoded({ extended: true }));

//...fire connection
mongoose.connect(db.url, (err, database) => {
  if (err) return console.log(err);

  //...fire the routes
  app.use('/', routes);

  app.listen(port, () => {
    console.log('we are live on ' + port);
  });
});

/src/routes/index.js:

const express = require('express');
const app = express();

const siswaRoute = require('./siswa_route');

app.get('/', (req, res) => {
  res.json({item: 'Welcome ini separated page...'});
})
.use('/siswa', siswaRoute);

module.exports = app;

/src/routes/siswa_route.js:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.json({item: 'Siswa page...'});
});

module.exports = app;

I am trying to update this answer with "express": "^4.16.3". This answer is similar to the one from ShortRound1911.

server.js:

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const db = require('./src/config/db');
const routes = require('./src/routes');
const port = 3001;

const app = new express();

//...use body-parser
app.use(bodyParser.urlencoded({ extended: true }));

//...fire connection
mongoose.connect(db.url, (err, database) => {
  if (err) return console.log(err);

  //...fire the routes
  app.use('/', routes);

  app.listen(port, () => {
    console.log('we are live on ' + port);
  });
});

/src/routes/index.js:

const express = require('express');
const app = express();

const siswaRoute = require('./siswa_route');

app.get('/', (req, res) => {
  res.json({item: 'Welcome ini separated page...'});
})
.use('/siswa', siswaRoute);

module.exports = app;

/src/routes/siswa_route.js:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.json({item: 'Siswa page...'});
});

module.exports = app;
一个人的夜不怕黑 2024-11-14 22:55:02

如果您想要一个单独的 .js 文件来更好地组织您的路由,只需在 app.js 文件中创建一个变量,指向它在文件系统中的位置:

var wf = require(./routes/wf);

然后,

app.get('/wf', wf.foo );

其中 .foo 是在 wf.js 文件中声明的一些函数。例如

// wf.js file 
exports.foo = function(req,res){

          console.log(` request object is ${req}, response object is ${res} `);

}

If you want a separate .js file to better organize your routes, just create a variable in the app.js file pointing to its location in the filesystem:

var wf = require(./routes/wf);

then,

app.get('/wf', wf.foo );

where .foo is some function declared in your wf.js file. e.g

// wf.js file 
exports.foo = function(req,res){

          console.log(` request object is ${req}, response object is ${res} `);

}
三人与歌 2024-11-14 22:55:02

对所有这些答案的一个调整是:

var routes = fs.readdirSync('routes')
      .filter(function(v){
         return (/.js$/).test(v);
      });

只需使用正则表达式通过测试数组中的每个文件来进行过滤。它不是递归的,但它会过滤掉不以 .js 结尾的文件夹

One tweak to all of these answers:

var routes = fs.readdirSync('routes')
      .filter(function(v){
         return (/.js$/).test(v);
      });

Just use a regex to filter via testing each file in the array. It is not recursive, but it will filter out folders that don't end in .js

叶落知秋 2024-11-14 22:55:02

我知道这是一个老问题,但我试图为自己找出类似的问题,这就是我最终遇到的问题,所以我想将我的解决方案应用于类似的问题,以防其他人遇到与我相同的问题。我有。有一个很好的节点模块,名为 consign ,它可以完成许多可见的文件系统工作在这里为您提供(即 - 没有 readdirSync 的东西)。例如:

我有一个正在尝试构建的 Restful API 应用程序,我想将所有发送到 '/api/*' 的请求进行身份验证,并且我想将 api 中的所有路由存储到他们自己的目录(我们称之为“api”)。在应用程序的主要部分:

app.use('/api', [authenticationMiddlewareFunction], require('./routes/api'));

在路由目录内,我有一个名为“api”的目录和一个名为 api.js 的文件。在 api.js 中,我只是:

var express = require('express');
var router = express.Router();
var consign = require('consign');

// get all routes inside the api directory and attach them to the api router
// all of these routes should be behind authorization
consign({cwd: 'routes'})
  .include('api')
  .into(router);

module.exports = router;

一切都按预期工作。希望这对某人有帮助。

I know this is an old question, but I was trying to figure out something like for myself and this is the place I ended up on, so I wanted to put my solution to a similar problem in case someone else has the same issues I'm having. There's a nice node module out there called consign that does a lot of the file system stuff that is seen here for you (ie - no readdirSync stuff). For example:

I have a restful API application I'm trying to build and I want to put all of the requests that go to '/api/*' to be authenticated and I want to store all of my routes that go in api into their own directory (let's just call it 'api'). In the main part of the app:

app.use('/api', [authenticationMiddlewareFunction], require('./routes/api'));

Inside of the routes directory, I have a directory called "api" and a file called api.js. In api.js, I simply have:

var express = require('express');
var router = express.Router();
var consign = require('consign');

// get all routes inside the api directory and attach them to the api router
// all of these routes should be behind authorization
consign({cwd: 'routes'})
  .include('api')
  .into(router);

module.exports = router;

Everything worked as expected. Hope this helps someone.

温馨耳语 2024-11-14 22:55:02

index.js

const express = require("express");
const app = express();
const http = require('http');
const server = http.createServer(app).listen(3000);
const router = (global.router = (express.Router()));
app.use('/books', require('./routes/books'))
app.use('/users', require('./routes/users'))
app.use(router);

路由/users.js

const router = global.router
router.get('/', (req, res) => {
    res.jsonp({name: 'John Smith'})
}

module.exports = router

路由/books.js

const router = global.router
router.get('/', (req, res) => {
    res.jsonp({name: 'Dreams from My Father by Barack Obama'})
}

module.exports = router

如果你的服务器在本地运行(http://localhost:3000),那么

// Users
curl --request GET 'localhost:3000/users' => {name: 'John Smith'}

// Books
curl --request GET 'localhost:3000/books' => {name: 'Dreams from My Father by Barack Obama'}

index.js

const express = require("express");
const app = express();
const http = require('http');
const server = http.createServer(app).listen(3000);
const router = (global.router = (express.Router()));
app.use('/books', require('./routes/books'))
app.use('/users', require('./routes/users'))
app.use(router);

routes/users.js

const router = global.router
router.get('/', (req, res) => {
    res.jsonp({name: 'John Smith'})
}

module.exports = router

routes/books.js

const router = global.router
router.get('/', (req, res) => {
    res.jsonp({name: 'Dreams from My Father by Barack Obama'})
}

module.exports = router

if you have your server running local (http://localhost:3000) then

// Users
curl --request GET 'localhost:3000/users' => {name: 'John Smith'}

// Books
curl --request GET 'localhost:3000/books' => {name: 'Dreams from My Father by Barack Obama'}
战皆罪 2024-11-14 22:55:02

我为此编写了一个小插件!厌倦了一遍又一遍地编写相同的代码。

https://www.npmjs.com/package/js-file-req

希望有帮助。

I wrote a small plugin for doing this! got sick of writing the same code over and over.

https://www.npmjs.com/package/js-file-req

Hope it helps.

策马西风 2024-11-14 22:55:02

您可以将所有路由功能放在其他文件(模块)中,并将其链接到主服务器文件。
在主express文件中,添加一个将模块链接到服务器的函数:

   function link_routes(app, route_collection){
       route_collection['get'].forEach(route => app.get(route.path, route.func));
       route_collection['post'].forEach(route => app.post(route.path, route.func));
       route_collection['delete'].forEach(route => app.delete(route.path, route.func));
       route_collection['put'].forEach(route => app.put(route.path, route.func));
   }

并为每个路由模型调用该函数:

link_routes(app, require('./login.js'))

在模块文件中(例如-login.js文件),照常定义函数:

const login_screen = (req, res) => {
    res.sendFile(`${__dirname}/pages/login.html`);
};

const forgot_password = (req, res) => {
    console.log('we will reset the password here')
}

并将其导出以请求方法作为键,值是一个对象数组,每个对象都有路径和功能键。

module.exports = {
   get: [{path:'/',func:login_screen}, {...} ],
   post: [{path:'/login:forgotPassword', func:forgot_password}]
};   

you can put all route functions in other files(modules) , and link it to the main server file.
in the main express file, add a function that will link the module to the server:

   function link_routes(app, route_collection){
       route_collection['get'].forEach(route => app.get(route.path, route.func));
       route_collection['post'].forEach(route => app.post(route.path, route.func));
       route_collection['delete'].forEach(route => app.delete(route.path, route.func));
       route_collection['put'].forEach(route => app.put(route.path, route.func));
   }

and call that function for each route model:

link_routes(app, require('./login.js'))

in the module files(for example - login.js file), define the functions as usual:

const login_screen = (req, res) => {
    res.sendFile(`${__dirname}/pages/login.html`);
};

const forgot_password = (req, res) => {
    console.log('we will reset the password here')
}

and export it with the request method as a key and the value is an array of objects, each with path and function keys.

module.exports = {
   get: [{path:'/',func:login_screen}, {...} ],
   post: [{path:'/login:forgotPassword', func:forgot_password}]
};   
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文