节点需要绝对路径
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');
如果只有一个配置,您最好将其放入全局变量并从那里使用它。
【讨论】:
以上是关于节点需要绝对路径的主要内容,如果未能解决你的问题,请参考以下文章