Node.js 如何让Grunt部署使用全局NPM模块而不是本地模块

Node.js 如何让Grunt部署使用全局NPM模块而不是本地模块,node.js,module,npm,gruntjs,Node.js,Module,Npm,Gruntjs,首先,我对npm和grunt很陌生。我们有一个项目,我们正在使用Grunt编译和生成输出文件。我正在尝试将构建服务器设置为使用Grunt生成输出文件。我们将Windows与TFS源代码管理一起使用,由于,我们无法将grunt bower任务模块检查到源代码管理() 当我从我的项目目录运行npm install时,它工作正常,并将以下所需模块安装到我的项目目录中的node_modules文件夹中: 咕噜声 咕噜-鲍尔任务 呼噜指南针 grunt contrib连接 grunt contrib j

首先,我对npm和grunt很陌生。我们有一个项目,我们正在使用Grunt编译和生成输出文件。我正在尝试将构建服务器设置为使用Grunt生成输出文件。我们将Windows与TFS源代码管理一起使用,由于,我们无法将grunt bower任务模块检查到源代码管理()

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

  • 咕噜声
  • 咕噜-鲍尔任务
  • 呼噜指南针
  • grunt contrib连接
  • grunt contrib jshint
  • grunt contrib requirejs
  • 呼噜手表
然后,当我从我的项目目录运行grunt deploy时,一切都按预期工作

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

我已经看到了这一点,所以我希望能够在构建服务器上全局安装模块,这样在运行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\u modules文件夹时,我确实看到了所有模块。但是,当我运行grunt deploy时,它会抱怨:

致命错误:找不到本地grunt

如果仅包括*node\u modules\grunt*目录,则仍会出现以下错误:

未找到本地Npm模块“grunt contrib watch”。安装了吗

未找到本地Npm模块“grunt contrib jshint”。安装了吗

我还尝试使用*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"
  }
}

谢谢。

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


全局
npm
安装仅用于方便命令行实用程序,如
jshint
,或
grunt cli
,解决方法:在您自己的package.json中显式列出所有临时依赖项

例如,假设您依赖于模块a,而模块a依赖于模块b。在
npm安装之后
您将拥有
node_modules/module_a/node_modules/module_b/
,因为npm将在模块a本地安装模块b。但是,如果在package.json中添加模块_b作为直接依赖项(并且版本说明符完全匹配),那么npm将只在顶层安装模块_b一次

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

所以,修改示例。您依赖于模块_a@0.1.0这取决于模块_b@0.2.0. 如果您还依赖于模块_b@0.1.0,您将安装两次模块_b。(0.1.0版将安装在顶层,0.2.0版将安装在模块a下。)但是,如果您依赖于v0.2.0(使用package.json中与模块a使用的完全相同的版本字符串),那么npm将注意到它可以使用相同版本的模块b。因此,它将只在顶层安装模块_b,而不是在模块_a下安装

长话短说:将具有较深模块树的临时依赖项直接添加到您自己的package.json中,您将得到较浅的
节点\u modules
树。

我用于解决Windows上的此类问题。 即使它与Git一起工作,如果您在Team Explorer中使用Visual Studio中的Git集成,如果长文件路径位于node_modules文件夹中,即使您没有将该文件夹添加到源代码管理中,它也会崩溃

通常Grunt和Bower依赖结构会导致这种情况

  • 我建议的第一件事是在您的软件包上运行
    npm dedupe
    。这样做的目的是扫描已经安装的软件包,看看是否有重复的依赖项。如果在更高级别上发现,它将删除经过深入测试的

  • 其次,如果重复数据消除无法解决此问题,如果您可以找到导致此问题的依赖项,请尝试直接将其安装到解决方案中,然后再次运行重复数据消除

  • 如果有更多的包依赖关系导致此问题,将解决此问题。另外,它真的很酷,因为你可以把它挂到你的npm安装上,而且它总是在安装了新软件包之后运行。而且,它是完全可逆的


  • 我希望这能有所帮助。

    我知道这条线索很旧,但我最终用Mac电脑找到了自己的答案,但我认为PC也可以这么说/这么做

    跟进bevacqua的回答:


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

    全局npm安装只是为了方便命令行实用程序(如jshint或grunt cli)使用

    我做了一些挖掘,也许可以
    .global_grunt_modules
        node_modules
            grunt
            grunt-contrib-watch
            grunt-contrib-less