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

例如,如果查看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://github.com/raaymax/irequire

你可以用它来代替require。

irequire.prefix('controllers',join.path(__dirname,'app/master'));
var adminUsersCtrl = irequire("controllers:admin/users");
var net = irequire('net');

也许它会对某人有用。

其他回答

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

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

/../变成了../

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

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

在你的例子文件中

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

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

这只是个人喜好。

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

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

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

手动符号链接(和Windows连接)

examples目录中不能包含一个node_modules,该node_modules带有指向项目根目录的符号链接吗?/因此允许示例使用require('project'),尽管这并没有删除映射,但它允许源代码使用require('project')而不是require('../../')。

我已经对此进行了测试,它确实适用于v0.6.18。

项目目录清单:

$ ls -lR project
project:
drwxr-xr-x 3 user user 4096 2012-06-02 03:51 examples
-rw-r--r-- 1 user user   49 2012-06-02 03:51 index.js

project/examples:
drwxr-xr-x 2 user user 4096 2012-06-02 03:50 node_modules
-rw-r--r-- 1 user user   20 2012-06-02 03:51 test.js

project/examples/node_modules:
lrwxrwxrwx 1 user user 6 2012-06-02 03:50 project -> ../../

index.js的内容将一个值赋给exports对象的一个属性,并调用console.log,并用一条消息声明它是必需的。test.js的内容是require('project')。

自动化的符号链接

手动创建符号链接的问题是,每次你npm ci时,你都会丢失符号链接。如果您使符号链接进程成为依赖项,那么就没有问题。

模块basetag是一个postinstall脚本,它在每次运行npm install或npm ci时创建一个名为$的符号链接(或Windows连接):

npm install --save basetag
node_modules/$ -> ..

这样,您就不需要对代码或require系统进行任何特殊修改。$成为您可以从中进行请求的根。

var foo = require('$/lib/foo.js');

如果你不喜欢使用$,而更喜欢#或其他(除了@,这是npm的一个特殊字符),你可以fork它并进行更改。

注意:虽然Windows符号链接(到文件)需要管理员权限,但Windows连接(到目录)不需要管理员权限。这是一种安全、可靠、跨平台的解决方案。

我实现这一点的方法是创建“本地链接模块”。

的文件夹结构为例

db ¬ 
    models ¬
        index.js
    migrations
    seed
    config.json

routes ¬
    index.js
    user ¬
        index.js

如果从。/routes/user/index.js我想访问/db/models/index.js我会写

require('../../db/models/index.js')

为了使/db/models/index.js可以从任何地方访问,我在db文件夹中创建了一个名为_module_的文件夹,其中包含一个包。Json和一个main.js文件。

# package.json
{
    "name": "db", <-- change this to what you want your require name to be
    "version": "1.0.0",
    "description": "",
    "author": "",
    "repository": {},
    "main": "main.js"
}
// main.js
module.exports = require('../../db/models/index');

main.js中的路径必须是相对的,就像文件在node_modules中一样

node_modules ¬
    db ¬
        main.js

然后你可以运行npm install ./db/_module_,这将把。/db/_module_中的文件复制到。/node_modules/db中,在应用程序包的依赖项下创建一个条目。json之类的

"db": "file:db/_module_"

您现在可以在任何地方使用此包

const db = require('db');

当你运行npm install时,它会自动安装你的其他模块,工作跨平台(没有符号链接),并且不需要第三方包。

我创建了一个名为rekiure的节点模块

它允许您在不使用相对路径的情况下进行要求

https://npmjs.org/package/rekuire

它非常容易使用