Reputation: 485
I'm having problems trying to implement grunt on different folders, in my root I have:
<root>/package.json
<root>/node_modules
And inside another folder, my gruntfile with different subfolders and files which I work:
<root>/apps/static/Gruntfile.js
If I go to root and execute
grunt --gruntfile /apps/static/Gruntfile.js MyTaskName
I get:
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?
And I run npm install
several times.
On my gruntfile.js I have
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');
I triple check and folders are ok (in fact, originally gruntfile and package where in the same folder and everything was working perfectly, run several task and everything is ok). I really need to have a common package.json and node_modules on root and the Gruntfile.js on a specific project folder
Any idea what's going on? Thanks in advance
Upvotes: 4
Views: 1565
Reputation: 1487
Sometimes, it may be the need of project to have Gruntfile.js
in a different folder than package.json
.
I had a very similar use-case where there were multiple submodules each with its own build process, one of them was Grunt. But at the same time I wanted to have a common package.json
just to avoid multiple node_modules
folders being created, so that common dependencies (including transitive) use to install once. It helped in reducing install time as well as disk usage.
I was expecting a solution in Grunt itself. But as @cartant mentioned, Grunt has made certain assumptions.
So, here is what I did:
In Gruntfile.js
,
Define a function:
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?');
}
}
And instead of
grunt.loadNpmTasks('grunt-contrib-concat');
do:
loadExternalNpmTasks(grunt, 'grunt-contrib-concat');
Reference: https://github.com/gruntjs/grunt/blob/master/lib/grunt/task.js#L396
Upvotes: 0
Reputation: 58440
Grunt makes certain assumptions regarding the location of gruntfile.js
.
When you specify the location of gruntfile.js
using the --gruntfile
option, Grunt sets the current directory to the directory containing the specified file:
// 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));
And when Grunt loads NPM tasks, it does so relative to the current directory:
var root = path.resolve('node_modules');
var pkgfile = path.join(root, name, 'package.json');
There is a --base
option with which the current directory can be specifed, but whether or not that will solve your problem (without introducing other problems) I do not know. The simplest solution is likely to locate gruntfile.js
where it wants and expects to be located.
Upvotes: 2