节点需要绝对路径

时间:2014-01-20 09:08:12

标签: javascript node.js express directory

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

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

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

5 个答案:

答案 0 :(得分:18)

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

  • 核心模块,例如fs
  • 您在require调用中指定的相对文件路径
  • 目录搜索node_modules文件夹中相应命名的模块,该文件夹位于调用require函数的文件的父目录中的某个位置。

请参阅: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文件时发生变化。

总之,请参阅Piotr Kowalczuk上面提到的How to make the require in node.js to be always relative to the root folder of the project?。根据该帖子,您有两个真正的选择:

  1. 使用相对文件路径。
  2. 将您想要的资源打包为具有package.json文件的真实模块,并将其放入node_modules文件夹。
  3. 最后,请记住,您尝试做的事情违背了您正在使用的程序。我认为这是一个案例,你最终会通过使用Node的粒度和使用相对文件路径来使你的生活更轻松(和你的合作者!)。

答案 1 :(得分:8)

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

所以,我喜欢干净的代码,require内部这样一条丑陋的道路让我感到害怕。我找到了许多解决方案如何解决它,但我喜欢的是在Linux系统下完美但不适用于Windows。然后我决定解决它。

性感要求

在某些项目中测试后,我决定制作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
    

  4. 路径列表

    您项目中的任何位置都可以获得已定义的快捷方式路径:

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

答案 2 :(得分:1)

似乎模块加载功能会在node_modules/前加上参数。例如,将以下脚本放入/tmp/t.js

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

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

  • /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/子目录,则根本不会查找与脚本相关的任何位置。

答案 3 :(得分:0)

global.__require = function (file) {
  return require(__dirname + '/' + file)
}

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

const foo = __require('src/foo')

我使用双下划线作为对__dirname的颂歌,但您可以将其重命名!

答案 4 :(得分:0)

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

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

现在告诉我您如何知道需要选择哪个配置文件。
解: user.js

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

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