【问题标题】:require path works in root but not in elsewhere要求路径在根目录中有效,但在其他地方无效
【发布时间】:2017-05-23 15:00:55
【问题描述】:

在 Node.js 中工作时,我将一个工作的 sn-p 拆分为两个产生相同结果的 sn-ps。工作的 sn-p 有一个 require 语句并且位于根目录中。拆分的两个段在根目录中的第一阶段工作,但第二阶段失败并报告找不到 eTrade 库。这是要求声明。

var etrade = require('./lib/etrade');

从根目录中的server.js 执行时,一切正常,但在拆分项目中,捕获变量现在出现在路由文件夹中的index.js 中并且不起作用。客户端报告找不到 eTrade 库。这里有一些我不明白的地方,可能是关于如何解决 require 中的路径规范。

与此同时,我使用从根目录中的app.js 传递到路由文件夹中的index.js 的全局变量来使事情正常工作。我可以以这种方式继续开发,但如果我了解如何使第一个变体工作会更好。

请编辑问题并显示您的文件层次结构,然后向我们展示您如何合并文件?你使用了哪些工具,输出在哪里

server.js 在根目录下运行并且运行良好。 app.js 在根目录中运行,是合并系统的 A 部分并且可以正常工作。 index.js 在 root/routes 文件夹中运行,是合并系统的 B 部分并且失败。 root/lib/eTrade 包含 eTrade 模块。

工作的 sn-p (server.js) 在 eTrade 网站上打开一个确认窗口,用户复制/粘贴一个确认代码,该代码回显到服务器端的控制台。失败的sn-p是A和B的组合,拒绝将变量(确认码)传递给B,因为它报告找不到eTrade库,我认为问题是require语句中的路径,即

var etrade = require('./lib/etrade');

合并后的系统执行任务的第一部分,但没有将变量传递给任务的第二部分,我认为这是因为 B 中的变量超出了范围。

这里是工作的 sn-p:

/*
 * 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 中没有引用该库。在工作的 sn-p 中,我无法将令牌传递到 server.js 之外,但我可以在用户将其粘贴并点击客户端的发送按钮后的服务器端。这是B。

var router = express.Router();

/* GET home page. */
router.get('/', function(req, res) {
  res.render('index',
        { authLink : ETauthUrl }
      )
});

这只是因为全局变量才有效。

【问题讨论】:

  • 我们可以给一些代码吗?
  • 请编辑问题并显示您的文件层次结构,然后向我们展示您如何合并文件?您使用了哪些工具,输出在哪里

标签: node.js path require resolve


【解决方案1】:

./... 告诉 NodeJS 从当前目录加载适用的代码。这将在应用程序根目录的server.js 中运行。但是,要从另一个目录正确引用所述文件,您需要正确引用它的路径。

例如给定

bootstrap/
├── lib/
│   ├── etrade.js
├── modules/
│   ├── foo.js
|   ├── bar/
|       ├── bar.js
└── server.js

您需要在server.js 中引用etrade

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.

来自路径 Y 的模块的 require(X) 1. 如果 X 是核心模块,a。返回核心模块 b.停止 2. 如果 X 以 './' 或 '/' 或 '../' 开头LOAD_AS_FILE(Y + X) b. LOAD_AS_DIRECTORY(Y + X) 3. LOAD_NODE_MODULES(X, 目录名(Y)) 4. 抛出“未找到” LOAD_AS_FILE(X) 1. 如果 X 是文件,则将 X 作为 JavaScript 文本加载。停止 2. 如果 X.js 是文件,则将 X.js 作为 JavaScript 文本加载。停止 3. 如果 X.json 是文件,则将 X.json 解析为 JavaScript 对象。停止 4. 如果 X.node 是文件,则将 X.node 作为二进制插件加载。停止 LOAD_AS_DIRECTORY(X) 1. 如果 X/package.json 是一个文件,a.解析 X/package.json,并查找“main”字段。湾。让 M = X + (json main field) c. LOAD_AS_FILE(M) 2. 如果 X/index.js 是文件,则将 X/index.js 加载为 JavaScript 文本。停止 3. 如果 X/index.json 是文件,则将 X/index.json 解析为 JavaScript 对象。停止 4. 如果 X/index.node 是一个文件,加载 X/index.node 作为二进制插件。停止 LOAD_NODE_MODULES(X,开始) 1. 让 DIRS=NODE_MODULES_PATHS(START) 2. 对于 DIRS 中的每个 DIR: LOAD_AS_FILE(DIR/X) b. LOAD_AS_DIRECTORY(目录/X) NODE_MODULES_PATHS(开始) 1. 让 PARTS = 路径分割(START) 2. 让 I = 零件数 - 1 3. 让 DIRS = [] 4. 当 I >= 0 时,a。如果 PARTS[I] = "node_modules" 继续 b。 DIR = 路径连接(PARTS[0 .. I] + "node_modules") c. DIRS = DIRS + DIR让我 = 我 - 1 5.返回DIRS

【讨论】:

    猜你喜欢
    • 2017-04-05
    • 2011-03-21
    • 1970-01-01
    • 2020-06-22
    • 2014-02-06
    • 2020-02-23
    • 2015-05-11
    • 2019-09-05
    • 1970-01-01
    相关资源
    最近更新 更多