Loads de-duped grunt tasks from parent or sibling modules.
load-grunt-parent-tasks is a Grunt library that allows you to load all of your
Grunt tasks even if they are in a parent folder. This library was heavily inspired
by this StackOverflow post: "Centralise Node Modules In Project With Subproject", and
and utilizes the gruntcollection
feature of grunt.loadNpmTasks
.
If Grunt task is loaded as a submodule then create a grunt-collection
module
in your local node_modules
folder to trick grunt into loading dependencies
from a parent folder. This might be necessary if project A contains a Gruntfile.js
with dependencies X, Y, and Z, and is loaded as a npm dependency of project B
which contains dependencies A, X and Y. In that scenario Npm will de-dupe
project A's Npm dependencies when executing npm install
in project B and will
look like this:
B
├── node_modules
│ ├── A
│ │ ├── Gruntfile.js
│ │ ├── node_modules
│ │ │ └── Z
│ │ └── package.json (has depencencies X,Y,Z)
│ ├── X
│ └── Y
└── package.json (has dependencies A,X,Y)
If project A's package.json contains an install
or postinstall
script that
executes it's Gruntfile.js the Grunt task will throw 2 errors:
Local Npm module "X" not found. Is it installed?
Local Npm module "Y" not found. Is it installed?
Project A's Grunt task will not be able to load the de-duped dependencies because
they reside in the parents node_modules folder. This can be fixed by dropping in
a new module which contains project A's package.json with the addition of a
keywords
property that contains "gruntcollection"
in it's array.
B
├── node_modules
│ ├── A
│ │ ├── Gruntfile.js
│ │ ├── node_modules
│ │ │ ├── grunt-collection
│ │ │ │ └── package.json (has dependencies X,Y,Z and 'keywords: ["gruntcollection"]')
│ │ │ └── Z
│ │ └── package.json (has depencencies X,Y,Z)
│ ├── X
│ └── Y
└── package.json (has dependencies A,X,Y)
Then at the beginning of your Gruntfile.js you call grunt.loadNpmTasks('grunt-collection')
.
Now Grunt will search up for the current directory to find the modules to load.
- Checks if the main Grunt task is a submodule of another project.
- Creates a
grunt-collection
module in your localnode_modules
folder. - Creates a
grunt-collection/package.json
that is a mirror of your projectspackage.json
file defined byoptions.config
. - Filters out npm modules to load using globbing patterns defined in
options.pattern
. - Filters out which dependencies key to load from defined by
options.scope
.
##Installation
npm install --save load-grunt-parent-tasks
##Example
Basic Gruntfile.js
module.exports = function(grunt) {
require('load-grunt-parent-tasks')(grunt);
};
Creates the following:
A
├── Gruntfile.js
├── node_modules
│ └── grunt-collection
│ └── package.json
└── package.json
Gruntfile.js with options
module.exports = function(grunt) {
require('load-grunt-parent-tasks')(grunt, {
config: 'package.json',
pattern: 'grunt-*',
scope: 'dependencies',
module: 'abc-def'
});
};
// Can also be written as:
module.exports = function(grunt) {
require('load-grunt-parent-tasks')(grunt, {
config: require('package.json'),
pattern: ['grunt-*'],
scope: ['dependencies'],
module: 'abc-def'
});
};
Creates the following:
A
├── Gruntfile.js
├── node_modules
│ └── abc-def
│ └── package.json
└── package.json
Type: String
, Object
Default: Path to nearest package.json
Type: String
, Array
Default: 'grunt-*'
(globbing pattern)
Type: String
, Array
Default: ['dependencies', 'optionalDependencies']
Type: String
Default: 'grunt-collection'
The module
option can be changed in case grunt-collection
ever conflicts with any other package name.
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.