require路径在root中工作但在其他地方不起作用

时间:2017-01-09 11:00:50

标签: node.js path require resolve

在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 }
      )
});

这仅仅是因为全局变量。

1 个答案:

答案 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