node.js – 节点模块化架构

我现在正在构建一个相当大的nodejs应用程序。为了避免单片机应用程序,我已经走下了更多模块化系统的体系结构路线,将多个组件分解成单独的npm模块。这些使用npm发布并安装在依赖模块中。我有大约6个不同的模块(我想打破更多),现在管理软件包变得很困难。

问题是:

>有嵌套依赖关系,所以如果我更改模块A,模块B取决于模块A,模块C依赖于模块B,那么当我更新模块AI需要发布一个新版本,这意味着我需要更新它模块B,这意味着我也需要发布它,然后最后我需要在模块A中安装新版本…你可以看到哪里可能是一个痛苦。更重要的是,所有package.json中的版本都是手动更新,因此容易出错,等待每个发布都是耗时的。
>模块可以共享npm依赖关系,因此当软件包更新时有时会发生冲突。模块越多,冲突的机会就越高。

好处是我们有一个非常模块化的系统,其中库可以轻松地重用,并且有一个明确的模块层次结构执行,因为不能有任何循环依赖。

可能的解决方案是:

> Monolith – 将依赖关系作为单个应用程序管理在单个存储库中,每个模块只是成为一个服务。这意味着只需要一个更新,并且所有的模块apis都将保持同步。但是,引用代码中的库可能会有点痛苦(因为我相信它们必须相对于本地文件被引用),我不知道如何实现模块之间的结构层次结构和代码重用存储库外的模块更难。
>微服务 – 使每个模块成为微服务。这保持了模块化系统的所有好处,但我担心这会增加构建和管理的复杂性,所有这些服务本身将成为一个全职工作。
>继续 – 建立一种保持当前架构的方法,但是消除推送更新的麻烦等等。也许脚本可以更新版本和缩小包装以确保正确的依赖关系。我认为这将是困难的,并可能导致它成为一个不同种类的整体系统。

选项1似乎对我来说最容易管理,但如果我不必要,我不想失去模块化结构。

这是一个很广泛的问题,但任何建议/建议/意见都将是非常有帮助的。

谢谢

我建议去解决方案2。

>在小模块中分解所有代码。
>实现与事件发射器的松散耦合。
>将每个模块存储为其自己的npm软件包没有附加值,除非它们在应用程序之外被单独使用。

您描述的两个问题简单地是由每个模块独立存储为npm包的事实引起的。

优点

>问题1解决了,因为您不需要再在package.json中管理npm软件包。
>问题2解决了,因为你只有一个package.json来管理所有的依赖项
>由于使用了单独的node.js模块,您仍然有一个干净的模块化结构。

示例实现

几个月前,我使用这些原则重构了一个单一的node.js应用程序,它真的减轻了维护,并且没有增加构建过程的开销。

模式如下:

主要模块是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
翻译自:https://stackoverflow.com/questions/34895019/node-modular-architecture

转载注明原文:node.js – 节点模块化架构