我想要求我的文件总是通过我的项目的根,而不是相对于当前模块。

例如,如果查看https://github.com/visionmedia/express/blob/2820f2227de0229c5d7f28009aa432f9f3a7b5f9/examples/downloads/app.js第6行,您将看到

express = require('../../')

在我看来,这真的很糟糕。假设我想让我所有的例子都只靠近根结点一层。这是不可能的,因为我必须更新超过30个例子,并且在每个例子中更新很多次。:

express = require('../')

我的解决方案是有一个基于根的特殊情况:如果字符串以$开头,那么它相对于项目的根文件夹。

任何帮助都是感激的,谢谢

更新2

现在我使用require.js,它允许你以一种方式编写,在客户端和服务器上都可以工作。Require.js还允许你创建自定义路径。

更新3

现在我转移到webpack + gulp,我使用enhanced-require来处理服务器端模块。看这里的基本原理:http://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/


当前回答

我尝试过很多这样的解决方案。我最终把这个添加到我的主文件的顶部(例如index.js):

process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();

这将在加载脚本时将项目根添加到NODE_PATH。允许我通过引用项目根的相对路径,如var User = require('models/ User '),来要求项目中的任何文件。只要在项目中运行其他任何东西之前在项目根目录中运行一个主脚本,这个解决方案就应该有效。

其他回答

在简单的行中,你可以调用自己的文件夹为module:

为此,我们需要:global和app-module-path module

这里“App-module-path”是模块,它允许你添加额外的目录到Node.js模块搜索路径 global的意思是,你附加到这个对象的任何东西b在你的应用中都是可用的。

现在看一下这个片段:

global.appBasePath = __dirname;

require('app-module-path').addPath(appBasePath);

__dirname为节点当前运行目录。您可以在这里给出自己的路径来搜索模块的路径。

我们准备尝试一种新的方法来解决这个问题。

以其他已知项目(如spring和guice)为例,我们将定义一个“context”对象,它将包含所有的“require”语句。

该对象将被传递给所有其他模块使用。

例如

var context = {}

context.module1 = require("./module1")( { "context" : context } )
context.module2 = require("./module2")( { "context" : context } )

这要求我们将每个模块编写为一个接收选项的函数,这对我们来说是一个最佳实践。

module.exports = function(context){ ... }

然后你会引用上下文而不是要求东西。

var module1Ref = context.moduel1;

如果您愿意,可以轻松地编写一个循环来执行require语句

var context = {};
var beans = {"module1" : "./module1","module2" : "./module2" }; 
for ( var i in beans ){
    if ( beans.hasOwnProperty(i)){
         context[i] = require(beans[i])(context);
    }
};

当您想要模拟(测试)时,这将使工作变得更容易,并且在使代码作为包可重用的同时解决了您的问题。

您还可以通过分离bean声明来重用上下文初始化代码。 例如,你的main.js文件可能是这样的

var beans = { ... }; // like before
var context = require("context")(beans); // this example assumes context is a node_module since it is reused.. 

这种方法也适用于外部库,不需要每次我们需要它们时都硬编码它们的名称-但是它需要特殊处理,因为它们的导出不是需要上下文的函数。

稍后,我们还可以将bean定义为函数——这将允许我们根据环境需要不同的模块——但这超出了这个线程的范围。

虽然这些答案工作,但他们没有解决npm测试的问题

例如,如果我在server.js中创建一个全局变量,它将不会为我的测试套件执行设置。

设置全局apot变量,避免../../..在npm start和npm test中都可以使用,参见:

Mocha使用额外的选项或参数进行测试

请注意,这是新的官方摩卡解决方案。

我认为你不需要用你描述的方式来解决这个问题。如果您想在大量文件中更改相同的字符串,请使用sed。在你的例子中,

find . -name "*.js" -exec sed -i 's/\.\.\/\.\.\//\.\.\//g' {} +

/../变成了../

或者,您可以要求配置文件存储包含库路径的变量。如果您将以下文件存储为config.js在示例目录中

var config = {};
config.path = '../../';

在你的例子文件中

myConfiguration = require('./config');
express = require(config.path);

您将能够从一个文件控制每个示例的配置。

这只是个人喜好。

感谢所有发帖的人,这篇帖子给我指明了正确的方向。由于提出的解决方案没有一个像我想要的那样简洁,我想在这里分享我的解决方案。

我一直在寻找一种解决方案,不“需要”任何额外的东西,没有模块,没有包。Json mod,没有环境变量,没有外部依赖,最小的CPU周期…

...所以我想到了这个:

全球。Dir = process.cwd();

我在应用程序加载时这样做一次。显然,您可以通过添加子目录和/或添加'/..,它将根据需要将您发送到目录树的上下。

在所有文件中,所有my include都是这样的格式:

找生气。(你,兄弟,妙/妙以致)