我最终试图在var server = require('../../index.js');
文件中要求foo-dao.js
,以便我可以访问hapi服务器插件而无需从控制器传递hapi request
对象到道。
当我尝试在文件顶部要求index.js时,我的foo-dao.js方法的注释中可以看到这个问题。
我认为问题是因为在我的index.js中,它需要./modules文件夹,它需要./modules/foo/foo-routes.js,它需要./modules/foo/foo-ctrl.js这需要./modules/foo/foo-dao.js。
以下是需求
的简化视觉效果./ modules / index.js - > ./modules/foo/foo-routes.js - > ./modules/foo/foo-ctrl.js - > ./modules/foo/foo-dao.js - > ./modules/index.js< - 问题就在这里,因为我的服务器变量在INDEX.JS没有被曝光。
/hapi/index.js
/**
* Hapi.js server.
*
* @type {exports}
*/
var Hapi = require('hapi');
var modules = require('./modules');
// Instantiate the server
var server = new Hapi.Server('0.0.0.0', 4445, {cors: true, debug: {request: ['error']}});
...
/**
* Add all the modules within the modules folder
*/
for(var route in modules) {
server.route(modules[route]);
}
/**
* Expose the server's methods when used as a require statement
*
* @type {exports.server}
*/
module.exports = server;
/hapi/modules/foo/foo-routes.js
var Joi = require('Joi');
var fooController = require('./foo-ctrl');
module.exports = function() {
return [
{
method: 'GET',
path: '/api/foo',
config: {
handler: fooController.foo//,
}
}
]
}();
/hapi/modules/foo/foo-ctrl.js
var fooDao = require('./foo-dao');
module.exports = function() {
return {
foo: function foo(req, reply) {
fooDao.findFoo(function(err, data) {
if (err) {
return reply(Boom.badImplementation(err));
}
reply(data);
});
}
}
}();
/hapi/modules/foo/foo-dao.js
var server = require('../../index.js'); // WHEN I REQUIRE THE FILE HERE, IT'S UNDEFINED, PROBABLY BECAUSE THE server OBJECT HAS NOT BEEN EXPOSED YET
console.log('server = ');
console.log(server);
module.exports = function() {
return {
findFoo: function findFoo(callback) {
var server = require('../../index.js'); // WHEN I REQUIRE THE FILE HERE, IT'S ACTUALLY DEFINED, PROBABLY BECAUSE THE server OBJECT HAS BEEN EXPOSED BY THIS POINT. I DON'T WANT TO HAVE TO REQUIRE INDEX.JS IN EVERY SINGLE FUNCTION THOUGH. HOW CAN I CIRCUMVENT THIS PROBLEM?
... get data and return it in the callback
}
}
}();
答案 0 :(得分:2)
我最终试图要求var server = require(' ../../ index.js');在我的foo-dao.js文件中,这样我就可以访问hapi服务器插件,而无需通过hapi请求对象从控制器传递给dao。
这是一个非常清楚的迹象表明CommonJS系统试图拯救你的设计很差。不要使用子模块并使其了解更高的相关父模型。它使子模块不可重用,并将其强烈耦合到包含的应用程序,这与您想要的相反。深度可重用模块应该通过选项和请求对象获得所需的内容,而不是要求更高级别的应用程序抽象。
至少作为解决您的循环要求问题的第一步,您希望在foo-dao.js
中执行此操作。但即便如此,我认为您需要对代码结构进行更广泛的更改,以使其更加清晰。
module.exports = function makeDao(server) {
return {
findFoo: function findFoo(callback) {
//now via closure you have permanent access to the server,
//without being coupled so tightly to it's exact filesystem location
}
}
};
要加载它,您需要从顶部向下传递服务器实例,在您的情况下是modules
。
var server = new Hapi.Server('0.0.0.0', 4445, {cors: true, debug: {request: ['error']}});
var modules = require('./modules')(server);
这将使您的模块代码更容易测试(依赖注入)和重用。
我在express_code_structure存储库中详细说明了我的整体方法。特别注意app
实例如何传递给路由。有关如何使用express4的详细信息,我确定hapi.js不同,但一般的想法可能仍然适用。