【问题标题】:How to make module (such as bcrypt) available globally in Express?如何使模块(例如 bcrypt)在 Express 中全局可用?
【发布时间】:2017-06-04 04:52:42
【问题描述】:

我有几个“路由”文件,我在其中导入这样的模块:

var bcrypt = require('bcryptjs');

我试图通过将 bcrypt 导入到我的主应用程序 js 中,然后使用类似这样的 app.use() 来使 bcrypt 全局可用:

var bcrypt = require('bcryptjs');
app.use(bcrypt); // clearly not right, app crashes

我在这里尝试了很多方法。我应该坚持将它单独导入每个文件,还是有一种好方法可以让这个模块在全球范围内可用?

【问题讨论】:

  • 我很确定你不能这样做/不建议这样做。只需在需要它的文件中使用它即可

标签: javascript node.js express


【解决方案1】:

app.use 只能与 Express 中间件一起使用,bcrypt 不是,它只是一个常规的 Node.js 模块。

正如 cmets 中所指出的,没有任何理由不应该只使用 require 使 bcrypt 在任何需要它的模块中可用。

对于它的价值,您可以使用全局可用变量global 在 Node.js 中创建一个全局变量。

在您的示例中,它将像这样使用(但同样,这是不推荐):

var bcrypt = require('bcryptjs');
global.bcrypt = bcrypt;

【讨论】:

  • 谢谢。 global 常用来做什么?我问是因为我总是尝试坚持 DRY 原则,但显然不想在此过程中把事情搞砸。
  • 我不确定,我没有在我的任何项目中使用过它。
  • @Alan 它不常用。我认为框架主要用于填充__dirname 之类的内容。
【解决方案2】:

虽然您已经接受了一个答案,但我想我会更多地描述您为什么不想使用全局以及为什么在您需要的每个模块中只需要 require()

模块背后的概念是您应该努力使每个模块尽可能独立使用。本着这种精神,完全没有理由让一个模块依赖于初始化某个全局变量的前一个模块。这只会使一个模块依赖于与其他模块一起加载的确切顺序,破坏了独立使用该模块的能力,并设置了潜在的全局变量命名冲突。

node.js 中模块设计的一大设计目标是避免使用全局变量。相反,一个模块应该只是 require() 在它需要的东西中,或者它可以在加载时从其他模块传递所需的数据,或者它可以通过调用其他模块中的方法来查询其他模块以获取共享数据。

此外,使用require() 加载模块会被缓存。因此,只有第一次使用require() 加载模块时,它才会从磁盘加载并执行。每次后续加载时,都会立即返回先前加载的模块对象。因此,从需要访问它的各种模块多次加载一个模块几乎没有任何成本。

所以,每个需要访问 bcrypt 的模块都应该这样做:

const bcrypt = require('bcrytpjs');

是的,这会导致在每个模块的顶部重复更多的事情,这有时会感觉比您通常努力的要少一些,但总体而言这是一个更好的权衡,因为它使模块尽可能独立因为每个模块独立地指定它依赖的其他模块并且不使用全局变量来做到这一点。

【讨论】:

  • 值得指出,它在逻辑上相当于 Python 和 Java import 和 C# using 等等。
  • 谢谢,所以我认为我的错误想法是我的模块(例如 myroute.js)就像 app.js 文件的孩子,所以他们应该可以访问 app.js 中已有的所有内容(这是许多其他框架的结构方式)。但是您是说我应该将这些模块(app.js、myroute.js 等)中的每一个视为彼此独立的吗?来自其他框架,这对我来说是一种陌生的思维方式,但我看到了避免不稳定依赖的好处。
猜你喜欢
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-14
  • 2019-06-27
  • 1970-01-01
  • 2012-01-16
相关资源
最近更新 更多