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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10111163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:31:09  来源:igfitidea点击:

In node.JS how can I get the path of a module I have loaded via require that is *not* mine (i.e. in some node_module)

node.js

提问by Zhami

I require a module that was installed via npm. I want to access a .js file subordinate to that module (so I can subclass a Constructor method in it). I can't (well, don't want to) modify the module's code, so don't have a place to extract its __dirname.

我需要一个通过 npm 安装的模块。我想访问从属于该模块的 .js 文件(因此我可以在其中继承 Constructor 方法)。我不能(好吧,不想)修改模块的代码,所以没有地方提取它的 __dirname。

I am aware of the following question, but it is about getting the path of a module that one has code control over (hence, __dirname is the solution): In Node.js how can I tell the path of `this` module?

我知道以下问题,但它是关于获取一个可以控制代码的模块的路径(因此,__dirname 是解决方案): 在 Node.js 中,我如何知道“this”模块的路径?

~~~

~~~

Even better would be to get the module's loaded module info

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

回答by Linus Gustav Larsson Thiel

If I correctly understand your question, you should use require.resolve():

如果我正确理解你的问题,你应该使用require.resolve()

Use the internal require() machinery to look up the location of a module, but rather than loading the module, just return the resolved filename.

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

Example: var pathToModule = require.resolve('module');

例子: var pathToModule = require.resolve('module');

回答by Jason

require.resolve()is a partial answer. The accepted answer may work for many node modules, but won't work for all of them.

require.resolve()是部分答案。接受的答案可能适用于许多节点模块,但不适用于所有节点模块。

require.resolve("moduleName")doesn't give you the directory where the module is installed; it gives you the location of the file defined in the mainattribute in the module's package.json.

require.resolve("moduleName")没有给你安装模块的目录;它为您提供了main在模块的package.json.

That might be moduleName/index.jsor it could be moduleName/lib/moduleName.js. In the latter case, path.dirname(require.resolve("moduleName"))will return a directory you may not want or expect: node_modules/moduleName/lib

那可能是moduleName/index.js,也可能是moduleName/lib/moduleName.js。在后一种情况下,path.dirname(require.resolve("moduleName"))将返回一个您可能不想要或不期望的目录:node_modules/moduleName/lib

The correct way to get the complete path to a specific module is by resolving the filename:

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

let readmePath = require.resolve("moduleName/README.md");

If you just want the directory for the module (maybe you're going to make a lot of path.join()calls), then resolve the package.json— which must always be in the root of the project — and pass to path.dirname():

如果您只想要模块的目录(也许您要进行大量path.join()调用),则解析package.json- 必须始终位于项目的根目录中 - 并传递给path.dirname()

let packagePath = path.dirname(require.resolve("moduleName/package.json"));

回答by Alexee

FYI, require.resolvereturns the module identifier according to CommonJS. In node.js this is the filename. In webpackthis is a number.

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

In webpacksituation, here is my solution to find out the module path:

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

Then from __webpack_modules__[pathToModule]I got information like this:

然后从__webpack_modules__[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?");

    /***/
})

Turned out I required old scripts from previous dll build file(for faster build speed), so that my updated module file didn't work as I expected. Finally I rebuilt my dll file and solved my problem.

结果我需要以前的 dll 构建文件中的旧脚本(为了更快的构建速度),所以我更新的模块文件没有按我预期的那样工作。最后我重建了我的 dll 文件并解决了我的问题。

Ref: Using require.resolveto get resolved file path (node)

参考:使用require.resolve得到解决文件路径(节点)

回答by Anatoliy

I hope I correctly understand your needs: to get entry point file of some module. Let's say you want to get entry point of jugglingdbmodule:

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

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

As you can see this is not "official" way to get this kind of information about module, so behavior of this function may change from version to version. I've found it in node source: https://github.com/joyent/node/blob/master/lib/module.js#L280

正如您所看到的,这不是获取此类模块信息的“官方”方式,因此此功能的行为可能会因版本而异。我在节点源中找到了它:https: //github.com/joyent/node/blob/master/lib/module.js#L280

回答by loretoparisi

According to @anatoliy solution, On MacOS X I have found the lookup paths doing

根据@anatoliy 解决方案,在 MacOS XI 上找到了查找路径

require('module')._resolveLookupPaths('myModule')

so I get the resolved lookup paths

所以我得到了解决的查找路径

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

whereas the

require('module')._resolveFilename('myModule')

will not resolve the module I was looking for anyways, in fact the crazy thing is that the _loadwill not resolve the module:

无论如何都不会解析我正在寻找的模块,实际上疯狂的是_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)

while the requirewill:

require遗嘱:

> require('myModule')

but I don't have this module in

但我没有这个模块

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/

so where is this module???

那么这个模块在哪里???

First I had to do a $ sudo /usr/libexec/locate.updatedbThen after some coffee I did locate myModuleor better locate myModule/someFile.js

首先我必须做一个$ sudo /usr/libexec/locate.updatedb然后在喝了一些咖啡之后我做了locate myModule或者更好locate myModule/someFile.js

et voilà, it comes out that it was in a parent folder of my project i.e. outside my project root folder:

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

$pwd
/Users/admin/Projects/Node/myProject
$ ls ../../node_modules/myModule/

so you cannot avoid to rm -rf ../../node_modules/myModule/and a fresh npm install.

所以你不能避免rm -rf ../../node_modules/myModule/和一个新鲜的npm install

I can argue that no one instructed npmto scan my computer in search for modules elsewhere than my project root folder where it was supposed to run or in the default modules search path.

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

回答by IvanM

This is maybe what you're looking for, check:

这可能是您正在寻找的内容,请检查:

require.main.filename

要求.main.filename