node.js - 如何让 Grunt Deploy 使用全局 NPM 模块而不是本地模块

标签 node.js module npm gruntjs

首先,我对 npm 和 grunt 很陌生。我们有一个项目,我们正在使用 Grunt 为其编译和生成输出文件。我正在尝试设置我们的构建服务器以使用 Grunt 生成输出文件。我们正在使用带有 TFS 源代码控制的 Windows,并且由于 it's 260 character path limit ,我们无法将 grunt-bower-task 模块 checkin 源代码控制 (as it alone uses 230 characters in its installed path)。

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

  • Grunt
  • 咕噜咕噜任务
  • grunt-contrib-compass
  • grunt-contrib-connect
  • grunt-contrib-jshint
  • grunt-contrib-requirejs
  • grunt-contrib-watch

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

虽然我可以简单地将运行 npm install 作为构建过程的一部分,但我不希望这样做,因为下载所有文件需要几分钟,而且我不想要我们的构建依赖于可用的外部网络服务。

我见过 you can install modules either locally or globally ,所以我希望能够在构建服务器上全局安装模块,这样它们就不需要在运行 grunt deploy 之前直接位于项目目录内的 node_modules 文件夹中。我已经为上面列出的每个模块运行了 npm install -g,以及 npm install -g [module],以及 npm install - g grunt-cli.

如果我执行 npm prefix -g,它会告诉我全局模块目录是 C:\Users[My User]\AppData\Roaming\npm,当我查看该目录的 node_modules 文件夹,确实看到了所有模块。但是,当我运行 grunt deploy 时,它会提示:

Fatal error: Unable to find local grunt

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

Local Npm module "grunt-contrib-watch" not found. Is it installed?

Local Npm module "grunt-contrib-jshint" not found. Is it installed?

...

我也尝试过使用 *grunt deploy --base "C:\Users[My User]\AppData\Roaming\npm",但它提示它找不到其他文件,例如 .jshintrc。

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

一个棘手的解决方法是在构建过程中手动将模块复制到本地项目目录,但如果可能的话,我想避免这种情况。

作为引用,这是我的 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"
  }
}

谢谢。

最佳答案

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

例如,假设您依赖于 module_a,而 module_a 依赖于 module_b。在 npm install 之后,您将拥有 node_modules/module_a/node_modules/module_b/,因为 npm 会将 module_b 安装到 module_a 的本地。但是,如果您在 your package.json 中添加 module_b 作为直接依赖项(并且版本说明符完全匹配),那么 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 树。

关于node.js - 如何让 Grunt Deploy 使用全局 NPM 模块而不是本地模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19795171/

相关文章:

javascript - 谷歌SDK返回403 `User Rate Limit Exceeded`

node.js - Webpack 已使用与 API 架构不匹配的配置对象进行初始化。 webpack 安装通过 "npm install webpack"

node.js - 使用 npm 管理客户端脚本

php - Composer 在自定义路径中安装包或模块?

ruby-on-rails - 我不应该在 `included do ... end` block 中包含什么?

symfony - webpack:无法读取未定义的属性 'match'

node.js - Sequelize 不存储额外的连接表字段

javascript - 无法有意发出 http 请求

node.js - 到时间后自动删除数据

ruby - 如何知道调用了哪个模块用户