261

我想始终要求我的文件始终位于项目的根目录下,而不是相对于当前模块。

例如,如果您查看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 并使用增强的需求来处理服务器端的模块。请参阅此处的理由:http ://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/

4

37 回答 37

171

那么:

var myModule = require.main.require('./path/to/module');

它需要该文件,就好像它是主 js 文件所需要的一样,因此只要您的主 js 文件位于项目的根目录下,它就可以很好地工作......这是我很欣赏的。

于 2014-10-02T15:09:56.807 回答
131

Browserify 手册中有一个非常有趣的部分:

避免../../../../../../..

并非应用程序中的所有内容都正确地属于公共 npm,并且在许多情况下,设置私有 npm 或 git repo 的开销仍然相当大。以下是一些避免 ../../../../../../../相对路径问题的方法。

节点模块

人们有时反对将特定于应用程序的模块放入 node_modules 中,因为在不从 npm 中签入第三方模块的情况下,如何签入内部模块并不明显。

答案很简单!如果您有一个.gitignore忽略的文件node_modules

node_modules

您可以!为每个内部应用程序模块添加一个例外:

node_modules/*
!node_modules/foo
!node_modules/bar

请注意,如果父目录已被忽略,则不能取消忽略子目录。因此,您必须使用 技巧忽略内部node_modules的每个目录,而不是忽略 ,然后您可以添加异常。 node_modulesnode_modules/*

现在,在您的应用程序中的任何地方,您都可以拥有require('foo')require('bar')不拥有非常大且脆弱的相对路径。

如果您有很多模块,并且希望将它们与 npm 安装的第三方模块分开,您可以将它们全部放在一个目录下,node_modules例如node_modules/app

node_modules/app/foo
node_modules/app/bar

现在,您将能够在您的应用程序中的任何地方来往require('app/foo')require('app/bar') 来自任何地方。

在您的.gitignore中,只需添加一个例外node_modules/app

node_modules/*
!node_modules/app

如果您的应用程序在 package.json 中配置了转换,则需要在您的node_modules/foonode_modules/app/foo组件目录中创建一个具有自己的转换字段的单独的 package.json,因为转换不会跨模块边界应用。这将使您的模块对应用程序中的配置更改更加健壮,并且更容易在应用程序之外独立重用包。

符号链接

如果您正在开发一个可以创建符号链接且不需要支持 windows 的应用程序,另一个方便的技巧是将一个lib/app/文件夹符号链接到node_modules. 从项目根目录,执行:

ln -s ../lib node_modules/app

现在,您可以在项目中的任何地方lib/通过执行require('app/foo.js')来获取文件lib/foo.js

自定义路径

您可能会看到一些地方谈论使用$NODE_PATH 环境变量或opts.paths为 node 和 browserify 添加目录以查找模块。

与大多数其他平台不同,与有效使用目录相比,在节点中使用 shell 样式的路径目录数组$NODE_PATH并不那么有利node_modules

这是因为您的应用程序与运行时环境配置的耦合更加紧密,因此有更多移动部件,并且您的应用程序只有在您的环境设置正确时才能工作。

node 和 browserify 都支持但不鼓励使用 $NODE_PATH.

于 2014-07-08T11:44:37.890 回答
89

我喜欢node_modules为共享代码创建一个新文件夹,然后让 node 和 require 做它最擅长的事情。

例如:

- node_modules // => these are loaded from your package.json
- app
  - node_modules // => add node-style modules
    - helper.js
  - models
    - user
    - car
- package.json
- .gitignore

例如,如果你在里面,car/index.js你可以require('helper')并且 node 会找到它!

node_modules 如何工作

node 有一个聪明的算法来解析模块,这在竞争对手的平台中是独一无二的。

如果您require('./foo.js')来自/beep/boop/bar.js,节点将./foo.js/beep/boop/foo.js. ./以或开头的路径../始终是调用require().

但是,如果您需要一个非相对名称,例如require('xyz')from /beep/boop/foo.js,节点会按顺序搜索这些路径,在第一个匹配时停止,如果没有找到则引发错误:

/beep/boop/node_modules/xyz
/beep/node_modules/xyz
/node_modules/xyz

对于每个xyz存在的目录,节点会首先查找xyz/package.json一个"main"字段是否存在。如果您使用目录路径,该"main"字段定义了哪个文件应该负责。require()

例如,如果/beep/node_modules/xyz是第一个匹配项并且/beep/node_modules/xyz/package.json具有:

{
  "name": "xyz",
  "version": "1.2.3",
  "main": "lib/abc.js"
}

然后出口/beep/node_modules/xyz/lib/abc.js将由 require('xyz').

如果没有package.json或没有"main"字段,index.js则假定:

/beep/node_modules/xyz/index.js
于 2014-06-27T22:23:45.500 回答
40

大图

这似乎“真的很糟糕”,但给它时间。事实上,它非常好。显式require()s 提供了完全的透明度和易于理解,就像在项目生命周期中呼吸新鲜空气一样。

可以这样想:您正在阅读一个示例,将您的脚趾浸入 Node.js 并且您已经确定它是“非常糟糕的 IMO”。你是 Node.js 社区的事后领导者,他们在编写和维护 Node.js 应用程序方面的时间比任何人都多。作者犯这种菜鸟错误的几率有多大?(我同意,从我的 Ruby 和 Python 背景来看,起初这似乎是一场灾难。)

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

常见情况

当然,node_modules从当前目录,然后是父目录,然后是祖父母、曾祖父母等等。因此,您安装的软件包已经以这种方式工作。通常,您可以require("express")从项目中的任何位置进行操作,并且效果很好。

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

其他解决方法

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

您可以设置$NODE_PATH为您的项目根目录。当您require().

接下来,您可以妥协并要求所有示例中的通用本地文件。该公用文件只是重新导出祖父目录中的真实文件。

示例/下载/app.js(以及许多其他喜欢它的人)

var express = require('./express')

示例/下载/express.js

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

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

于 2012-06-02T10:50:35.950 回答
21

如果你使用yarn而不是npm,你可以使用workspaces

假设我有一个services我希望更容易需要的文件夹:

.
├── app.js
├── node_modules
├── test
├── services
│   ├── foo
│   └── bar
└── package.json

要创建 Yarn 工作区,请在以下文件中创建一个package.json文件services folder

{
  "name": "myservices",
  "version": "1.0.0"
}

在你的主 package.json 添加:

"private": true,
"workspaces": ["myservices"]

yarn install从项目的根目录运行。

然后,在您的代码中的任何位置,您都可以执行以下操作:

const { myFunc } = require('myservices/foo')

而不是类似的东西:

const { myFunc } = require('../../../../../../services/foo')
于 2018-11-06T19:52:16.510 回答
20

看看node-rfr

就这么简单:

var rfr = require('rfr');
var myModule = rfr('projectSubDir/myModule');
于 2014-04-16T11:24:53.607 回答
14

process.cwd()在我的项目中使用。例如:

var Foo = require(process.cwd() + '/common/foo.js');

可能值得注意的是,这将导致require绝对路径,尽管我还没有遇到这个问题。

于 2015-06-10T04:11:31.747 回答
13

恕我直言,最简单的方法是将您自己的函数定义为GLOBAL对象的一部分。projRequire.js使用以下内容在项目的根目录中创建:

var projectDir = __dirname;

module.exports = GLOBAL.projRequire = function(module) {
  return require(projectDir + module);
}

在您的主文件中,在require任何特定于项目的模块之前:

// init projRequire
require('./projRequire');

之后,以下对我有用:

// main file
projRequire('/lib/lol');

// index.js at projectDir/lib/lol/index.js
console.log('Ok');


@Totty,我想出了另一种解决方案,它可能适用于您在评论中描述的情况。描述会tl;dr,所以我最好展示一张带有我的测试项目结构的图片。

于 2012-06-02T19:27:38.527 回答
11

假设您的项目根目录是当前工作目录,这应该可以工作:

// require built-in path module
path = require('path');

// require file relative to current working directory
config = require( path.resolve('.','config.js') );
于 2013-10-25T22:14:26.487 回答
11

这里有一个很好的讨论这个问题

我遇到了同样的架构问题:想要一种为我的应用程序提供更多组织和内部命名空间的方法,而无需:

  • 将应用程序模块与外部依赖项混合在一起,或者为特定于应用程序的代码使用私有 npm 存储库
  • 使用相对需求,这使得重构和理解更加困难
  • 使用符号链接或更改节点路径,这可能会掩盖源位置并且不能很好地与源代码控制配合使用

最后,我决定使用文件命名约定而不是目录来组织我的代码。结构看起来像:

  • npm-shrinkwrap.json
  • 包.json
  • 节点模块
    • ...
  • 源代码
    • 应用程序.js
    • app.config.js
    • app.models.bar.js
    • app.models.foo.js
    • 应用程序.web.js
    • app.web.routes.js
    • ...

然后在代码中:

var app_config = require('./app.config');
var app_models_foo = require('./app.models.foo');

要不就

var config = require('./app.config');
var foo = require('./app.models.foo');

和往常一样,可以从 node_modules 获得外部依赖项:

var express = require('express');

通过这种方式,所有应用程序代码都被分层组织成模块,并且可用于与应用程序根相关的所有其他代码。

主要缺点当然是在文件浏览器中,您无法展开/折叠树,就好像它实际上已组织到目录中一样。但我喜欢它非常明确地说明所有代码的来源,并且它不使用任何“魔法”。

于 2014-02-22T20:13:50.650 回答
10

一些答案是说最好的方法是将代码作为一个包添加到 node_module 中,我同意这可能是丢失../../../in 要求的最佳方法,但它们实际上都没有提供这样做的方法。

从版本开始2.0.0,您可以从本地文件安装包,这意味着您可以在根目录中创建包含所需所有包的文件夹,

-modules
 --foo
 --bar 
-app.js
-package.json

因此在 package.json 中,您可以将modules(或foobar)添加为一个包,而无需像这样发布或使用外部服务器:

{
  "name": "baz",
  "dependencies": {
    "bar": "file: ./modules/bar",
    "foo": "file: ./modules/foo"
  }
}

之后,npm install您可以使用 访问代码var foo = require("foo"),就像使用所有其他包一样。

更多信息可以在这里找到:

https://docs.npmjs.com/files/package.json#local-paths

在这里如何创建一个包:

https://docs.npmjs.com/getting-started/creating-node-modules

于 2016-12-10T17:28:31.810 回答
8

我已经尝试了许多这样的解决方案。我最终将它添加到我的主文件(例如 index.js)的顶部:

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

这会在加载脚本时将项目根目录添加到 NODE_PATH。这允许我通过从项目根目录引用其相对路径来要求我的项目中的任何文件,例如var User = require('models/user'). 只要您在项目根目录中运行主脚本,然后在项目中运行其他任何内容,此解决方案就应该有效。

于 2015-08-26T15:23:42.623 回答
8

您可以使用我制作的模块Undot。它没有什么先进的,只是一个助手,所以你可以简单地避免那些点地狱。

例子:

var undot = require('undot');
var User = undot('models/user');
var config = undot('config');
var test = undot('test/api/user/auth');
于 2016-07-07T18:27:00.640 回答
7

另一个答案:

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

  • 节点模块
    • 罗达什
  • 源代码
    • 子目录
      • 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");

现在你可以将babelbabel-plugin-module-resolver与 this 一起使用。babelrc文件来配置 2 个根文件夹:

{
    "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"
于 2017-11-13T13:41:55.507 回答
6

您可以在 app.js 中定义类似的内容:

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

然后任何时候你想从根中获取一些东西,无论你在哪里,你只需要使用 requireFromRoot 而不是原版的 require。到目前为止对我来说效果很好。

于 2013-06-28T23:53:08.127 回答
5

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

目录是否不能examples包含node_modules带有指向项目根目录的符号链接的a ,project -> ../../从而允许示例使用require('project'),尽管这不会删除映射,但它确实允许源使用require('project')而不是require('../../').

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

目录列表project

$ 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.jsrequire('project')

自动符号链接

手动创建符号链接的问题在于,每次您npm ci都会丢失符号链接。如果您使符号链接进程成为依赖项,中提琴,没有问题。

该模块是一个安装后脚本,它会在每次运行或运行时basetag创建一个符号链接(或 Windows 联结):$npm installnpm ci

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

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

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

如果您不喜欢使用$and would prefer#或其他东西(除了@,它是 npm 的特殊字符),您可以分叉它并进行更改。

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

于 2012-06-02T07:55:32.240 回答
5

恕我直言,实现这一点的最简单方法是在应用程序启动时node_modules/app(或任何你称之为的)创建一个指向../app. 然后你就可以打电话了require("app/my/module")。符号链接在所有主要平台上都可用。

但是,你仍然应该将你的东西拆分成更小的、可维护的模块,这些模块是通过 npm 安装的。您还可以通过 git-url 安装您的私有模块,因此没有理由拥有一个单一的应用程序目录。

于 2013-10-22T13:00:47.480 回答
5

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

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

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

// in app.js
express = require(process.env.root);
于 2015-05-21T01:23:50.313 回答
4

这是我超过6个月的实际方式。我在项目中使用一个名为 node_modules 的文件夹作为我的根文件夹,这样它总是会从我称之为绝对要求的任何地方查找该文件夹:

  • 节点模块
    • 我的项目
      • index.js 我可以 require("myProject/someFolder/hey.js") 而不是 require("./someFolder/hey.js")
      • someFolder 包含 hey.js

当您嵌套在文件夹中时,这更有用,如果以绝对方式设置,更改文件位置的工作要少得多。我在整个应用程序中只使用了 2 个相对要求。

于 2013-01-16T00:12:52.443 回答
4

刚刚看到这篇提到app-module-path 的文章。它允许您像这样配置基础:

require('app-module-path').addPath(baseDir);
于 2018-05-09T12:43:05.730 回答
4

我一直在寻找完全相同的简单性来要求任何级别的文件,我发现了module-alias

只需安装:

npm i --save module-alias

打开你的 package.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')
于 2019-11-04T15:52:52.983 回答
2

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

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

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

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

所以就是这样。

于 2015-09-22T21:25:41.907 回答
2

我喜欢做的是利用节点如何从 node_module 目录加载。

如果一个人试图加载模块“东西”,一个人会做类似的事情

require('thing');

然后 Node 会在 'node_module' 目录中寻找 'thing' 目录。

由于 node_module 通常位于项目的根目录,我们可以利用这种一致性。(如果 node_module 不在根目录下,那么您还有其他自我诱发的头痛需要处理。)

如果我们进入该目录然后退出它,我们可以获得到节点项目根目录的一致路径。

require('thing/../../');

然后,如果我们想访问 /happy 目录,我们会这样做。

require('thing/../../happy');

虽然它有点hacky,但是我觉得如果node_modules加载的功能发生变化,将会有更大的问题需要处理。这种行为应该保持一致。

为了清楚起见,我这样做,因为模块的名称无关紧要。

require('root/../../happy');

我最近将它用于angular2。我想从根目录加载服务。

import {MyService} from 'root/../../app/services/http/my.service';
于 2016-01-27T07:27:08.743 回答
2

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

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()
于 2017-05-02T20:31:56.883 回答
2

只想跟进Paolo Moretti和 Browserify的精彩回答。如果您正在使用转译器(例如,babel、typescript)并且您有单独的文件夹用于源代码和转译代码,例如and ,您可以使用解决方案的变体作为src/dist/

节点模块

具有以下目录结构:

app
  node_modules
    ... // normal npm dependencies for app
  src
    node_modules
      app
        ... // source code
  dist
    node_modules
      app
        ... // transpiled code

然后,您可以让 babel 等将src目录转换为dist目录。

符号链接

使用符号链接,我们可以摆脱某些级别的嵌套:

app
  node_modules
    ... // normal npm dependencies for app
  src
    node_modules
      app // symlinks to '..'
    ... // source code
  dist
    node_modules
      app // symlinks to '..'
    ... // transpiled code

babel 的警告 --copy-files--copy-files标志babel不能很好地处理符号链接。它可能会继续导航到..符号链接并反复查看无穷无尽的文件。一种解决方法是使用以下目录结构:

app
  node_modules
    app // symlink to '../src'
    ... // normal npm dependencies for app
  src
    ... // source code
  dist
    node_modules
      app // symlinks to '..'
    ... // transpiled code

这样,下面的代码src仍然会app解析为src,而 babel 将不再看到符号链接。

于 2017-06-22T20:28:38.923 回答
2

我多次遇到同样的问题。这可以通过使用basetagnpm 包来解决。它本身不必是必需的,只需在它在node_modules您的基本路径中创建一个符号链接时安装。

const localFile = require('$/local/file')
// instead of
const localFile = require('../../local/file')

使用$/...前缀将始终引用相对于您的应用程序根目录的文件。

来源:我如何创建basetag来解决这个问题

于 2020-04-24T09:48:21.650 回答
1

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

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

https://npmjs.org/package/rekuire

超级好用

于 2013-03-28T10:03:43.193 回答
1

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

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

然后这个对象将被传递给所有其他模块以供使用。

例如

var context = {}

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

这要求我们将每个模块编写为接收 opts 的函数,无论如何这对我们来说都是最佳实践。

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

然后你会参考上下文而不是要求东西。

var module1Ref = context.moduel1;

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

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 定义为函数——这将允许我们require根据环境使用不同的模块——但它超出了这个线程的范围。

于 2014-01-07T13:21:09.773 回答
1

我遇到了同样的问题,所以我写了一个名为include的包。

Include通过定位你的 package.json 文件来处理你的项目的根文件夹,然后将你给它的路径参数传递给本机 require() 而不会出现所有相对路径混乱。我想这不是作为 require() 的替代品,而是需要处理非打包/非第三方文件或库的工具。就像是

var async = require('async'),
    foo   = include('lib/path/to/foo')

我希望这会很有用。

于 2014-07-27T06:52:10.447 回答
1

如果您的应用程序的入口点 js 文件(即您实际运行“node”的那个)在您的项目根目录中,您可以使用rootpath npm 模块轻松完成此操作。只需通过安装它

npm install --save rootpath

...然后在入口点 js 文件的最顶部,添加:

require('rootpath')();

从那时起,所有 require 调用现在都与项目根目录相关 - 例如require('../../../config/debugging/log'); 变为require('config/debugging/log');(配置文件夹位于项目根目录中)。

于 2015-09-11T05:43:19.213 回答
1

简单来说,您可以将自己的文件夹称为模块:

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

这里的“App-module-path”是模块,它使您能够将其他目录添加到 Node.js 模块搜索路径而“全局”是,您附加到此对象的任何内容都将在您的应用程序中随处可用。

现在看看这个片段:

global.appBasePath = __dirname;

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

__dirname 是节点当前运行的目录。您可以在此处输入自己的路径来搜索模块的路径。

于 2016-09-29T14:53:46.323 回答
1

如果你使用 ES5 语法,你可以使用asapp。对于 ES6,您可以使用babel-plugin-module-resolver使用如下配置文件:

.babelrc

{
  "plugins": [
    ["module-resolver", {
      "root": ["./"],
      "alias": {
        "app": "./app",
        "config": "./app/config",
        "schema": "./app/db/schemas",
        "model": "./app/db/models",
        "controller": "./app/http/controllers",
        "middleware": "./app/http/middleware",
        "route": "./app/http/routes",
        "locale": "./app/locales",
        "log": "./app/logs",
        "library": "./app/utilities/libraries",
        "helper": "./app/utilities/helpers",
        "view": "./app/views"
      }
    }]
  ]
}
于 2018-10-20T19:46:11.300 回答
0

前段时间,我创建了用于加载相对于预定义路径的模块的模块。

https://github.com/raaymax/irequire

您可以使用它来代替 require。

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

也许它对某人有用..

于 2015-05-28T18:21:56.963 回答
0

虽然这些答案有效,但它们并没有解决 npm test 的问题

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

要设置一个全局 appRoot 变量,以避免 ../../../ 问题,并且在 npm start 和 npm test 中都可用,请参阅:

带有额外选项或参数的 Mocha 测试

请注意,这是新的官方 mocha 解决方案

于 2017-01-26T13:50:42.470 回答
0

尝试使用 asapp:

npm install --save asapp

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

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

controller('home')反而require('../../controllers/home)

于 2017-10-29T20:48:38.537 回答
-1

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

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

将 ../../ 更改为 ../

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

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

并在您的示例文件中

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

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

这真的只是个人喜好。

于 2012-06-02T06:55:40.783 回答
-2

这里已经有很多很好的答案了。这只是表明这是一个没有明确最佳解决方案的常见问题。最好的当然是 N​​ode.js 的原生支持。这是我目前使用的:

const r  = p => require (process.cwd() + p);
let see  = r ('/Subs/SubA/someFile.js' );
let see2 = r ('/Subs/SubB/someFile2.js');
...

我喜欢这个解决方案,因为 requires-section 变得更短,不需要多次输入“require”。绝对路径的主要好处是您可以将它们从一个文件复制到另一个文件,而无需像使用相对路径那样调整它们。因此,复制额外的单行箭头函数“r()”也不是太多额外的工作。并且不需要仅仅为了完成这个非常简单的任务而导入额外的 npm-dependencies。

于 2021-01-21T19:43:20.557 回答