Node.js:获取已安装的npm包的(绝对)根路径 [英] Node.js: Get (absolute) root path of installed npm package
问题描述
我正在寻找一种通用方法来获取Node.js中已安装的npm包的(绝对)根路径。
I'm looking for an universal way to get the (absolute) root path of an installed npm package in Node.js.
我知道 require.resolve
,但这会给出我是入口点(主模块的路径)而不是包的根路径。
I know about require.resolve
, but that will give me the entry point (path to the main module) rather than the root path of the package.
取 bootstrap-sass
作为一个例子。假设它在本地安装在项目文件夹 C:\ dev \ my-project
中。然后我要找的是 C:\ dev \ my-project \ node_modules \ bootstrap-sass
。 require.resolve('bootstrap-sass')
将返回 C:\dev \ my-project \ node_modules \ bootstrap-sass \\ \\ assets\javascripts\bootstrap.js
。
Take bootstrap-sass
as an example. Say it's installed locally in a project folder C:\dev\my-project
. Then what I'm looking for is C:\dev\my-project\node_modules\bootstrap-sass
. require.resolve('bootstrap-sass')
will return C:\dev\my-project\node_modules\bootstrap-sass\assets\javascripts\bootstrap.js
.
我可以想到几种方法如何获取包的根路径:
I can think of several methods how to get the package's root path:
var packageRoot = path.resolve('node_modules/bootstrap-sass');
console.log(packageRoot);
这对于本地安装在 node_modules $ c $中的软件包可以正常工作c>文件夹。但是,如果我在子文件夹中,我需要解析
../ node_modules / bootstrap-sass
,并且使用更多嵌套文件夹会更复杂。此外,这对全局安装的模块不起作用。
This will work fine for packages installed locally in node_modules
folder. However, if I'm in a subfolder, I need to resolve ../node_modules/bootstrap-sass
, and it get's more complicated with more nested folders. In addition, this does not work for globally installed modules.
var packageRoot = require.resolve('bootstrap-sass')
.match(/^.*[\/\\]node_modules[\/\\][^\/\\]*/)[0];
console.log(packageRoot);
这适用于 node_modules $ c中安装的本地和全局模块$ c>文件夹。正则表达式将匹配最后一个
)。 node_modules
路径元素以及以下路径元素的所有内容。但是,如果将包的入口点设置为另一个包(例如main:<。cn c> c> c> c中的./node_modules/sub-package
,则会失败.json
This will work for local and global modules installed in node_modules
folder. The regex will match everything up to the last node_modules
path element plus the following path element. However this will fail if a package's entry point is set to another package (e.g. "main": "./node_modules/sub-package"
in package.json
).
var escapeStringRegexp = require('escape-string-regexp');
/**
* Get the root path of a npm package installed in node_modules.
* @param {string} packageName The name of the package.
* @returns {string} Root path of the package without trailing slash.
* @throws Will throw an error if the package root path cannot be resolved
*/
function packageRootPath(packageName) {
var mainModulePath = require.resolve(packageName);
var escapedPackageName = escapeStringRegexp(packageName);
var regexpStr = '^.*[\\/\\\\]node_modules[\\/\\\\]' + escapedPackageName +
'(?=[\\/\\\\])';
var rootPath = mainModulePath.match(regexpStr);
if (rootPath) {
return rootPath[0];
} else {
var msg = 'Could not resolve package root path for package `' +
packageName + '`.'
throw new Error(msg);
}
}
var packageRoot = packageRootPath('bootstrap-sass');
console.log(packageRoot);
此函数适用于 node_modules $ c中安装的所有软件包$ c>文件夹。
我想知道这个相当简单的任务是否无法解决一种更简单,更少hacky的方式。对我而言,它看起来应该已经构建到Node.js中。有什么建议吗?
I wonder if this rather simple task cannot be solved in a simpler and less hacky way. To me it looks like something that should already be built into Node.js. Any suggestions?
推荐答案
试试这个:
require.resolve('bootstrap-sass/package.json')
返回:
path_to_my_project/node_modules/bootstrap-sass/package.json
您现在可以摆脱'package.json'路径后缀,例如:
You can now get rid of 'package.json' path suffix such as:
var path = require('path') // npm install path
var bootstrapPath = path.dirname(require.resolve('bootstrap-sass/package.json'))
因为每个包都必须包含 package.json
文件,这应该始终有效(参见什么是包裹?)。
Since it is mandatory for every package to contain package.json
file, this should always work (see What is a package?).
这篇关于Node.js:获取已安装的npm包的(绝对)根路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!