【发布时间】:2016-04-07 16:34:53
【问题描述】:
任务
我正在寻找一种通用方法来获取 Node.js 中已安装 npm 包的(绝对)根路径。
问题
我知道require.resolve,但这会给我入口点(主模块的路径)而不是包的根路径。
以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。
我能想到几种获取包根路径的方法:
解决方案 #1
var packageRoot = path.resolve('node_modules/bootstrap-sass');
console.log(packageRoot);
这适用于本地安装在 node_modules 文件夹中的软件包。但是,如果我在子文件夹中,我需要解析../node_modules/bootstrap-sass,而且嵌套文件夹越多,它就越复杂。此外,这不适用于全局安装的模块。
解决方案 #2
var packageRoot = require.resolve('bootstrap-sass')
.match(/^.*[\/\\]node_modules[\/\\][^\/\\]*/)[0];
console.log(packageRoot);
这适用于安装在node_modules 文件夹中的本地和全局模块。正则表达式将匹配直到最后一个 node_modules 路径元素加上以下路径元素的所有内容。但是,如果一个包的入口点设置为另一个包(例如,package.json 中的 "main": "./node_modules/sub-package"),这将失败。
解决方案 #3
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 文件夹中的所有软件包。
但是……
我想知道这个相当简单的任务是否不能用一种更简单、更简单的方式来解决。对我来说,它看起来应该已经内置到 Node.js 中了。有什么建议吗?
【问题讨论】:
-
您真正想解决什么问题(例如,您为什么要尝试这条路径)?您是否正在尝试获取模块中其他资源的路径?通常一个模块本身应该知道它自己的资源相对于它的位置在哪里,所以你只需要让模块告诉你东西在哪里,它就会给你答案。
-
我猜第一个问题是你为什么要查找模块的位置而不是它的主文件
-
其次,npm 有几个模块来提供它的功能,包括查找 node_modules 的目录,例如 read-package-tree
-
我想用 npm 安装 css 框架(例如 bootstrap)并获取包含文件的路径(例如 .css/.scss/.svg/...)。
-
read-package-tree 需要一个包根路径作为它的第一个参数...
标签: javascript node.js path npm package