Grunt:在不同的文件夹上有 package.json 和 Gruntfile.js

Grunt: have package.json and Gruntfile.js on different folders

我在尝试在不同文件夹上实施 g运行t 时遇到问题,在我的根目录中我有:

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

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

<root>/apps/static/Gruntfile.js

如果我转到 root 并执行

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

我得到:

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

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

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

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

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

然后我运行几次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');

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

上有一个 Gruntfile.js

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

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

当您使用 --gruntfile 选项指定 gruntfile.js 的位置时,Grunt 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 它想要和期望的位置。

有时,项目可能需要将 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