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/

相关文章:

node.js - 我可以知道,在 node.js 中,我的脚本是直接运行还是被另一个脚本加载?

node.js - 我们如何停止 webdriver-manager?

json - Node 请求模块未将 Content-Type 设置为 application/json

node.js - 将 jBPM 与 Node.js 和 PostgreSQL 集成

javascript - HAPI框架中的后续路由中完成身份验证后如何填充request.auth.isAuthenticated?

python - 将 python 模块导入例程或类定义有什么问题吗?

vb.net 模块可见性

javascript - 无法将我本地开发的 Angular 模块导入 Angular 应用程序

windows - grunt-contrib-build' 不在 npm 注册表中

javascript - Backbone ?可以.js吗?贫民窟DIY?我应该如何处理这些数据?