在node.JS中,如何获取通过require加载的模块的路径,该模块不是我的(即,在某个node_模块中)

在node.JS中,如何获取通过require加载的模块的路径,该模块不是我的(即,在某个node_模块中),node.js,Node.js,我需要一个通过npm安装的模块。我想访问从属于该模块的.js文件(因此我可以在其中对构造函数方法进行子类化)。我不能(好吧,我不想)修改模块的代码,所以没有地方提取它的_dirname 我知道下面的问题,但它是关于获取一个模块的路径,该模块由代码控制(因此,_dirname是解决方案): ~~~ 更好的方法是获取模块加载的模块信息我希望我正确理解您的需求:获取某个模块的入口点文件。假设您想要获得jugglingdb模块的入口点: node > require('module')._res

我需要一个通过npm安装的模块。我想访问从属于该模块的.js文件(因此我可以在其中对构造函数方法进行子类化)。我不能(好吧,我不想)修改模块的代码,所以没有地方提取它的_dirname

我知道下面的问题,但它是关于获取一个模块的路径,该模块由代码控制(因此,_dirname是解决方案):

~~~


更好的方法是获取模块加载的模块信息

我希望我正确理解您的需求:获取某个模块的入口点文件。假设您想要获得
jugglingdb
模块的入口点:

node
> require('module')._resolveFilename('jugglingdb')
'/usr/local/lib/node_modules/jugglingdb/index.js'

正如您所看到的,这不是获取有关模块的此类信息的“官方”方式,所以此函数的行为可能会随着版本的不同而变化。我在node source中找到了它:

如果我正确理解了您的问题,您应该使用:

使用内部require()机制查找模块的位置,但只返回解析的文件名,而不是加载模块


示例:
var-pathToModule=require.resolve('module')

根据@anatoliy solution,在MacOS X上,我发现查找路径正在运行

require('module')._resolveLookupPaths('myModule')
所以我得到了解析的查找路径

[ 'myModule',
  [ '/Users/admin/.node_modules',
    '/Users/admin/.node_libraries',
    '/usr/local/lib/node' ] ]
鉴于

require('module')._resolveFilename('myModule')
无论如何都无法解析我正在寻找的模块,事实上疯狂的是,
\u load
无法解析模块:

> require('module')._load('myModule')
Error: Cannot find module 'myModule'
    at Function.Module._resolveFilename (module.js:440:15)
    at Function.Module._load (module.js:388:25)
    at repl:1:19
    at sigintHandlersWrap (vm.js:32:31)
    at sigintHandlersWrap (vm.js:96:12)
    at ContextifyScript.Script.runInContext (vm.js:31:12)
    at REPLServer.defaultEval (repl.js:308:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:489:10)
但是我没有这个模块

myProject/node_modules/
myProject/node_modules/@scope/
/usr/local/lib/node_modules/
/usr/local/lib/node_modules/@scope
/usr/local/lib/node_modules/npm/node_modules/
/usr/local/lib/node_modules/npm/node_modules/@scope
$HOME/.npm/
$HOME/.npm/@scope/
那么这个模块在哪里

首先我必须做一个
$sudo/usr/libexec/locate.updatedb
喝了一杯咖啡后,我找到了myModule,或者更好地找到了myModule/someFile.js

等等,原来它在我的项目的父文件夹中,即在我的项目根文件夹之外:

$pwd
/Users/admin/Projects/Node/myProject
$ ls ../../node_modules/myModule/
因此,您无法避免使用
rm-rf.././node\u modules/myModule/
和新的
npm安装

我可以争辩说,没有人指示npm扫描我的计算机,在它应该运行的项目根文件夹或默认模块搜索路径以外的其他地方搜索模块。

是部分答案。公认的答案可能适用于许多节点模块,但不适用于所有节点模块

require.resolve(“moduleName”)
不提供安装模块的目录;它提供模块的
package.json
main
属性中定义的文件的位置

这可能是
moduleName/index.js
,也可能是
moduleName/lib/moduleName.js
。在后一种情况下,
path.dirname(require.resolve(“moduleName”)
将返回您可能不想要或不期望的目录:
node\u modules/moduleName/lib

获取特定模块的完整路径的正确方法是解析文件名:

let readmePath = require.resolve("moduleName/README.md");
如果您只需要模块的目录(可能需要进行大量的
path.join()
调用),则解析
package.json
——它必须始终位于项目的根目录中——并传递到
path.dirname()


这可能就是你要找的,检查:

require.main.filename


仅供参考,
require.resolve
根据CommonJS返回模块标识符。在node.js中,这是文件名。在网页中这是一个数字

webpack情况下,以下是我查找模块路径的解决方案:

const pathToModule = require.resolve('module/to/require');
console.log('pathToModule is', pathToModule); // a number, eg. 8
console.log('__webpack_modules__[pathToModule] is', __webpack_modules__[pathToModule]);
然后从
\uuuuu网页\uuuuu模块[pathToModule]
我得到了如下信息:

(function(module, exports, __webpack_require__) {

    eval("module.exports = (__webpack_require__(6))(85);\n\n//////////////////\n// 
    WEBPACK FOOTER\n// delegated ./node_modules/echarts/lib/echarts.js from dll-reference vendor_da75d351571a5de37e2e\n// module id = 8\n// module chunks = 0\n\n//# sourceURL=webpack:///delegated_./node_modules/echarts/lib/echarts.js_from_dll-reference_vendor_da75d351571a5de37e2e?");

    /***/
})
事实证明,我需要以前的dll构建文件中的旧脚本(为了更快的构建速度),所以我更新的模块文件不能像我预期的那样工作。最后我重建了我的dll文件并解决了我的问题


参考:

Jason的答案是最好的答案,直到Node.js ESM和
exports
字段出现

现在该节点支持带有
导出
字段的包,默认情况下,该字段将阻止像
package.json
这样的文件被解析,除非包作者明确决定公开它们,否则Jason回答中的技巧对于没有明确公开
package.json
的包将失败

有一个名为的包可以实现这个目的

以下是如何使用它:

const resolvePkg=require('resolve-package-path'))
log(resolvePkg(“@some/package”))
这将输出类似于

/path/to/@some/package/package.json

无论包的
导出
字段包含什么内容。

您可以在哪里加载模块而不会出现require('modulename')错误?您能更好地解释一下吗?一些代码?这个答案并不适用于所有节点模块。通过检测
package.json
文件,查看我的答案。非常聪明的答案。你不应该使用
path.join('moduleName','package.json')
来兼容Windows吗?@JoãoPimentelFerreira
require.resolve
是平台无关的,就像
require
一样,所以不需要使用
path.join
别忘了添加
const path=require('path')path.dirname
之前使用code>。我希望这个答案是完全正确的!我可以成功地解析类似于
require.resolve('@scope/module')
的内容,这给了我类似于
/path/to/@scope/module/dist/index.js
的内容,但是如果我尝试运行
require.resolve('@scope/module/package.json')
它会抛出一个
module\u NOT\u FOUND
错误。我在节点14.4.0中,我试图解析的模块在其package.json中有
“type”:“module”
,带有一个
exports
字段,该字段不包括
package.json
。不确定这是否与此有关…我发现了问题:当模块具有
类型:module
时,显然
包.json
必须在
导出中显式公开
(function(module, exports, __webpack_require__) {

    eval("module.exports = (__webpack_require__(6))(85);\n\n//////////////////\n// 
    WEBPACK FOOTER\n// delegated ./node_modules/echarts/lib/echarts.js from dll-reference vendor_da75d351571a5de37e2e\n// module id = 8\n// module chunks = 0\n\n//# sourceURL=webpack:///delegated_./node_modules/echarts/lib/echarts.js_from_dll-reference_vendor_da75d351571a5de37e2e?");

    /***/
})
/path/to/@some/package/package.json