如何加载节点模块,就像当前模块位于其他位置一样?

时间:2016-11-01 18:09:21

标签: javascript node.js module require

我在某个模块中运行了一些nodejs代码。从这个模块,我想加载一个位于文件系统中完全不同位置的模块 - 例如,给定路径"/another/dir"和模块名称"foo",我希望Node采取行动好像在/another/dir中运行的模块调用了require("foo"),而不是我自己的模块。

  My code is running here
/some/folder/node_modules/mine/my_module.js

  I have the path "/another/dir/", the string "foo",
    and want to load this module
/another/dir/node_modules/foo/index.js

换句话说,module documentation是指来自路径Y" 的模块的进程" require(X),我想指定自己的值Y

这可以实现吗?如果是这样,怎么样?如果没有,为什么不呢?

5 个答案:

答案 0 :(得分:7)

最简单的,只是将路径解析为绝对路径,对于大多数情况(即使不是所有情况),这将是推荐的方法。

var path = require('path');

var basedir = '/another/dir';
var dirname = 'foo';

var filepath = path.join(basedir, 'node_modules', filename);
var imports = require(filepath);

如果您确实需要以使其行为就好像它位于不同的目录中一样, 您可以将基目录推送到module.paths

module.paths.unshift('/another/dir/node_modules');

var imports = require('foo');

module.paths.shift();

module.paths也可以通过环境变量NODE_PATH在外部进行修改,这将是推荐最少的方法但是这确实在所有模块中全局应用它。

答案 1 :(得分:7)

带有npm链接的符号链接

为避免出现问题或修改源代码,我会使用npm link,例如:

首先:

cd /another/dir/node_modules/foo  # go into the package directory
npm link                          # creates global link

这将为foo模块创建一个全局链接,在Linux上您需要root权限才能执行此操作。

然后:

cd /some/folder/ # go into some other package directory.
npm link foo     # link-install the package

/some/folder/package.json应该包含foo作为dep,不是强制性的,如果没有它,您会收到extraneous npm ls的警告:

"dependencies": {
    [...]
    "foo": "*"
  }

没有符合本地NODE_PATH

的符号链接

你不喜欢符号链接吗?您仍然可以使用NODE_PATH但在本地而不是将全局变量设置为@rocketspacer建议,因为正如他所说的那样,不建议全局使用它。

注意:在任何情况下,我都会使用用户变量 系统范围的变量,一个同事可以在同一台机器上使用不同的用户名进行登录,但仍然可以获得修改后的NODE_PATH

但是要在Linux本地执行此操作只需一次调用,您只需调用:

NODE_PATH=$NODE_PATH:/another/dir/node_modules npm start

该调用只使用NODE_PATH

在Windows上进行同一次调用:

@ECHO OFF

SET BASE_NODE_PATH=%NODE_PATH%
SET NODE_PATH=%BASE_NODE_PATH%;C:\another\dir\node_modules\
node index.js
SET NODE_PATH=%BASE_NODE_PATH%

而...

您还可以使用本地代码:

"dependencies": {
  "foo": "file:/another/dir/node_modules/foo"
}

但需要npm install并且会复制当前包foo文件夹中node_modules的内容。

答案 2 :(得分:3)

实现起来非常简单,只需添加模块对象的绝对路径

即可

在当前脚本中module.paths.push('/another/dir/node_modules'); //this must be absolute, like /Users/John/another/dir/node_modules var foo = require('foo'); 添加此

module.paths

对于演示,在终端中打开节点,然后键入require,它将显示所有路径节点将搜索for,您只需添加路径

答案 3 :(得分:2)

"要求(X)来自路径Y"

的模块

表示从位于路径Y的文件中调用require(X)。因此,您实际上无法更改Y.

<小时/> 虽然上述解决方案有效(修改module.paths并要求绝对路径),但您必须将这些片段添加到项目中需要外部模块的每个文件中。

更多的是,官方不支持修改 module.paths 。因此,不保证在节点的未来更新中工作

<小时/>

介绍NODE_PATH

NODE_PATH 是一个环境变量,设置为以冒号分隔的绝对路径列表。

在这些绝对路径中,当所有其他方法都失败时,Node.js将搜索与require语句匹配的模块(已将 node_modules 索引到文件系统根和仍然没有找到匹配)

它是官方支持的,虽然不推荐,因为它违反惯例(您的同事可能不知道 NODE_PATH 用法,因为在您的项目中没有描述性的方式告诉您)

注意:

  • 在Windows上, NODE_PATH 由分号分隔,而不是 冒号。
  • Node不会在这些路径中查找node_modules 它的默认行为,因此您的路径应该正好在您的位置 包含所需的模块。例如:&#34; / another / dir / node_modules&#34;

<小时/> 有关详细信息,请参阅NodeJs官方文件:
https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
对于那些不知道环境变量是什么以及如何设置它们的人,我有一个Windows屏幕截图,可以帮助你开始

enter image description here

答案 4 :(得分:1)

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

为此我们需要:全局和app-module-path模块

这里&#34; App-module-path&#34;是模块,它使您能够将其他目录添加到Node.js模块搜索路径和&#34; global&#34;是的,您附加到此对象的任何内容都将在您的应用中随处可用。

现在看看这个片段:

global.appBasePath = __dirname;

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

__ dirname是节点的当前运行目录。您可以在此处提供自己的路径来搜索模块的路径。