2012-10-05 22 views
7

在嘗試模塊化大型現有節點+快速+貓鼬 應用程序分爲多個安裝的應用程序,每一個開發爲 獨立的NPM包,我們想知道是否共享一個 貓鼬他們之間的實例是一個好主意?分享多個NPM之間的貓鼬實例程序包

比方說,我們有一套NPM軟件包,每個軟件包都包含客戶端資產, Mongoose模型以及使用Express實現的REST-API。他們確實共享 幾個共同的特徵,但基本上被認爲是獨立的 可重複使用的文物。主機應用程序,也快速爲基礎,根據不同的根的URI安裝這些 :

var discussions = require('discussions'), 
    tickets  = require('tickets'), 
    events  = require('events'), 
    express  = require('express'), 
    app   = express(); 

var environment = { ...see below... }; 

... 

app.use('/events-api', events(environment)); 
app.use('/tickets-api', tickets(environment)); 
app.use('/discussions-api', discussions(environment)); 

現在,由於eventsticketsdiscussions應用程序(獨立的NPM包 通過主機package.json被拉)用貓鼬,如做主機應用程序本身,我們認爲我們會通過某種environment對象傳遞主機Mongoose實例 對象,該對象還包括主機想要與安裝的應用程序共享的其他 對象。

您是否發現這種方法存在明顯的缺陷?在安裝應用程序 在這種情況下將在其 各自package.json指定貓鼬作爲依賴,他們將require('mongoose') 的正常進行,而是從主機 負責將其連接到拿到貓鼬實例MongoDB的。

如果這是一個壞主意,你認爲各個子應用程序申報自己的依賴 對貓鼬,每個NPM包將得到貓鼬自己 副本,並會各有連接到MongoDB的,對不對?

一些背景資料:

  • 我們真的想在一個主機應用程序的應用程序,在一個進程中運行 ,而具有多個節點的實例。 主機包含用於認證和其他事情的中間件。
  • 我們希望將這些應用作爲單獨開發的NPM軟件包包括在內,作爲我們構建的各種主機應用程序的版本依賴關係,而不僅僅是將它們的源複製到主機應用程序。
  • 我們意識到,重複使用多個 安裝的應用程序之間的相同Mongoose實例將使它們共享相同的模型名稱空間。

編輯:爲了澄清包結構中的所有已後npm install ED:

host/ 
    assets/ 
    models/ 
    routes/ 
    node_modules/ 
    express/ ... 
    mongoose/ ... 
    events/ 
     assets/ ... 
     models/ ... 
     routes/ ... 
    tickets/ 
     assets/ ... 
     models/ ... 
     routes/ ... 
    discussions/ 
     assets/ ... 
     models/ ... 
     routes/ ... 

即,eventstickets,和discussions應用程序不包括 貓鼬(或快遞)的他們自己的,但旨在依靠總是存在的提供這些依賴關係的主機應用程序 。

我們在此假設的NPM包像tickets不能簡單地從父 require的東西,對不對?

回答

6

如果您想在其他NPM軟件包之間重複使用您的Mongoose軟件包,最好的方法是在頂級應用程序上安裝共享軟件包,然後使用它來初始化其他NPM軟件包。

在頂層:

var db = require('myMongooseDb'), 
    events = require('events')(db), 
    ... 

那麼你的事件包只需要導出函數,它的數據庫作爲參數。

+0

非常感謝您的回答,但並不意味着說,核心問題是隻是把一個間接的水平?如果我們的每個「可掛載應用程序」NPM軟件包都包含這個新的「DB」包作爲依賴關係,它們都會在各自的'node_modules'中有一個嵌套的Mongoose實例,它們都需要連接到MongoDB?我目前的假設是,根/主機應用程序不足以聲明對其它NPM軟件包可以「需要」的DB包的依賴性。對不起,如果我誤解了你。 – Greg

+0

哦,對不起,我很困惑。我以爲你只是在創建可重用的模塊,而不是你正在安裝的實際的NPM軟件包。 NPM真的是在項目之間共享包,而不是在單個項目中創建模塊。你希望獲得什麼,使用常規模塊不能解決?在我看來,你會重複很多順着NPM路徑的事情。 – Bill

+0

爲我的問題添加了一個小小的說明。使用NPM包的基本原理是,它們很容易被聲明爲主機的依賴關係,在這種情況下,通過簡單的版本控制,多個主機可以直接從它的'package.json'使用不同版本的相同子應用程序。實際的NPM包有自己的Git回購和開發生命週期,但我想我們可以使用Git子模塊,而不是通過主機'package.json'管理它們?還是有另一種重用模塊的巧妙方式? – Greg

3

我建議你看看https://github.com/jaredhanson/node-parent-require,這是一個最近發佈的軟件包,它爲我解決了這個問題。

Github項目頁面上的node-parent-require Readme file提供了使用貓鼬的詳細演練。

基本上,你需要在你的子模塊挖掘和替換這樣的:

mongoose = require("mongoose"); 

...這一點:

try { 
    var mongoose = require('mongoose'); 
} catch (_) { 
    // workaround when `npm link`'ed for development 
    var prequire = require('parent-require') 
    , mongoose = prequire('mongoose'); 
} 

不要忘了在你的子模塊的加入貓鼬爲peerDependency的package.json。例如:

"peerDependencies": { 
    "mongoose": "3.x" 
} 

您可能還想先閱讀http://blog.nodejs.org/2013/02/07/peer-dependencies/

+0

優秀的文章和解決方案對我來說非常棒。我只是將try..catch包裝器代碼放在自己的文件中,所有包都引用它 - 謝謝! – electblake

+0

我如何在2017年使用ES6/Typescript導入? 「導入」不能被包裝在try/catch塊中... –

相關問題