Node.js 将我的模块连接起来而不至于弄得一团糟
Node.js Plumbing my modules together without it becoming a mess
真是个简单的问题。我试图根据特性或功能将我的 node.js 应用程序拆分为相关模块。例如。用于读取日志文件的日志读取模块、用于使用 IRC 机器人等的 IRC 模块。
我目前使用全局事件发射器模块将所有内容连接在一起,该模块对需要传递的任何消息进行所有管道处理,例如我想推送到我的数据库中的日志条目。
这一段时间以来一直运行良好,但我感觉好像我需要开始要求我的一些功能模块才能完成其他功能模块中的一些工作。我想避免紧密耦合(因此使用事件模块),但这真的有什么不好吗?
在审查其他一些 node.js 项目时,我经常看到一个 app.js 文件需要 10 个左右的其他模块,看起来试图在一个地方完成所有工作。我试图让我的文章非常简洁易读。有没有你能想到的做得好的例子?
我遇到的最佳经验法则是:模块是否可单独测试?我可以要求模块并从测试用例中调用它的功能吗?如果该模块依赖于其他模块,那么用假模块模拟这些模块进行测试有多难?
在我看来,可测试性是良好分离关注点的最佳指标。如果您的模块确实需要其他十个模块,那也没关系。我会始终将可测试性牢记在心,即使您实际上并不打算花时间编写测试。
即使只是保持测试选项打开也比没有好,它是了解您的模块的专业程度的有用指南。如果您有三个模块并且您不能在没有另外两个的情况下使用一个,那么它们可能属于一个模块。或者也许这三个模块很大,分开时更容易导航;对于这种情况,我通常会创建一个 包装器模块 .
我创建了一个具有相关名称的目录,并在其中放入了一个 index.js
文件,该文件需要其他三个模块(或者我需要的任何模块)。然后我可以从我的应用程序的其余部分访问该模块,就好像它是一个专门的 API,即使它在内部很复杂并且分成多个子模块。包装器模块从我的应用程序的其余部分隐藏了混乱,这样我仍然可以模块化,同时也保持 API 简单。对于将东西组合到一个模块中太混乱并且在拆分配置中使用模块也很混乱的情况,这是一个很好的解决方法。
如果一个模块足够通用(如果可能的话,我通常会以此为目标)那么我通常会将其作为独立模块发布到 NPM。然后我将像 NPM 上的任何其他模块一样在我的项目中需要它。例如,我一直在编写一个脚本,将我所有的猫鼬模型加载到一个 db
对象中,以便于访问。代码将循环遍历项目根目录下 dbmodels
目录中的 mongodb 模型文件。它需要模块,用猫鼬注册模型数据,并生成一个我可以使用的简单 db
对象(例如 db.User.findOne({ username: 'munkee' }, function (err, user) { ... }
)。
我没有继续将相同的代码块复制并粘贴到我构建的每个项目中,而是创建了一个名为 mongoose-simpledb. If you look at the code for that module 的通用 NPM 模块,您可以看到它不是很复杂。尽管我认为它应该在 NPM 注册表中占有一席之地,但它非常通用且非常有用。它使新项目中的事情变得容易得多。其他人发现它也有用只是一个快乐的奖励:)
真是个简单的问题。我试图根据特性或功能将我的 node.js 应用程序拆分为相关模块。例如。用于读取日志文件的日志读取模块、用于使用 IRC 机器人等的 IRC 模块。
我目前使用全局事件发射器模块将所有内容连接在一起,该模块对需要传递的任何消息进行所有管道处理,例如我想推送到我的数据库中的日志条目。
这一段时间以来一直运行良好,但我感觉好像我需要开始要求我的一些功能模块才能完成其他功能模块中的一些工作。我想避免紧密耦合(因此使用事件模块),但这真的有什么不好吗?
在审查其他一些 node.js 项目时,我经常看到一个 app.js 文件需要 10 个左右的其他模块,看起来试图在一个地方完成所有工作。我试图让我的文章非常简洁易读。有没有你能想到的做得好的例子?
我遇到的最佳经验法则是:模块是否可单独测试?我可以要求模块并从测试用例中调用它的功能吗?如果该模块依赖于其他模块,那么用假模块模拟这些模块进行测试有多难?
在我看来,可测试性是良好分离关注点的最佳指标。如果您的模块确实需要其他十个模块,那也没关系。我会始终将可测试性牢记在心,即使您实际上并不打算花时间编写测试。
即使只是保持测试选项打开也比没有好,它是了解您的模块的专业程度的有用指南。如果您有三个模块并且您不能在没有另外两个的情况下使用一个,那么它们可能属于一个模块。或者也许这三个模块很大,分开时更容易导航;对于这种情况,我通常会创建一个 包装器模块 .
我创建了一个具有相关名称的目录,并在其中放入了一个 index.js
文件,该文件需要其他三个模块(或者我需要的任何模块)。然后我可以从我的应用程序的其余部分访问该模块,就好像它是一个专门的 API,即使它在内部很复杂并且分成多个子模块。包装器模块从我的应用程序的其余部分隐藏了混乱,这样我仍然可以模块化,同时也保持 API 简单。对于将东西组合到一个模块中太混乱并且在拆分配置中使用模块也很混乱的情况,这是一个很好的解决方法。
如果一个模块足够通用(如果可能的话,我通常会以此为目标)那么我通常会将其作为独立模块发布到 NPM。然后我将像 NPM 上的任何其他模块一样在我的项目中需要它。例如,我一直在编写一个脚本,将我所有的猫鼬模型加载到一个 db
对象中,以便于访问。代码将循环遍历项目根目录下 dbmodels
目录中的 mongodb 模型文件。它需要模块,用猫鼬注册模型数据,并生成一个我可以使用的简单 db
对象(例如 db.User.findOne({ username: 'munkee' }, function (err, user) { ... }
)。
我没有继续将相同的代码块复制并粘贴到我构建的每个项目中,而是创建了一个名为 mongoose-simpledb. If you look at the code for that module 的通用 NPM 模块,您可以看到它不是很复杂。尽管我认为它应该在 NPM 注册表中占有一席之地,但它非常通用且非常有用。它使新项目中的事情变得容易得多。其他人发现它也有用只是一个快乐的奖励:)