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

例如,如果查看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/


当前回答

如果有人正在寻找另一种方法来解决这个问题,这里是我自己的贡献:

https://www.npmjs.com/package/use-import

基本思路:在项目的根目录中创建一个JSON文件,将文件路径映射为简写名称(或者让use-automapper为您完成)。然后您可以使用这些名称请求您的文件/模块。像这样:

var use = require('use-import');
var MyClass = use('MyClass');

就是这样。

其他回答

尝试使用asapp:

NPM安装——保存为app

https://www.npmjs.com/package/asapp

var { controller, helper, middleware, route, schema, model, APP, ROOT } = require('asapp')

Controller ('home')改为require('../../controllers/home)

你可以在app.js中定义这样的东西:

requireFromRoot = (function(root) {
    return function(resource) {
        return require(root+"/"+resource);
    }
})(__dirname);

然后任何时候你想从根目录中要求一些东西,无论你在哪里,你只需要使用requireFromRoot而不是普通的require。到目前为止对我来说还不错。

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

以其他已知项目(如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定义为函数——这将允许我们根据环境需要不同的模块——但这超出了这个线程的范围。

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

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

/../变成了../

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

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

在你的例子文件中

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

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

这只是个人喜好。

另一个答案是:

想象一下这个文件夹结构:

node_modules lodash src 子目录 foo.js bar.js main.js 测试 . js

然后在test.js中,你需要这样的文件:

const foo = require("../src/subdir/foo");
const bar = require("../src/subdir/bar");
const main = require("../src/main");
const _ = require("lodash");

在main.js中:

const foo = require("./subdir/foo");
const bar = require("./subdir/bar");
const _ = require("lodash");

现在你可以使用。babelrc文件中的babel和babel插件模块解析器来配置两个根文件夹:

{
    "plugins": [
        ["module-resolver", {
            "root": ["./src", "./src/subdir"]
        }]
    ]
}

现在你可以在测试和src中以同样的方式要求文件:

const foo = require("foo");
const bar = require("bar");
const main = require("main");
const _ = require("lodash");

如果你想使用es6模块语法:

{
    "plugins": [
        ["module-resolver", {
            "root": ["./src", "./src/subdir"]
        }],
        "transform-es2015-modules-commonjs"
    ]
}

然后像这样在测试和SRC中导入文件:

import foo from "foo"
import bar from "bar"
import _ from "lodash"