【问题标题】:Grunt: have package.json and Gruntfile.js on different foldersGrunt:在不同的文件夹中有 package.json 和 Gruntfile.js
【发布时间】:2017-02-15 18:44:33
【问题描述】:

我在尝试在不同文件夹上实现 grunt 时遇到问题,在我的根目录中:

<root>/package.json
<root>/node_modules

在另一个文件夹中,我的 gruntfile 包含不同的子文件夹和我工作的文件:

<root>/apps/static/Gruntfile.js

如果我进入根目录并执行

grunt --gruntfile /apps/static/Gruntfile.js MyTaskName

我明白了:

找不到本地 Npm 模块“grunt-contrib-concat”。安装了吗?

找不到本地 Npm 模块“grunt-contrib-cssmin”。安装了吗?

找不到本地 Npm 模块“grunt-contrib-clean”。安装了吗?

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

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

我运行了几次 npm install。

在我的 gruntfile.js 上你有

grunt.loadNpmTasks('grunt-contrib-concat');

grunt.loadNpmTasks('grunt-contrib-cssmin');

grunt.loadNpmTasks('grunt-contrib-clean');

grunt.loadNpmTasks('grunt-contrib-watch');

grunt.loadNpmTasks('grunt-contrib-uglify');

我三重检查,文件夹没问题(事实上,最初 gruntfile 和包在同一个文件夹中,一切正常,运行多个任务,一切正常)。我真的需要在 root 上有一个通用的 package.json 和 node_modules,在特定的项目文件夹上有一个 Gruntfile.js

知道发生了什么吗?提前致谢

【问题讨论】:

    标签: javascript node.js npm gruntjs


    【解决方案1】:

    有时,项目可能需要将Gruntfile.jspackage.json 放在不同的文件夹中。

    我有一个非常相似的用例,其中有多个子模块,每个子模块都有自己的构建过程,其中一个是 Grunt。但同时我想有一个通用的package.json 只是为了避免创建多个node_modules 文件夹,以便通用依赖项(包括传递)使用一次安装。它有助于减少安装时间和磁盘使用量。

    我期待 Grunt 本身有一个解决方案。但正如@cartant 提到的,Grunt 做出了某些假设。

    所以,这就是我所做的:

    Gruntfile.js

    定义一个函数:

    function loadExternalNpmTasks(grunt, name) {
      const tasksdir = path.join(root, 'node_modules', name, 'tasks');
      if (grunt.file.exists(tasksdir)) {
        grunt.loadTasks(tasksdir);
      } else {
        grunt.log.error('Npm module "' + name + '" not found. Is it installed?');
      }
    }
    

    而不是

    grunt.loadNpmTasks('grunt-contrib-concat');
    

    做:

    loadExternalNpmTasks(grunt, 'grunt-contrib-concat');
    

    参考:https://github.com/gruntjs/grunt/blob/master/lib/grunt/task.js#L396

    【讨论】:

      【解决方案2】:

      Grunt 对gruntfile.js 的位置做出了某些假设。

      当您使用--gruntfile 选项指定gruntfile.js 的位置时,将sets the current directory 发送到包含指定文件的目录:

      // Change working directory so that all paths are relative to the
      // Gruntfile's location (or the --base option, if specified).
      process.chdir(grunt.option('base') || path.dirname(gruntfile));
      

      当 Grunt 加载 NPM 任务时,它会这样做relative to the current directory

      var root = path.resolve('node_modules');
      var pkgfile = path.join(root, name, 'package.json');
      

      有一个--base option可以指定当前目录,但是否能解决你的问题(不引入其他问题)我不知道。最简单的解决方案可能是将gruntfile.js 定位到它想要和期望定位的位置。

      【讨论】:

      • 我阅读了关于 --base 的信息,但我仍然有问题,我在根文件夹中,我得到:找不到有效的 Gruntfile。有关如何配置 grunt 的更多信息,请参阅入门指南:gruntjs.com/getting-started 致命错误:无法找到 Gruntfile。 gruntfile 就在那里。我的问题是这是一个大项目,将所有内容放在同一个文件中可能会很复杂。我正在使用 8 个网站,每个网站都必须有他特定的咕噜声才能让它变得简单
      • 我认为在尝试定位gruntfile.js 某个它并不想被定位的地方时,你正在进入一个痛苦的世界。这看起来像XY problem。如果您的问题很复杂,Grunt 有一些其他机制可能会提供不那么痛苦的解决方案(例如grunt.config.merge)。我建议问另一个问题,询问如何解决您的复杂性问题。我认为这个为什么不工作的问题已经得到解答。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      • 2014-11-16
      相关资源
      最近更新 更多