如何使node.js要求绝对?(而不是相对)

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

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

216180 次浏览

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

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

/../变成了../

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

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

在你的例子文件中

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

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

这只是个人喜好。

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

examples目录是否可以包含一个带有指向项目根project -> ../../的符号链接的node_modules,从而允许示例使用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.js的内容是require('project')

自动化的符号链接

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

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

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

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

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

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

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

大局

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

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

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

一般情况

当然,当前目录中的node_modules,然后是父节点,然后是祖父节点,曾祖父节点等等。所以已安装的软件包已经这样工作了。通常你可以从你项目中的任何地方require("express"),它工作得很好。

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

其他解决方法

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

你可以将$NODE_PATH设置为你的项目根。当你require(). conf文件时,该目录将被搜索。

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

/下载/ app.js例子(和许多其他类似的)

var express = require('./express')

/下载/ express.js例子

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

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

恕我直言,最简单的方法是将自己的函数定义为GLOBAL对象的一部分。 在项目的根目录中创建projRequire.js,内容如下
var projectDir = __dirname;


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

在你的主文件requireing任何特定于项目的模块之前:

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

之后,以下工作对我来说:

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


// index.js at projectDir/lib/lol/index.js
console.log('Ok');
人力资源/ > < p > < @Totty,我想出了另一个解决方案,可以解决你在评论中描述的情况。Description将是tl;dr,所以我最好显示一张带有测试项目的结构的图片

这是我六个多月来的实际做法。我在项目中使用一个名为node_modules的文件夹作为我的根文件夹,这样它将始终从我调用绝对require的任何地方查找该文件夹:

    <李> node_modules
      <李>。
      • index.js我可以require("myProject/someFolder/hey.js")而不是require("./someFolder/hey.js")
      • 包含hey.js的someFolder
      • 李< / ul > < / > 李< / ul > < / >

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

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

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

https://npmjs.org/package/rekuire

它非常容易使用

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

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

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

在我看来,实现这一点最简单的方法是在应用程序启动时创建一个指向../app的符号链接。然后你可以调用require("app/my/module")。符号链接在所有主要平台上都可用。

然而,你仍然应该把你的东西分成更小的、可维护的模块,这些模块通过npm安装。你也可以通过git-url安装你的私有模块,所以没有理由有一个单一的应用程序目录。

假设你的项目根目录是当前的工作目录,这应该是有效的:

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


// require file relative to current working directory
config = require( path.resolve('.','config.js') );

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

以其他已知项目(如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. module1;

如果您愿意,可以轻松地编写一个循环来执行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定义为函数——这将允许我们根据环境require不同的模块——但这超出了这个线程的作用域。

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

我遇到了同样的架构问题:想要给我的应用程序更多的组织和内部名称空间,但没有:

  • 将应用程序模块与外部依赖项混合,或者为特定于应用程序的代码使用私有NPM回购
  • 使用相对要求,使得重构和理解更加困难
  • 使用符号链接或更改节点路径,这可能会模糊源代码位置,并且不能很好地进行源代码控制

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

  • npm-shrinkwrap.json
  • package.json
  • <李> node_modules
    • ...
    • 李< / ul > < / > <李> src
      • app.js
      • app.config.js
      • app.models.bar.js
      • app.models.foo.js
      • app.web.js
      • app.web.routes.js
      • ...
      • 李< / ul > < / >

      然后在代码中:

      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');
      

      通过这种方式,所有应用程序代码都按层次结构组织成模块,相对于应用程序根,所有其他代码都可以使用。

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

看看node-rfr

其实很简单:

var rfr = require('rfr');
var myModule = rfr('projectSubDir/myModule');

我喜欢为共享代码创建一个新的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会找到它!

< a href = " http://blairanderson。> node_modules如何工作 . co/browserify-handbook/# How -node_modules-works

节点有一个聪明的算法来解析模块,在竞争对手中是唯一的 平台。< / p >

如果你从/beep/boop/bar.jsrequire('./foo.js'), node将在/beep/boop/foo.js中查找./foo.js。以./../开头的路径始终是调用require()的文件的本地路径。

然而,如果你需要一个非相对名称,例如require('xyz')来自/beep/boop/foo.js, node会按顺序搜索这些路径,在第一个匹配处停止,如果没有找到则抛出错误:

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

对于每个存在的xyz目录,node将首先查找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') . < / p >

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

/beep/node_modules/xyz/index.js

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

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

不是应用程序中的所有东西都属于公共npm 设置一个私有NPM或git回购的开销仍然是 在很多情况下是相当大的。这里有一些方法来避免 ../../../../../../../相对路径问题

node_modules

人们有时反对将特定于应用程序的模块放入 Node_modules,因为如何检查内部并不明显

答案很简单!如果你有一个.gitignore文件 忽略了node_modules: < / p >
node_modules
你可以用!为每个内部异常添加一个异常 应用程序模块:< / p >
node_modules/*
!node_modules/foo
!node_modules/bar
请注意你不能unignore子目录,如果父目录是 已经忽略了。因此,你必须忽略node_modules,而不是忽略它 ,忽略每个目录内部 node_modules node_modules/*技巧,然后你可以添加你的异常 现在在你的应用程序中的任何地方你都可以require('foo')require('bar')而没有一个非常大和脆弱的相对 路径。< / p >

如果你有很多模块,并且想让它们更独立 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
如果你的应用程序在包中配置了转换。json,你会 需要创建一个单独的包。Json中有自己的转换字段 你的node_modules/foonode_modules/app/foo组件目录 因为转换不能跨模块边界应用。这将 使您的模块对您的配置更改更加健壮 应用程序,将更容易独立地重用包

符号链接

如果你正在开发一个可以使用的应用程序,这是另一个方便的技巧 使符号链接和不需要支持窗口是符号链接lib/app/文件夹到node_modules。从项目根,做:

ln -s ../lib node_modules/app

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

自定义路径

你可能会在一些地方看到使用$NODE_PATH 环境变量或opts.paths为节点和添加目录

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

这是因为您的应用程序与运行时耦合更紧密 环境配置,所以有更多的活动部件和您的

.应用程序只有在您的环境正确设置时才能工作

节点和browserify都支持但不鼓励使用 $NODE_PATH . < / p >

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

包括通过定位你的包来处理计算你的项目的根文件夹。Json文件,然后传递路径参数,你给它的本地require()没有所有的相对路径混乱。我认为这不是require()的替代品,而是需要处理非打包/非第三方文件或库的工具。类似的

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

我希望这对你有用。

还有:

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

它需要的文件,就像它被要求从主js文件,所以它工作得很好,只要你的主js文件是在你的项目的根…这一点我很感激。

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

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

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

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

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

https://github.com/raaymax/irequire

你可以用它来代替require。

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

也许它会对某人有用。

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

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

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

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

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

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

如果你的应用程序的入口点js文件(即你实际运行“node”的文件)是在你的项目根目录下,你可以很容易地用Rootpath NPM模块。只需通过

npm install --save rootpath

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

require('rootpath')();

从那时起,所有的require调用现在都相对于项目根目录了——例如require('../../../config/debugging/log');变成了require('config/debugging/log');(其中配置文件夹在项目根目录中)。

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

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

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

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

就是这样。

我喜欢做的是利用node从node_module目录加载的方式。

如果有人试图加载“thing”模块,他会做如下的事情

require('thing');

Node将在'node_module'目录中查找'thing'目录。

由于node_module通常位于项目的根,所以我们可以利用这种一致性。(如果node_module不在根节点上,那么您就会遇到其他令人头痛的问题。)

如果我们进入目录,然后从目录中返回,我们可以获得到节点项目根的一致路径。

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

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

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

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

为了使事情更清楚,我这样做,因为模块的名称并不重要。

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

我最近在angular2中使用了它。我想从根目录加载服务。

import {MyService} from 'root/../../app/services/http/my.service';

你可以使用我创建的模块Undot。它没有什么高级的,只是一个助手,让你可以避免那些点地狱与简单。

例子:

var undot = require('undot');
var User = undot('models/user');
var config = undot('config');
var test = undot('test/api/user/auth');

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

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

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

现在看一下这个片段:

global.appBasePath = __dirname;


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

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

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

从版本2.0.0你可以从本地文件安装一个包,这意味着你可以在根目录下创建一个文件夹,里面有你想要的所有包,

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

所以在包装上。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

而这些答案工作他们没有用NPM测试解决问题

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

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

摩卡测试有额外的选项或参数

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

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

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()

只是想从保罗·莫雷蒂和Browserify跟进伟大的回答。如果你正在使用编译器(例如babel, typescript),并且你有单独的文件夹存放源代码和编译过的代码,如src/dist/,你可以使用解决方案的变体

node_modules

目录结构如下:

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标志不能很好地处理符号链接。它可能会一直导航到..符号链接,并隐式地看到无穷无尽的文件。一种变通方法是使用以下目录结构:

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将不再看到符号链接。

尝试使用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)

另一个答案是:

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

  • < >强node_modules
    • lodash
    • 李< / ul > < / >
    • <强> src
      • <强>子目录
        • foo.js
        • bar.js
        • 李< / ul > < / >
        • main.js
        • 李< / ul > < / >
        • < p > 测试

          • . js
          • 李< / ul > < / >

          然后在. 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-plugin-module-resolver来配置两个根文件夹:

          {
          "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"
          

刚刚发现这篇文章提到了app-module-path。它允许你这样配置一个基础:

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

如果你使用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"
}
}]
]
}

如果你使用而不是npm,你可以使用工作区

假设我有一个文件夹services,我希望更容易地要求:

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

要创建Yarn工作空间,在services folder中创建一个package.json文件:

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

在你的主包里。json添加:

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

从项目的根目录运行yarn install

然后,在代码的任何地方,你可以这样做:

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

而不是像这样:

const { myFunc } = require('../../../../../../services/foo')

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

安装:

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')

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

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

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

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

这里已经有很多好答案了。这只是说明这是一个普遍的问题,没有明确的最佳解决方案。当然最好是在Node.js中提供本地支持。以下是我目前使用的:

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

我喜欢这个解决方案,因为require部分变得更短,不需要键入'require'很多次。绝对路径的主要好处是,您可以将它们从一个文件复制到另一个文件,而不必像使用相对路径那样对它们进行调整。因此,复制额外的一行箭头函数'r()'也不会有太多额外的工作。为了完成这个非常简单的任务,不需要导入额外的npm依赖项。

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

的文件夹结构为例

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_的文件夹,其中包含一个package.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中,在应用程序的package.jsondependencies下创建一个条目

"db": "file:db/_module_"

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

const db = require('db');

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

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

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

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

全球。Dir = process.cwd();

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

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

const myFn = require(全局的。'/js/myDir/myFn');