如何使Grunt Deploy使用全局NPM模块而不是本地模块
首先,我对npm和grunt很新。 我们有一个项目,我们正在使用Grunt来编译和生成输出文件。 我试图设置我们的生成服务器使用Grunt生成输出文件。 我们正在使用Windows与TFS源代码控制,并由于它的260个字符的path限制 ,我们无法检查到源代码pipe理( 因为它单独使用230个字符安装path )的grunt-bower-task模块。
当我从我的项目目录运行npm install时 ,它工作正常,并将以下必需模块安装到我的项目目录中的node_modules文件夹中:
- 咕噜
- 咕噜鲍尔任务
- 咕噜-的contrib罗盘
- 咕噜-的contrib-CONNECT
- 咕噜-的contrib-jshint
- 咕噜-的contrib-requirejs
- 咕噜-的contrib手表
然后当我从我的项目目录运行grunt部署一切都按预期工作。
虽然我可以简单地使运行npm install构build过程的一部分,但我不愿意,因为它需要几分钟时间才能下载所有文件,而且我不希望我们的构build依赖于可用的外部Web服务。
我已经看到, 您可以在本地或全局安装模块 ,所以我希望能够在生成服务器上全局安装模块,以便它们不需要直接在项目目录内的node_modules文件夹中运行grunt部署 。 我已经运行了npm install -g ,以及上面列出的每个模块的npm install -g [module] ,以及npm install -g grunt-cli 。
如果我做npm前缀-g,它会告诉我全局模块目录是C:\ Users [我的用户] \ AppData \ Roaming \ npm ,当我查看该目录的node_modules文件夹时,我看到所有的模块。 但是,当我运行grunt部署它抱怨:
致命错误:无法find本地咕噜声
如果我只包含* node_modules \ grunt *目录,那么我仍然得到这些错误:
没有find本地Npm模块“grunt-contrib-watch”。 是否安装?
未find本地Npm模块“grunt-contrib-jshint”。 是否安装?
…
我也尝试过使用* grunt deploy –base“C:\ Users [我的用户] \ AppData \ Roaming \ npm”,但是它却抱怨它找不到其他文件,比如.jshintrc。
那么是否有一种方法可以运行grunt deploy ,并让它检查模块的npm全局前缀path,而不是查看项目目录?
一个黑客的解决办法是在构build过程中手动将模块复制到本地项目目录,但是我希望尽可能避免这种情况。
作为参考,这是我的package.json文件看起来像:
{ "name": "MyProject", "version": "0.0.1", "scripts": { "preinstall": "npm i -g grunt-cli bower" }, "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-compass": "~0.2.0", "grunt-contrib-watch": "~0.4.4", "grunt-contrib-jshint": "~0.6.0", "grunt-contrib-requirejs": "~0.4.1", "grunt-contrib-connect": "~0.3.0", "grunt-bower-task": "~0.2.3" } }
谢谢。
而不是使用npm
的全局选项,你应该使用模块上的符号链接来获得相似的结果。
全局npm
安装只是为了方便jshint
或grunt-cli
等命令行工具。
解决方法:明确列出您自己的package.json中的所有临时依赖项。
比如说,你依赖于module_a,而module_a依赖于module_b。 npm install
之后,你将有node_modules/module_a/node_modules/module_b/
因为npm会将module_b本地安装到module_a。 但是,如果您在package.json中添加module_b作为直接依赖项(并且版本说明符完全匹配),那么npm将只安装一次module_b:位于顶层。
这是因为当需要模块时,它们开始查看最近的node_modules目录并向上遍历,直到find所需的模块。 所以npm能够通过在模块匹配的最低级别安装模块来节省磁盘空间。
所以,修改后的例子。 您依赖于依赖于module_b@0.2.0的module_a@0.1.0。 如果你也依赖于module_b@0.1.0,你最终会安装两次module_b。 (版本0.1.0将安装在顶层,0.2.0将安装在module_a下)。但是,如果您依赖于v0.2.0(在package.json中使用确切的版本string作为module_a使用),那么npm会注意到它可以使用相同版本的module_b。 所以它只会在顶层安装module_b,而不会在module_a下安装。
长话短说:将具有较深模块树的暂时依赖关系直接添加到您自己的package.json中,最后得到一个更浅的node_modules
树。
我使用窗口来解决Windows上的这类问题。 即使它适用于Git,如果您在Team Explorer中使用Visual Studio中的Git集成,即使您的node_modules文件夹中存在长文件path,它也会崩溃 – 即使您没有将该文件夹添加到源代码pipe理中。
通常Grunt和Bower依赖结构导致这种情况。
-
我build议的第一件事是在你的软件包上运行
npm dedupe
。 这是做什么的,是扫描你已经安装的软件包,看看是否有一些依赖关系是重复的。 如果在更高的层次上发现,它将删除深度testing的。 -
其次,如果重复数据删除无法解决问题,如果您可以find导致此问题的嵌套深度的依赖关系,请尝试将其直接安装到解决scheme中,然后再次运行重复数据删除。
-
如果有更多的软件包依赖性导致这种情况,那么有限责任公司将解决这个问题。 加上它非常酷,因为你可以把它挂在你的npm install上,它会在安装新的包后运行。 另外,它是完全可逆的。
我希望这有帮助。
我知道这个线程是旧的,但我终于find了自己的个人答案,使用Mac,但我认为可以说与PC完成。
跟进bevacqua的回答:
而不是使用npm的全局选项,你应该使用模块上的符号链接来获得相似的结果。
全局npm安装只是为了方便jshint或grunt-cli等命令行工具。
我做了一些挖掘,可能会给予更多的澄清:
我结束了在我的用户目录的根目录中创build一个全局文件夹。 在那个目录中,我使用npm install
添加了我需要的所有软件包。 因此,例如,我运行了npm install grunt
, npm install grunt-contrib-watch
, npm install grunt-contrib-less
等等。你也可以在同一个文件夹中添加一个package.json
文件,然后运行npm install
将它们全部添加到一旦。 现在我的全局目录具有以下结构:
.global_grunt_modules node_modules grunt grunt-contrib-watch grunt-contrib-less
然后我去了任何需要运行grunt的工作项目目录,并在该文件夹的根目录下运行命令:
ln -s ~/.global_grunt_modules/node_modules .
在-s
(符号链接)标志中有两个参数:
[source_file] [target_dir]
所以命令基本上说:“从我的全局node_modules文件夹创build一个符号链接,并将其链接到我的当前目录”。 的.
指定当前的工作目录。
希望这有帮助,我也遇到了麻烦。 然后,每当我有一个项目需要一个新的grunt模块,我只需要通过我的全局目录来安装它,然后在任何地方都可以创build符号链接。
当npm链接不够好(networking文件系统,…)时,可以使用'requireg'包。 这是以某种方式使其“内置”的唯一清洁解决scheme。 'requireg'包有一个函数globalize,这使得后续的require调用也在全局寻找。