【问题标题】:Pattern for Express/Node dependencies: Can I use a separate services file for "app" instance?Express/Node 依赖模式:我可以为“app”实例使用单独的服务文件吗?
【发布时间】:2018-12-12 17:42:29
【问题描述】:

我有一个 express/node 应用程序,我想让应用程序实例在多个文件中可用,而不会遇到循环引用(例如,在 express 包含路由对象之前,您需要将应用程序对象导出到路由中.js 文件,但随后将 routes.js 文件导出回主 app.js 文件)。

虽然我知道 routes 对象可以解决这个用例,但我正在尝试找出不同的模式是否可行/是否是最佳实践。

所以...我可以有一个单独的服务文件,我需要 express 然后在该服务文件中创建应用程序吗?并让我的主根文件夹以及其他 n 个文件夹(每个文件夹都有自己的循环)安全地需要此服务中的应用程序。

Example Folder structure
├── app.js   // main file; ordinarily would have required routes.js
├── routes
    ├── routes.js // ordinarily would have required top app.js for app object
├── services
    ├── firebase.js
    ├── amplitude.js
    └── app.js // instead, create app here and export it to both above

例如,三个文件可能如下所示:

app.js(主)

const app = require('./services/app');
app.listen(3000, () => console.log('Listening on port 3000));

routes/routes.js

const app = require('../services/app');
app.get('/', (req, res) => res.send('hello world'));

services/app.js

const express = require('express');
const app = express();
module.exports.app = app;

这是安全/最佳做法吗?

【问题讨论】:

    标签: node.js express require dependency-management circular-dependency


    【解决方案1】:

    既然是module.exports.app = app,应该不是

    const app = require('./services/app');
    

    但是

    const { app } = require('./services/app');
    

    它看起来不是很优雅,但它会起作用。

    由于routes.js 等应该按照严格的顺序加载以使中间件和路由正常工作,因此这种方法不会使它们松散耦合并且不会提供明显的好处。

    一种常见的做法是做相反的事情并在app.js 中加载中间件。路由不需要app 实例,如this guide 中所述,它们可以使用路由器实例,然后在入口点挂载到/

    routes.js

    const express = require('express');
    const router = express.Router();
    
    router.get('/', (req, res) => res.send('hello world'));
    
    module.exports = router;
    

    app.js

    const express = require('express');
    const app = express();
    
    const router = require('./routes');
    
    app.use('/', router);
    app.listen(3000, () => console.log('Listening on port 3000'));
    

    【讨论】:

    • 谢谢,埃斯图斯!会记住这一点。我的问题措辞不佳,因为我打算谈论一般的服务(例如,使用 SQL 数据库时的“池”实例,使用日志记录时的“幅度”实例等)。当多个文件中需要某个服务的实例时,我试图找出一种允许跨多个文件使用相同实例的模式。根据您的回答,似乎 express 提供了一个优雅的解决方案(即路由),但对于没有此类选项的其他库,服务文件方法将起作用。感谢您的反馈!
    • JS 模块(CJS、ES 等)自然会提供单例实例,因为它们仅在首次导入时进行评估。所以是的,从“服务”模块导出数据库实例并将其导入任何地方是有意义的,这就是通常的做法。至于 Express,它提供了settings table 来管理应用程序的东西,包括数据库实例。因此,您可以在主文件中执行 app.set('db', instance) 并在其他任何地方使用 app.get('db')(这就是您原来的 services/app.js 方法可能有用的地方)。这不是强制性的,只是可能的方法之一。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 2013-07-03
    • 2011-02-23
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多