Javascript Express.js子应用程序加载同一模块
我有一个简单的Express应用程序,可以加载2个子应用程序-登录和发布。子应用程序和顶级应用程序都使用不同的require语句导入一些公共代码,但是当代码运行时,它们看起来共享相同的代码 文件结构为:Javascript Express.js子应用程序加载同一模块,javascript,node.js,express,Javascript,Node.js,Express,我有一个简单的Express应用程序,可以加载2个子应用程序-登录和发布。子应用程序和顶级应用程序都使用不同的require语句导入一些公共代码,但是当代码运行时,它们看起来共享相同的代码 文件结构为: ├── app.js ├── lib │ ├── Common.js │ ├── login │ │ └── index.js │ └── posts │ └── index.js └── package.json app.js: var express
├── 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
我希望每个应用程序都有自己的代码副本,所以在此之前:undefined会打印3次。相反,只有要加载的第一个应用程序才会打印此行,下一个要加载的应用程序会从第一个应用程序设置存储的_文本变量
有没有一种方法可以在应用程序之间安全地共享代码?这种行为——需要缓存和重用的事实,已经有了很好的文档记录,而且非常可取,因为它允许一个应用程序有多个js文件需要“x”,并且所有这些文件都会碰到同一个x,而不必创建其他方法来共享 一般来说,如果我了解您的目标,您可能希望为解决方案采用的方法是将“Common.js”修改为更类似类的结构,并让每个应用程序使用一个新实例。由于某种原因,您已经通过广泛使用的约定选择了将Common大写,只有“构造函数”函数具有初始大写字母,因此它看起来类似 比如: 对于Common.js
// this is a constructor
var Common = function(initStr)
{
this.storedText = initStr;
}
module.exports = Common;
// 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;
在index.js和其他文件中
var Common = require('../Common');
var common = new Common ("instance string");
// code access 'common' from here.
如果在多个文件中执行此操作,则每个文件都会有自己的公用项,即使所有文件都共享一个公用项(如果愿意的话)
您可以进一步增强这一点,以允许某种类型的键控访问,这样,如果您需要文件A和文件B来共享单个公共实例,您可以使其可用,但我认为上面的内容应该满足您的即时查询
希望这有帮助。如果您需要进一步的澄清,请发表评论,我将密切关注
更新
正如您在评论中所要求的那样,您可以采用以下方法来实现实例的键控共享:
对于Common.js
// this is a constructor
var Common = function(initStr)
{
this.storedText = initStr;
}
module.exports = Common;
// 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');
返回的公共项仍将具有“POST的实例数据”,而不是“某些其他实例数据”。很明显,如果您愿意,您可以改变这种行为,但以上是该概念的基本版本。感谢您提供的详细答案,非常有用。我能让你建议的解决方案发挥作用。您能概述一下您提到的共享单实例增强功能吗?这听起来可能是在应用程序之间共享数据的好方法。不客气。我发布了详细解答的更新。Barry感谢这是一个非常酷的东西,我没有想到你可以向函数添加属性,或者你可以将属性作为实例的引用。我仍在努力了解javascript的一些复杂之处。干杯。如果你已经习惯了许多其他语言,那么函数具有属性的想法有点奇怪,但它的好处或功能至少是Javascript的功能性质。我推荐道格拉斯·克罗克福德(Douglas Crockford)的讲座可以在Youtube上找到——他的YUI Conf讲座或《Javascript:The Good Parts》一书都可以作为深入理解Javascript的有用工具。