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

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


当前回答

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

的文件夹结构为例

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时,它会自动安装你的其他模块,工作跨平台(没有符号链接),并且不需要第三方包。

其他回答

在您自己的项目中,您可以修改根目录中使用的任何.js文件,并将其路径添加到进程的属性中。env变量。例如:

// in index.js
process.env.root = __dirname;

之后,您可以在任何地方访问该属性:

// in app.js
express = require(process.env.root);

大局

这看起来“真的很糟糕”,但要给它时间。事实上,它真的很好。显式的require()提供了完全的透明性和易于理解,就像项目生命周期中的一股新鲜空气。

可以这样想:你正在阅读一个例子,尝试Node.js,你认为它“在我看来真的很糟糕”。你在质疑Node.js社区的领导者,他们比任何人都花了更多的时间来编写和维护Node.js应用程序。作者犯这样一个新手错误的可能性有多大?(我同意,从我的Ruby和Python背景来看,乍一看这像是一场灾难。)

围绕Node.js有很多炒作和反炒作。但是当尘埃落定后,我们将承认显式模块和“本地优先”包是采用的主要驱动力。

一般情况

当然,首先搜索当前目录中的node_modules,然后是父目录、祖父目录、曾祖父目录等等。所以您已经安装的包已经以这种方式工作了。通常你可以从项目中的任何地方要求(“express”),它工作得很好。

如果您发现自己正在从项目的根目录加载公共文件(可能是因为它们是公共实用程序函数),那么这就是一个很大的线索,说明是时候创建包了。包非常简单:将文件移动到node_modules/,并放入package.json 在那里。瞧!整个项目都可以访问该名称空间中的所有内容。包是将代码放入全局名称空间的正确方法。

其他解决方法

我个人不使用这些技巧,但它们确实回答了你的问题,当然你比我更了解自己的情况。

您可以将$NODE_PATH设置为项目根目录。当您需要()时,将搜索该目录。

接下来,您可以折衷一下,从所有示例中要求一个通用的本地文件。该通用文件只是重新导出祖父目录中的真实文件。

Examples /downloads/app.js(以及其他类似的文件)

var express = require('./express')

/下载/ express.js例子

module.exports = require('../../')

现在当你重新定位这些文件时,最坏的情况是修复一个垫片模块。

另一个答案是:

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

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"

我正在寻找完全相同的简单性,要求文件从任何级别,我发现模块-别名。

安装:

npm i --save module-alias

打开你的包裹。Json文件,在这里你可以为你的路径添加别名,例如。

"_moduleAliases": {
 "@root"      : ".", // Application's root
 "@deep"      : "src/some/very/deep/directory/or/file",
 "@my_module" : "lib/some-file.js",
 "something"  : "src/foo", // Or without @. Actually, it could be any string
}

使用你的别名只需:

require('module-alias/register')
const deep = require('@deep')
const module = require('something')

我编写了这个小包,它允许您通过项目根的相对路径来要求包,而不引入任何全局变量或覆盖节点默认值

https://github.com/Gaafar/pkg-require

它是这样工作的

// create an instance that will find the nearest parent dir containing package.json from your __dirname
const pkgRequire = require('pkg-require')(__dirname);

// require a file relative to the your package.json directory 
const foo = pkgRequire('foo/foo')

// get the absolute path for a file
const absolutePathToFoo = pkgRequire.resolve('foo/foo')

// get the absolute path to your root directory
const packageRootPath = pkgRequire.root()