我的设置如下:
bower
安装{
"name": "gadada",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "me",
"dependencies": {
"bower": "latest",
},
"devDependencies": {
}
}
由于我无法在web目录中正确安装这些模块,因为同步文件夹和npm存在已知问题,我想全局安装它们。 没有伤害,因为它是一个专用的虚拟机,只适用于一个Web应用程序。
所以我这样做:
sudo npm install -g
之后我尝试使用bower
,它不起作用,因为它在npm安装期间没有链接。
我这样做很好
sudo npm install -g bower@latest
我做错了什么?
答案 0 :(得分:2)
好的,我发现,npm不能那样工作。您无法从package.json全局安装依赖命令行工具。 谢谢你指出这一点,@ Matthew Bakaitis
我昨天挖掘了npm代码,发现了一段解释这种行为的代码:
var linkStuff = build.linkStuff = function (pkg, folder, global, didRB, cb) {
// allow to opt out of linking binaries.
if (npm.config.get('bin-links') === false) return cb()
// if it's global, and folder is in {prefix}/node_modules,
// then bins are in {prefix}/bin
// otherwise, then bins are in folder/../.bin
var parent = pkg.name && pkg.name[0] === '@' ? path.dirname(path.dirname(folder)) : path.dirname(folder)
var gnm = global && npm.globalDir
var gtop = parent === gnm
log.info('linkStuff', packageId(pkg))
log.silly('linkStuff', packageId(pkg), 'has', parent, 'as its parent node_modules')
if (global) log.silly('linkStuff', packageId(pkg), 'is part of a global install')
if (gnm) log.silly('linkStuff', packageId(pkg), 'is installed into a global node_modules')
if (gtop) log.silly('linkStuff', packageId(pkg), 'is installed into the top-level global node_modules')
shouldWarn(pkg, folder, global, function () {
asyncMap(
[linkBins, linkMans, !didRB && rebuildBundles],
function (fn, cb) {
if (!fn) return cb()
log.verbose(fn.name, packageId(pkg))
fn(pkg, folder, parent, gtop, cb)
},
cb
)
})
}
在此处找到:https://github.com/npm/npm/blob/master/lib/build.js#L93
正如您在此处所看到的,关于parent
变量的评论清楚地指出,只有安装在“根”节点模块文件夹中的软件包才会全局链接,而所有其他软件包将在.bin
中链接包文件夹。
为了澄清这种行为,我将给你快速举例。
因此,我运行npm install -g
后的结构将是:
/usr/lib/node_modules
| --> npm
| --> gadada
正如我们所看到的,npm创建了一个新的子文件夹调用gadada
,这是我在包json中给出的名称。在那里放置依赖关系并在/usr/lib/node_modules/gadada/.bin
内创建链接。
这是因为当构建depdencies时,npm检查它们具有哪个父文件夹。如果不是/usr/lib/node_modules
,则不会全局链接。
为了比较,我现在运行npm install -g bower@latest
的结果会产生这个文件夹结构:
/usr/lib/node_modules
| --> npm
| --> gadada
| --> bower
在安装时,npm会意识到bower
的父文件夹是/usr/lib/node_modules
并且全局链接。
这是它背后的整个伏都教。 我没有发现任何网站解释这种特殊行为,但我想这是为了防止依赖性乱搞全局二进制文件。
只是为了澄清:节点模块的全局文件夹可能不同。
/usr/
只是我的前缀。
我尝试使用`脚本来解决这个问题。我发现了一个很棒的教程,但由于隐私浏览而失去了它:/
我建议在scripts
的{{1}}部分中包含您需要的命令,如下所示:
package.json
在你尖叫之前:Nooo,到底是什么,缺少完整的路径,考虑一下。
当您使用{
"name": "gadada",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bower": "bower"
},
"author": "me",
"dependencies": {
"bower": "latest",
},
"devDependencies": {
}
}
从脚本运行命令时,npm包含$ PATH的npm run bower
文件夹,以便可以找到二进制文件。
魔术最精彩:)
我希望我能帮助一些遇到同样问题的人:)
答案 1 :(得分:0)
如果您的意思是尝试使用package.json
在npm install -g
全局安装依赖项...那不是它的工作原理。 package.json
专门用于定义本地安装的包。它是可以与项目一起运行的必需模块的清单,允许总体项目大小在传输中更小(即,您不必在回购中包含node_modules
等)。
-g
标志用于单独安装的全局包,通常用于命令行实用程序。如果项目中的每个模块都是全局安装的,那么你的情况就不会有任何严重的问题,在其他情况下,这样的情况将是一件坏事。
所以你没有做错任何事,这不是npm如何安装。
但是,您可以使用npm脚本来定义基本上运行-g
安装的安装前或安装后步骤。这是额外的工作,但是如果你拥有这个项目并且你将会做很多......这可能是一种自动化的好方法。