本文介绍了节点模块化架构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个现在相当大的nodejs应用程序.为了避免单片节点应用程序,我采用了更加模块化的系统的体系结构路线,该体系结构将几个组件分解为单独的npm模块.这些使用npm发布并安装在相关模块中.我大约有6个不同的模块(我想进一步介绍),现在管理包变得很困难.

I am building a nodejs application that is fairly large now. In an attempt to avoid a monolithic node application I have gone down the architectural route of a more modular system breaking out several components into separate npm modules. These are published using npm and installed in the dependent modules. I have about 6 different modules (which I would want to break out in to more) and now it has become difficult to manage the packages.

问题是:

  1. 存在嵌套依赖性,因此如果我更改模块A而模块B依赖于模块A而模块C依赖于模块B,那么当我更新模块AI时需要发布它的新版本,这意味着我需要更新它在模块B中,这意味着我还需要发布该模块,然后最后我需要在模块A中安装该新版本...您可以看到哪里可能会很痛苦.此外,所有package.json中的版本更新都是手动操作,因此容易出错,并且等待每次发布都很耗时.
  2. 模块可以共享npm依赖性,因此有时在更新软件包时会发生冲突.模块越多,冲突的可能性就越高.

好处是我们拥有一个非常模块化的系统,在该系统中,可以轻松地重用库,并且由于没有任何循环依赖性,因此强制执行的模块层次清晰.

The benefits are that we have a very modular system where libraries can be reused easily and there is a clear hierarchy of modules enforced as there can't be any circular dependencies.

可能的解决方案是:

  1. Monolith -在单个存储库中作为单个应用程序管理依赖项,而每个模块都只是一个服务.这意味着只需要一次更新,所有模块api都将同步.但是,在代码中引用库可能会有些麻烦(因为我认为必须相对于本地文件进行引用),我不确定如何在模块之间强制执行结构层次结构,并且代码重用将如何在存储库外使用模块会更加困难.

  1. Monolith - To manage the dependencies as a single app in a single repository with each module just becoming a services. This means that only one update is necessary and all the module apis will be in sync. However, referencing the libraries in the code might be a bit of a pain (as I believe they will have to be referenced relative to the local file), I am not sure how a structural hierarchy between the modules can be enforced and code reuse will be harder with modules outside the repository.

微服务-使每个模块成为微服务.这保留了模块化系统的所有优点,但我担心它会增加构建的复杂性,并且管理所有服务本身将成为一项全职工作.

Microservices - To make each module a micro service. This maintains all the benefits of the modular system, but I am concerned that it will add a lot of complexity to the build and managing all the services will become a full time job in itself.

继续前进-设法保留当前体系结构,但消除了推送更新等麻烦.也许脚本可以更新版本并收缩包装以确保正确的依赖关系.我认为这既困难又有可能导致它成为一个不同种类的整体系统.

Keep going - Work out a way to keep the current architecture but remove the trouble of pushing updates etc. Maybe scripts to update versions and shrinkwrap to ensure correct dependencies. I think this would both be difficult and would potentially lead it to being a monolithic system of a different variety.

对我来说,选项1似乎是最易于管理的,但我不想失去模块化结构.

Option 1 seems the most manageable to me but I don't want to lose the modular structure if I don't have to.

这是一个相当广泛的问题,但是任何建议/建议/评论都将非常有帮助.

This is quite a broad question, but any suggestions/advice/comments would be really helpful.

谢谢

推荐答案

我建议使用解决方案2.

I'd recommend going for solution 2.

  • 在小模块中分解所有代码.
  • 使用事件发射器实现松散耦合.
  • 除非将每个模块作为单独的npm包存储在您的应用程序之外,否则它们没有任何附加价值.

您描述的两个问题仅是由于每个模块都独立存储为npm软件包而引起的.

The two problems you have described are simply caused by the fact that each module is independently stored as an npm package.

  • 解决了问题1,因为您不再需要在package.json中管理npm软件包.
  • 问题2已解决,因为您只有一个package.json管理所有依赖项
  • 由于使用了单独的node.js模块,您仍然拥有干净的模块化结构.
  • Problem 1 is solved as you don't need to manage npm packages in package.json anymore.
  • Problem 2 is solved as you only have one package.json managing all the dependencies
  • You still have a clean modular structure thanks to usage of separate node.js modules.

几个月前,我使用这些原理重构了一个单体的node.js应用程序,它确实简化了维护,并且没有增加构建过程的开销.

A few months ago, I refactored a monolithic node.js app using these principles, and it really eased the maintenance, and didn't add overhead to the build process.

模式如下:

主模块是app.js

var sys = require('sys')
    , events = require('events')
    , UserModel = require('./model/user') // this is a microservice taking care of managing user data
    , Logic = require('./controller/logic')   // this is another microservice doing some work

var App = function (server, app) {

    this.controller = (
        logic: new Logic(this) // "this" is the app instance, it's passed to all microservices, which will benefit from the access to event emitter...
    }
    this.model = {
        new UserModel(this)
    }

    // ...
}

sys.inherits(App, events.EventEmitter)

module.exports = App

微服务看起来像这样:

/**
* Logic functions
*
* this controller does ...
*
* @constructor
*
*/
function Logic(app) {

    /****************************************
    *
    * Private methods
    *
    ****************************************/

    /**
    * this is a private function in the controller
    *
    * @private
    */
    function computeSomething () {

        var res = 3

        app.emit('computed', res) // emit event, that can be liseted to by some other modules

        return res
    }


    /****************************************
    *
    * Public methods
    *
    ****************************************/

    /**
    *
    * This function can be called directly by the other modules using "app.controller.logic.work()"
    *
    */
    this.work = function () {

        return 'result is ' + computeSomething()
    }


    /****************************************
    *
    * Event listeners
    *
    ****************************************/

    /**
    * listener: event from the app - loose-coupling magic happens thanks to this. Recommended over public functions.
    *
    * @private
    */
    app.on('data-ready', this.work)

}

module.exports = Logic

这篇关于节点模块化架构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 13:51