节点需要绝对路径

Posted

技术标签:

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

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

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

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

【问题讨论】:

类似问题:***.com/questions/10860244/… 【参考方案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 所引用的。根据那篇文章,您有两个真正的选择:

    使用相对文件路径。 使用 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

使用它的三个简单步骤。

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

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

     require('sexy-require');
     const routers = require('/routers');
     const api = require('$api');
     ...
    

    可选步骤。路径配置可以在项目根目录的.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');

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

【讨论】:

以上是关于节点需要绝对路径的主要内容,如果未能解决你的问题,请参考以下文章

从节点 fs 模块中的绝对路径读取本地文件

在我们的私有节点依赖项中使用绝对路径?

如何从 response.body 获取节点中 '<img src=''>' 的绝对路径

xpath路径表达式

爬虫相关知识(二 )xpath

Gatsby JSON 中的绝对图像路径