Javascript 如果当前模块位于其他位置,如何加载节点模块?
我在某个模块中运行了一些nodejs代码。从这个模块中,我想加载一个位于文件系统中完全不同位置的模块——例如,给定路径Javascript 如果当前模块位于其他位置,如何加载节点模块?,javascript,node.js,module,require,Javascript,Node.js,Module,Require,我在某个模块中运行了一些nodejs代码。从这个模块中,我想加载一个位于文件系统中完全不同位置的模块——例如,给定路径“/other/dir”和模块名“foo”,我希望节点的行为就像在/other/dir中运行的模块调用了require(“foo”),而不是我自己的模块 My code is running here /some/folder/node_modules/mine/my_module.js I have the path "/another/dir/", the stri
“/other/dir”
和模块名“foo”
,我希望节点的行为就像在/other/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
换句话说,指的是流程“从路径Y处的模块请求(X)”,我想为Y
指定我自己的值
这能做到吗?如果是,怎么做?如果没有,为什么不呢?最简单的方法就是将路径解析为绝对路径,这将是大多数(如果不是所有)情况下的推荐方法
var path = require('path');
var basedir = '/another/dir';
var filename = 'foo'; // renamed from dirname
var filepath = path.join(basedir, 'node_modules', filename);
var imports = require(filepath);
如果您确实需要使require像在不同的目录中一样工作,
您可以将基本目录推送到module.path
module.paths.unshift('/another/dir/node_modules');
var imports = require('foo');
module.paths.shift();
module.路径
也可以通过环境变量NODE\u PATH
进行外部修改,虽然这是最不推荐的方法,但它可以在所有模块中全局应用。很容易实现,只需将绝对路径添加到模块对象中即可
在当前脚本/some/folder/node\u modules/mine/my\u module.js
中添加以下内容
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
,您只需将路径添加到路径Y处的模块中的require(X)
意味着从位于路径Y的文件中调用require(X)。因此实际上无法更改Y。尽管上述解决方案可行(修改module.path&需要绝对路径),但您必须将这些代码段添加到项目中需要外部模块的每个文件中 此外,官方不支持修改模块路径。因此,它不能保证在以后的节点更新中工作
引入节点路径 节点路径是一个环境变量,设置为以冒号分隔的绝对路径列表 在这些绝对路径中,Node.js将在所有其他操作都失败时搜索与require语句匹配的模块(已将Node_模块索引到文件系统根目录,但仍然找不到匹配项) 它是官方支持的,但不建议使用,因为它违反了惯例(您的同事可能不知道节点路径的用法,因为在您的项目中没有描述性的方法来说明这一点) 注:
- 在Windows上,节点路径由分号分隔,而不是 科隆李>
- Node不会在这些路径中查找Node_模块,如 它的默认行为,因此您的路径应该正好位于 包含所需的模块。例如:“/other/dir/node_modules”
详细信息见NodeJs官方文件:
对于那些不知道环境变量是什么以及如何设置它们的人,我有一个windows屏幕截图,可以让你们开始 带有npm链接的符号链接 为了避免问题或修改源代码,我将使用您的示例: 第一:
cd /another/dir/node_modules/foo # go into the package directory
npm link # creates global link
这将为foo
模块创建一个全局链接,在Linux上,您需要root权限才能执行此操作
然后:
/some/folder/package.json
应包含foo
作为一个dep,这不是强制性的,如果没有它,您将得到一个与npm ls
无关的警告:
"dependencies": {
[...]
"foo": "*"
}
没有带有本地节点路径的符号链接
你不喜欢符号链接?您仍然可以使用NODE\u PATH
,但可以按照@rocketspacer的建议在本地设置一个全局变量,因为正如他正确指出的那样,不建议全局使用它
注意:在任何情况下,我都会使用用户变量而不是系统范围内的变量,同事可以使用不同的用户名在同一台机器上登录,并且仍然可以获得修改后的节点路径
但要在Linux上本地执行一次调用,您只需调用:
NODE_PATH=$NODE_PATH:/another/dir/node_modules npm start
它将仅使用该节点路径
进行该调用
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%
而且。。。
您也可以使用本地dep,如:
"dependencies": {
"foo": "file:/another/dir/node_modules/foo"
}
但是需要安装npm
,它会将foo
的内容复制到当前包node\u modules
文件夹中。简单地说,你可以将自己的文件夹称为module:
为此,我们需要:全局和应用程序模块路径模块
这里的“App module path”是模块,它允许您向Node.js模块搜索路径添加其他目录,“global”是指,您附加到此对象的任何内容都将在应用程序中的任何位置可用
现在看一下这个片段:
global.appBasePath = __dirname;
require('app-module-path').addPath(appBasePath);
__dirname是节点的当前运行目录。您可以在此处提供自己的路径来搜索模块的路径。如果我弄错了,请更正我。您想从/some/folder/
包中的包/other/dir/
加载已安装的模块,但如果/some/folder
中未安装模块的某些依赖项,则该foo
模块将正常工作?人们还建议将node\u modules
path添加到modules.path
中,但如果两个包都安装了一些相同的依赖项,这不是问题吗?模块不是全局的,它的作用域是调用它的特定文件,tested logging module.path访问多个文件,必须在每个文件中添加这个小片段,才能让这个hack-to-work是的,这是一个hack-tho,因为您正在尝试访问允许的目录之外的内容,在模块的末尾清除路径。paths
数组不起作用,您必须使用unshift
。一个约束条件是我需要这一切发生
global.appBasePath = __dirname;
require('app-module-path').addPath(appBasePath);