我需要一个通过npm安装的模块.我想访问从属于该模块的.js文件(因此我可以在其中继承一个Constructor方法).我不能(好吧,不想)修改模块的代码,所以没有地方提取它的__dirname.
我知道以下问题,但它是关于获取一个代码控制的模块的路径(因此,__ dirname是解决方案): 在Node.js中,我如何告诉`this`模块的路径?
~~~
更好的方法是获取模块的加载模块信息
Lin*_*iel 115
如果我正确理解您的问题,您应该使用require.resolve():
使用内部的require()机制来查找模块的位置,而不是加载模块,只需返回已解析的文件名.
例: var pathToModule = require.resolve('module');
Jas*_*son 35
require.resolve()是正确的答案,但前提是你使用正确的参数.最佳答案适用于许多节点模块,但不适用于所有节点模块.
require.resolve("moduleName")没有提供安装模块的目录.它为您提供package.json中'main'属性中定义的文件的位置.那可能是moduleName/index.js,也可能是moduleName/lib/moduleName.js.在后一种情况下,main将返回错误的目录:node_modules/moduleName/lib
找到moduleName/README.md的正确方法是调用:
let readmePath = require.resolve("moduleName/README.md");
Run Code Online (Sandbox Code Playgroud)
如果您只是想要模块的目录(也许您要进行大量package.json调用),那么package.json必须始终位于项目的根目录中:
let packagePath = path.dirname(require.resolve("moduleName/package.json"));
Run Code Online (Sandbox Code Playgroud)
Jason 的答案是最好的答案,直到 Node.js ESM 和该exports领域出现。
既然 Node 支持带有一个exports字段的包,默认情况下该字段将阻止类似文件package.json被解析,除非包作者明确决定公开它们,Jason 的答案中的技巧对于没有显式公开的包将失败package.json。
有一个名为的包resolve-package-path可以解决这个问题。
使用方法如下:
const resolvePkg = require('resolve-package-path')
console.log(resolvePkg('@some/package'))
Run Code Online (Sandbox Code Playgroud)
这会输出类似的东西
/path/to/@some/package/package.json
Run Code Online (Sandbox Code Playgroud)
无论包的exports字段包含什么。
这是一个以与平台无关的方式返回模块目录的解决方案。这不使用任何第 3 方库,并成功找到"type": "module"通过 .. 安装的 ESM 模块和模块npm link。
注意:如果特定模块是到另一个位置的符号链接(例如
npm link),您将需要使用fs.realpath来获取目标目录的位置:Run Code Online (Sandbox Code Playgroud)const moduleDir = getModuleDir('some-npm-module'); const theRealPath = fs.realpathSync(moduleDir);
import fs from 'fs';
import path from 'path';
import { createRequire } from 'module';
/**
* Get's the file path to a module folder.
* @param {string} moduleEntry
* @param {string} fromFile
*/
const getModuleDir = (moduleEntry) => {
const packageName = moduleEntry.includes('/')
? moduleEntry.startsWith('@')
? moduleEntry.split('/').slice(0, 2).join('/')
: moduleEntry.split('/')[0]
: moduleEntry;
const require = createRequire(import.meta.url);
const lookupPaths = require.resolve.paths(moduleEntry).map((p) => path.join(p, packageName));
return lookupPaths.find((p) => fs.existsSync(p));
};
Run Code Online (Sandbox Code Playgroud)
const fs = require('fs');
const path = require('path');
const { createRequire } = require('module');
/**
* Get's the file path to a module's folder.
* @param {string} moduleEntry
* @param {string} fromFile
*/
const getModuleDir = (moduleEntry, relativeToFile = __filename) => {
const packageName = moduleEntry.includes('/')
? moduleEntry.startsWith('@')
? moduleEntry.split('/').slice(0, 2).join('/')
: moduleEntry.split('/')[0]
: moduleEntry;
const require = createRequire(relativeToFile);
const lookupPaths = require.resolve.paths(moduleEntry).map((p) => path.join(p, packageName));
return lookupPaths.find((p) => fs.existsSync(p));
};
Run Code Online (Sandbox Code Playgroud)