【问题标题】:Node require absolute path节点需要绝对路径
【发布时间】:2014-02-09 09:12:02
【问题描述】:

我有一个如下所示的目录:

-- app/
   |- models/
      |- user.js
   |- config.json

我希望我的 user.js 文件需要 config.json。现在我正在使用require('/config'),但这不起作用。我究竟做错了什么?我想避免使用require('../config')

【问题讨论】:

标签: javascript node.js express directory


【解决方案1】:

简单的答案是您没有做错任何事。根据一些研究,require 函数会寻找以下之一:

  • fs 等核心模块
  • 您在 require 调用中指定的相对文件路径
  • 在调用 require 函数的文件的父目录中某处的 node_modules 文件夹中的目录搜索适当命名的模块。

见:http://www.bennadel.com/blog/2169-Where-Does-Node-js-And-Require-Look-For-Modules-.htm 还有:http://nodejs.org/api/modules.html#loading_from_node_modules_Folders

以上两个资源都提到了修改 NODE_PATH 环境变量的能力,但是这听起来是非常糟糕的做法,并且至少会使您的代码的可移植性降低。它甚至可能不适用于像 config.json 这样的文件,因为尽管我从未这样做过,但我想更改 NODE_PATH 变量只会更改 require() 查找与真实模块相对应的 package.json 文件。

总而言之,请参阅:How to make the require in node.js to be always relative to the root folder of the project?,如上面 Piotr Kowalczuk 所引用的。根据那篇文章,您有两个真正的选择:

  1. 使用相对文件路径。
  2. 使用 package.json 文件将所需资源打包为真正的模块并将其放入 node_modules 文件夹中。

最后,请记住,您尝试做的事情与您正在使用的程序的本质背道而驰。我认为这是一种情况,通过使用 Node 的颗粒并按照设计的意图使用相对文件路径,最终会让你的生活(以及你的合作者!)变得更轻松。

【讨论】:

    【解决方案2】:

    我找不到比编写自己的模块更好的解决方案了。

    在一些项目中对其进行测试后,我决定制作it open source

    const user = require('../../../database/user'); // ? what you have
    // OR
    const user = require('$db/user'); // ? no matter how deep you are
    const product = require('/database/product'); // ? alias or pathing from root directory
    

    使用它的三个简单步骤。

    1. 安装包:npm install sexy-require --save

    2. 在主应用程序文件的顶部包含一次require('sexy-require')

       require('sexy-require');
       const routers = require('/routers');
       const api = require('$api');
       ...
      
    3. 可选步骤。路径配置可以在项目根目录的.paths文件中定义。

       $db = /server/database
       $api-v1 = /server/api/legacy
       $api-v2 = /server/api/v2
      

    您可以在项目中的任何位置获取已定义的快捷路径:

    const path = require(`sexy-require`);
    console.log(path.$db); // -> '/full/path/to/app/server/database'
    

    【讨论】:

    • @PakpoomTiwakornkit 您能否在 github 中打开问题单并提供有关如何获得问题的更多信息?我会努力解决的。
    • @sultan 我错了。对不起:)
    • @PakpoomTiwakornkit 很奇怪,为什么我的回答会受到负面影响,是不是有些错误?
    • @sultan 现在已经锁定,所以我无法撤消我的反对票。我已经编辑了您的答案,我正在等待审核并撤消我的反对票。对不起我的激进行为。
    • @sultan 审阅者没有批准我对您的答案的修改,因此仍无法撤消否决票。您能否编辑您的答案,以便我撤消它?
    【解决方案3】:

    似乎模块加载功能将node_modules/ 添加到参数中。例如,将以下脚本放入/tmp/t.js

    meow = require('meow/meow.js');
    

    创建 (mkdir) /tmp/node_modules/ 并尝试使用 BSD 的 ktrace(或 Linux 的 strace,提供类似的功能)运行它。节点将尝试打开以下内容:

    • /tmp/node_modules/meow/meow.js
    • /tmp/node_modules/meow/meow.js.js
    • /tmp/node_modules/meow/meow.js.json
    • /tmp/node_modules/meow/meow.js.node
    • /tmp/node_modules/meow/meow.js/package.json
    • /tmp/node_modules/meow/meow.js/index.js
    • /tmp/node_modules/meow/meow.js/index.json
    • /tmp/node_modules/meow/meow.js/index.node

    如果您的脚本旁边没有 node_modules/ 子目录,则它根本不会在与您的脚本相关的任何地方查找。

    【讨论】:

      【解决方案4】:
      global.__require = function (file) {
        return require(__dirname + '/' + file)
      }
      

      将其放在入口点文件的顶部(例如,index.js)。然后你就可以使用

      const foo = __require('src/foo').

      我使用双下划线作为__dirname 的颂歌,但你可以重命名它!

      【讨论】:

        【解决方案5】:

        我认为我们不需要讨论这个问题。 为方便开发人员而设计。
        如果我们需要 /config.json,可能子文件夹中有很多 config.json,这通常会使它更难理解

        -- app/
           |- controller
              |- config.json(2) 
           |- models/
              |- user.js
              |- config.json(3)
           |- config.json(1)
        
        

        现在告诉我你是如何知道你需要选择哪个配置文件的。
        解决方案: 用户.js

        var config1 = require('../config.json');
        var config2 = require('../controller/config.json');
        var config3 = require('./config.json');
        

        如果只有一个配置,您最好将其放入全局变量并从那里使用它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-03-23
          • 1970-01-01
          • 1970-01-01
          • 2018-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-24
          相关资源
          最近更新 更多