Express.js子应用程序加载相同的模块

时间:2014-03-05 02:17:53

标签: javascript node.js express

我有一个简单的Express应用程序,可以加载2个子应用程序 - 登录和发布。子应用程序和顶级应用程序各自使用不同的require语句导入一些公共代码,但是当代码运行时,它们看起来像是在共享相同的代码。

文件结构是:

├── app.js
├── lib
│   ├── Common.js
│   ├── login
│   │   └── index.js
│   └── posts
│       └── index.js
└── package.json

app.js:

var
  express  = require( 'express' ),
  Common   = require( './lib/Common' ),
  login    = require( './lib/login' ),
  posts    = require( './lib/posts' ),
  app      = express();

app.use( login );
app.use( posts );
Common.init( "top level" );
app.listen( 3000 );

lib / login / index.js :( lib / posts / index.js类似)

var
  express = require( 'express' ),
  Common  = require( '../Common' ),
  app     = module.exports = express();

Common.init( "login subapp" );

LIB / Common.js:

var stored_text = undefined;

init = function ( text ) {
  console.log( "text: " + text );
  console.log( "before: " + stored_text );
  stored_text = text;
  console.log( "after: " + stored_text );
}

module.exports = {
  init: init
}

当我运行应用程序时,我得到以下输出:

node app.js 
text: login subapp
before: undefined
after: login subapp
text: posts subapp
before: login subapp
after: posts subapp
text: top level
before: posts subapp
after: top level

我希望每个应用程序都有自己的代码副本,因此“before:undefined”将被打印3次。相反,只有第一个要加载的应用程序打印此行,下一个加载具有从第一个应用程序设置的stored_text变量。

有没有办法在应用之间安全地共享代码?

1 个答案:

答案 0 :(得分:0)

这种行为 - require缓存和重用的事实,是非常好的文档和非常需要,因为它允许一个应用程序有多个js文件require('x'),所有这些文件都会触及相同的x,与必须创建其他方法进行共享。

一般来说,如果我理解你的目标,你可能想要为你的解决方案采取的方法是将'Common.js重新编写为更“类”的结构,并让每个应用程序使用一个新实例。由于某些原因,您已经选择将Common资本化(通过广泛使用的约定,只有'构造函数'函数具有初始资本),因此它看起来很相似。

类似的东西:

对于Common.js

// this is a constructor
var Common = function(initStr)
{
   this.storedText = initStr;
}

module.exports = Common;

在index.js(和其他文件)中

var Common = require('../Common');

var common = new Common ("instance string");

// code access 'common' from here. 

如果您在多个文件中执行此操作,则每个文件都有自己的common,即使所有文件都共享Common,如果您愿意的话。

你可以进一步增强这一点以允许某种键控访问,这样如果你需要文件A和文件B来共享一个common实例,你可以使它可用,但我认为以上内容应该解决你的问题立即询问。

希望这会有所帮助。如果您需要进一步澄清,请发表评论,我会留意。

<强>更新

正如您在评论中所要求的那样,您可以采用键控共享实例的方法:

对于Common.js

// this is a constructor
var Common = function(key, initStr)
{
   if(Common.instances[key])
       return Common.instances[key]

   this.storedText = initStr;
   Common.instances[key] = this;
}

Common.instances= {};

module.exports = Common;

然后你可以从各种文件中访问它的相同实例:

specificButShareable = new Common('postsModule', 'instance data for posts');

请注意,如果已实现,则使用

加载第二个文件
specificButShareable = new Common('postsModule', 'some other instance data');

返回的公共文件仍然会有“帖子的实例数据”而不是“其他一些实例数据”。显然,如果你愿意,你可以改变这种行为,但上面的内容是概念的简单版本。