在Node.js中工作,我将一个工作片段分成两个产生相同结果的片段。工作代码段有一个require语句,位于根目录中。拆分的两个段在根目录的第一个阶段工作,但第二个阶段失败并报告无法找到eTrade库。这是require语句。
var etrade = require('./lib/etrade');
当从根目录中的server.js
执行时,一切正常,但在拆分项目中,捕获变量现在出现在routes文件夹中的index.js
中,并且不起作用。客户端报告无法找到eTrade库。这里有些东西我不理解,可能是关于如何解决require中的路径规范。
与此同时,我使用一个全局变量来完成工作,我从根目录中的app.js
传递到routes文件夹中的index.js
。我可以通过这种方式继续开发,但如果我了解如何使第一个变体发挥作用会更好。
请编辑问题并显示您的文件层次结构,然后告诉我们您如何合并文件?您使用了哪些工具,输出在哪里
server.js在root中运行并且运行良好。 app.js在根目录中运行,是合并系统的A部分并且有效。 index.js在root / routes文件夹中运行,是合并系统的B部分,但失败了。 root / lib / eTrade包含eTrade模块。
工作片段(server.js)在eTrade网站上打开一个确认窗口,用户复制/粘贴一个确认代码,该代码将回显到服务器端的控制台。失败的片段是A和B的组合,拒绝将变量(确认码)传递给B,因为它报告找不到eTrade库,我认为问题是require语句中的路径,是
var etrade = require(' ./ lib / etrade');
合并系统执行任务的第一部分,但不会将变量传递给任务的第二部分,我认为这是因为B中的变量超出了范围。
以下是工作片段:
/*
* Module dependencies
*/
const port = 3000
var express = require('express')
, stylus = require('stylus')
, nib = require('nib')
, logger = require('morgan')
, routes = require('./routes/index')
, users = require('./routes/users')
,app = express()
function compile(str, path) {
return stylus(str)
.set('filename', path)
.use(nib());
}
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
//app.use('/', routes);
//app.use('/users', users);
app.use(logger('dev'));
app.use(stylus.middleware(
{ src: __dirname + '/public'
, compile: compile
}
));
app.use(express.static(__dirname + '/public'))
//from expressSite
// from readme
var etrade = require('./lib/etrade');
var configuration =
{
useSandbox : true, // true if not provided
key : '', //actual value deleted
secret : '' //actual value deleted
}
var et = new etrade(configuration);
//here we send the user a credentials link
et.getRequestToken(
function(authorizationUrl) {
// Your service requires users, who will need to visit
// the following URL and, after logging in and
// authorizing your service to access their account
// data, paste the E*TRADE provided verification
// code back into your application.
app.get('/', function (req, res) {
res.render('AuthApp',
{ authLink : authorizationUrl }
)
});
console.log("AuthorizationURL " + authorizationUrl + " "); },
function(error) {
console.log("Error encountered while attempting " +
"to retrieve a request token: " +
error);
}
); //end getRequestToken
//user sends confirmation code and we get acesss token
app.get('/users/sendcode', function (req, res) {
console.log('verification code is '+req.query.vCode);
//end get verification code
et.getAccessToken(req.query.vCode,
function() {
// Your app can start using other E*TRADE API now
// begin main interaction
// this is where we should land first after oath
// hand it over to the db page?
//et.listAccounts();
//console.log(a);
res.render('ETQuery');
console.log('thread entered getAccessToken function')
// console.log(AccessToken)
},
function(error) {
console.log("Error encountered while attempting " +
"to exchange request token for access token: " +
error);
}
);
})
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`CIA is listening to the FSB on ${port}`)
})
以下是根目录中app.js中的新部分A代码。您可以看到我是如何修补它以使用全局的。
var etrade = require('./lib/etrade');
var configuration =
{
useSandbox : true, // true if not provided
key : '', //actual value deleted
secret : '' //actual value deleted
}
var et = new etrade(configuration);
// here we send the user a credentials link
et.getRequestToken(
function(authorizationUrl) {
// Your service requires users, who will need to visit
// the following URL and, after logging in and
// authorizing your service to access their account
// data, paste the E*TRADE provided verification
// code back into your application.
// app.get('/', function (req, res) {
// res.render('index',
// { authLink : authorizationUrl }
// )
// });
console.log("AuthorizationURL is " + authorizationUrl + " ");
global.ETauthUrl = authorizationUrl;
},
function(error) {
console.log("Error encountered while attempting " +
"to retrieve a request token: " +
error);
}
); //end getRequestToken
但是B部分没有捕获令牌。这里奇怪的是报告失败是为了找到eTrade库,而在B中没有引用该库。在工作片段中,我无法将令牌传递到server.js之外但我可以在服务器端报告它用户粘贴后,点击客户端的发送按钮。这是B。
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index',
{ authLink : ETauthUrl }
)
});
这仅仅是因为全局变量。
答案 0 :(得分:0)
./...
告诉NodeJS从当前目录加载适用的代码。这将在应用程序的根目录server.js
中运行。但是,要从另一个目录中正确引用所述文件,您需要正确引用它的路径。
<强> E.g。给定强>:
bootstrap/
├── lib/
│ ├── etrade.js
├── modules/
│ ├── foo.js
| ├── bar/
| ├── bar.js
└── server.js
您需要在etrade
中引用server.js
作为:
var etrade = require('./lib/etrade');
在modules/foo.js
中:
var etrade = require('../lib/etrade');
在modules/bar/bar.js
中:
var etrade = require('../../lib/etrade');
More on how NodeJS require
resolves files
require(X) from module at path Y 1. If X is a core module, a. return the core module b. STOP 2. If X begins with './' or '/' or '../' a. LOAD_AS_FILE(Y + X) b. LOAD_AS_DIRECTORY(Y + X) 3. LOAD_NODE_MODULES(X, dirname(Y)) 4. THROW "not found" LOAD_AS_FILE(X) 1. If X is a file, load X as JavaScript text. STOP 2. If X.js is a file, load X.js as JavaScript text. STOP 3. If X.json is a file, parse X.json to a JavaScript Object. STOP 4. If X.node is a file, load X.node as binary addon. STOP LOAD_AS_DIRECTORY(X) 1. If X/package.json is a file, a. Parse X/package.json, and look for "main" field. b. let M = X + (json main field) c. LOAD_AS_FILE(M) 2. If X/index.js is a file, load X/index.js as JavaScript text. STOP 3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP 4. If X/index.node is a file, load X/index.node as binary addon. STOP LOAD_NODE_MODULES(X, START) 1. let DIRS=NODE_MODULES_PATHS(START) 2. for each DIR in DIRS: a. LOAD_AS_FILE(DIR/X) b. LOAD_AS_DIRECTORY(DIR/X) NODE_MODULES_PATHS(START) 1. let PARTS = path split(START) 2. let I = count of PARTS - 1 3. let DIRS = [] 4. while I >= 0, a. if PARTS[I] = "node_modules" CONTINUE b. DIR = path join(PARTS[0 .. I] + "node_modules") c. DIRS = DIRS + DIR d. let I = I - 1 5. return DIRS