如何使Grunt Deploy使用全局NPM模块而不是本地模块

dea*_*dog 27 module node.js npm gruntjs

首先,我是npm和grunt的新手.我们有一个项目,我们正在使用Grunt来编译和生成输出文件.我正在尝试设置我们的构建服务器以使用Grunt生成输出文件.我们正在使用带有TFS源代码控制的Windows,并且由于它有260个字符的路径限制,我们无法将grunt-bower-task模块检查到源代码控制中(因为它在其安装路径中仅使用230个字符).

当我从我的项目目录运行npm install时,它工作正常,并将以下必需的模块安装到我的项目目录中的node_modules文件夹中:

  • 咕噜
  • 咕噜鲍尔任务
  • 咕噜-的contrib罗盘
  • 咕噜-的contrib-CONNECT
  • 咕噜-的contrib-jshint
  • 咕噜-的contrib-requirejs
  • 咕噜-的contrib手表

然后当我从我的项目目录运行grunt deploy时,一切都按预期工作.

虽然我可以简单地运行npm install部分构建过程,但我不愿意,因为下载所有文件需要几分钟,而且我不希望我们的构建依赖于可用的外部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 deploy时,它抱怨:

致命错误:无法找到当地的咕噜声

如果我只包含*node_modules\grunt*目录,那么我仍然会收到以下错误:

找不到本地Npm模块"grunt-contrib-watch".它安装了吗?

找不到本地Npm模块"grunt-contrib-jshint".它安装了吗?

...

我也尝试使用*grunt deploy --base"C:\ Users [我的用户]\AppData\Roaming \npm",但它抱怨说它找不到其他文件,例如.jshintrc.

那么有没有办法让我可以运行grunt deploy并让它检查模块的npm全局前缀路径,而不是查看项目目录?

一个hacky的工作是在构建过程中手动将模块复制到本地项目目录,但我想尽可能避免这种情况.

作为参考,这是我的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"
  }
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

jas*_*rns 16

解决方法:在您自己的package.json中明确列出所有瞬态依赖项.

比如说,你依赖于module_a,而module_a依赖于module_b.之后npm install你会node_modules/module_a/node_modules/module_b/因为npm将module_b local安装到module_a.但是,如果您添加module_b作为一个直接依赖的package.json(和版本说明符完全匹配),那么NPM将只安装module_b一次:在顶层.

这是因为当需要模块时,它们会开始查找最近的node_modules目录并向上遍历,直到找到所需的模块.所以npm只能通过在版本匹配的最低级别安装模块来节省磁盘空间.

所以,修改过的例子.您依赖于module_a@0.1.0,它取决于module_b@0.2.0.如果您还依赖module_b@0.1.0,那么最终会安装module_b两次.(版本0.1.0将安装在顶层,0.2.0将安装在module_a下.)但是,如果您依赖于v0.2.0(使用package.json中的确切版本字符串作为module_a使用),那么npm会注意到它可以使用相同版本的module_b.所以它只会在顶层安装module_b,而不是在module_a下.

简而言之:将具有深层模块树的瞬态依赖项直接添加到您自己的package.json中,最终会得到一个更浅的node_modules树.


bev*_*qua 7

npm您应该在模块上使用符号链接,而不是使用全局选项,以获得类似的结果.

全局npm安装仅用于方便命令行实用程序,例如jshint,或grunt-cli.

  • 我测试使用mklink.exe创建一个符号链接,它似乎工作得很好,所以这将避免我必须复制/粘贴node_modules文件夹,如果我必须使用变通方法,节省时间和空间是很好的.哦,fyi,260个字符的路径限制是Windows的限制,而不是TFS(http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx). (3认同)

小智 5

我知道这个线程很旧,但我终于找到了我自己的个人答案,使用 Mac,但我认为可以用 PC 说/做同样的事情。

跟进bevacqua的回答:

您应该在模块上使用符号链接,而不是使用 npm 的全局选项,以获得类似的结果。

全局 npm 安装只是为了方便命令行实用程序,例如 jshint 或 grunt-cli。

我做了一些挖掘,也许能够给出更多的澄清:

我最终在我的用户目录的根目录中创建了一个全局文件夹。在该目录中,我使用npm install. 例如,我运行了npm install gruntnpm install grunt-contrib-watchnpm install grunt-contrib-less等。您还可以package.json在同一文件夹中添加一个文件,然后运行npm install以一次性添加所有文件。现在我的全局目录具有以下结构:

.global_grunt_modules
    node_modules
        grunt
        grunt-contrib-watch
        grunt-contrib-less
Run Code Online (Sandbox Code Playgroud)

然后我转到任何需要运行 grunt 的工作项目目录,并在该文件夹的根目录中运行以下命令:

ln -s ~/.global_grunt_modules/node_modules .

ln带有-s(符号链接)标志需要两个参数:

[source_file] [target_dir]

所以该命令基本上是说,“从我的全局 node_modules 文件夹创建一个符号链接,并将其链接到我的当前目录”。在.指定当前的工作目录。

希望这会有所帮助,我也遇到了麻烦。然后每当我有一个需要新 grunt 模块的项目时,我只需通过我的全局目录安装它,然后在创建符号链接的任何地方都可以使用它。