简体   繁体   中英

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

Im having problems trying to implement grunt on diferent folders, in my root i have:

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

And inside another folder, my gruntfile with diferent subfolders and files wich 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 several times npm install.

On my gruntfile.js y 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 perfect, 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 whats going on? thanks in advance

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM