├── Built-with-Grunt-Badge.md ├── Community.md ├── Configuring-tasks.md ├── Contributing.md ├── Creating-plugins.md ├── Creating-tasks.md ├── Development-Team.md ├── Development-helpers.md ├── Documentation.md ├── Exit-Codes.md ├── Frequently-Asked-Questions.md ├── Getting-started.md ├── Grunt-Brand-Guide.md ├── Grunt-Plugins.md ├── Help-Resources.md ├── Home.md ├── Inside-Tasks.md ├── Installing-grunt.md ├── Plugin-Release-Candidate-Versions.md ├── Project-Scaffolding.md ├── README.md ├── Roadmap.md ├── Sample-Gruntfile.md ├── Support.md ├── Testing-Tasks.md ├── Upgrading-from-0.3-to-0.4.md ├── Upgrading-from-0.4-to-1.0.md ├── Using-plugins.md ├── Using-the-CLI.md ├── Who-uses-Grunt.md ├── blog ├── Blog-2013-02-15-Updating-plugins-to-Grunt-0.4.md ├── Blog-2013-02-18-Grunt-0.4.0-released.md ├── Blog-2013-03-13-Grunt-0.4.1-released.md ├── Blog-2013-11-21-Grunt-0.4.2-released.md ├── Blog-2014-03-07-Grunt-0.4.3-released.md ├── Blog-2014-03-14-Grunt-0.4.4-released.md ├── Blog-2014-05-12-Grunt-0.4.5-released.md ├── Blog-2016-02-11-Grunt-1.0.0-rc1-released.md ├── Blog-2016-04-04-Grunt-1.0.0-released.md ├── Blog-2018-08-15-Grunt-CLI-1.3.0-released.md ├── Blog-2020-03-16-Grunt-1.1.0-released.md ├── Blog-2020-07-03-Grunt-1.2.0-released.md └── Blog-2021-04-22-Grunt-1.4.0-released.md ├── grunt.config.md ├── grunt.event.md ├── grunt.fail.md ├── grunt.file.md ├── grunt.log.md ├── grunt.md ├── grunt.option.md ├── grunt.task.md ├── grunt.template.md ├── grunt.util.md └── package.json /Built-with-Grunt-Badge.md: -------------------------------------------------------------------------------- 1 | Do you use Grunt in a project and want to proudly display that in your project README or on your project website? Now you can with the "Built with Grunt" badge! 2 | 3 | [![Built with Grunt](https://gruntjs.com/builtwith.svg)](https://gruntjs.com/) 4 | 5 | ## Using the Badge 6 | 7 | Just copy the following Markdown code snippet and paste it right underneath the headline in your project README. You can also put it on your project website homepage or footer. 8 | 9 | ```markdown 10 | [![Built with Grunt](https://gruntjs.com/builtwith.svg)](https://gruntjs.com/) 11 | ``` 12 | 13 | If you need an HTML version, we've got you covered. 14 | 15 | ```html 16 | 17 | Built with Grunt 18 | 19 | ``` 20 | 21 | ## For example... 22 | 23 | As you can see, the "Built with Grunt" badge is modern, stylish, and has been designed to fit nicely next to all your project's other mini-badges. You can put it first, last, or anywhere in the middle. Have fun! 24 | 25 | [![NPM version](https://badge.fury.io/js/grunt.svg)](http://badge.fury.io/) 26 | [![Built with Grunt](https://gruntjs.com/builtwith.svg)](https://gruntjs.com/) 27 | [![Tested with QUnit](https://img.shields.io/badge/tested_with-qunit-9c3493.svg)](https://qunitjs.com/) 28 | 29 | ## Shout-outs 30 | 31 | Let us know if you are using the "Built with Grunt" badge by [tweeting at @gruntjs](https://twitter.com/gruntjs). 32 | -------------------------------------------------------------------------------- /Community.md: -------------------------------------------------------------------------------- 1 | Please see the [[Help Resources]] page. 2 | -------------------------------------------------------------------------------- /Configuring-tasks.md: -------------------------------------------------------------------------------- 1 | This guide explains how to configure tasks for your project using a `Gruntfile`. If you don't know what a `Gruntfile` is, please read the [[Getting Started]] guide and check out a [[Sample Gruntfile]]. 2 | 3 | ## Grunt Configuration 4 | Task configuration is specified in your `Gruntfile` via the `grunt.initConfig` method. This configuration will mostly be under task-named properties, but may contain any arbitrary data. As long as properties don't conflict with properties your tasks require, they will be otherwise ignored. 5 | 6 | Also, because this is JavaScript, you're not limited to JSON; you may use any valid JavaScript here. You may even programmatically generate the configuration if necessary. 7 | 8 | ```js 9 | grunt.initConfig({ 10 | concat: { 11 | // concat task configuration goes here. 12 | }, 13 | uglify: { 14 | // uglify task configuration goes here. 15 | }, 16 | // Arbitrary non-task-specific properties. 17 | my_property: 'whatever', 18 | my_src_files: ['foo/*.js', 'bar/*.js'], 19 | }); 20 | ``` 21 | 22 | ## Task Configuration and Targets 23 | 24 | When a task is run, Grunt looks for its configuration under a property of the same name. Multi-tasks can have multiple configurations, defined using arbitrarily named "targets." In the example below, the `concat` task has `foo` and `bar` targets, while the `uglify` task only has a `bar` target. 25 | 26 | ```js 27 | grunt.initConfig({ 28 | concat: { 29 | foo: { 30 | // concat task "foo" target options and files go here. 31 | }, 32 | bar: { 33 | // concat task "bar" target options and files go here. 34 | }, 35 | }, 36 | uglify: { 37 | bar: { 38 | // uglify task "bar" target options and files go here. 39 | }, 40 | }, 41 | }); 42 | ``` 43 | 44 | Specifying both a task and target like `grunt concat:foo` or `grunt concat:bar` will process just the specified target's configuration, while running `grunt concat` will iterate over _all_ targets, processing each in turn. Note that if a task has been renamed with [grunt.task.renameTask](grunt.task#grunt.task.renameTask), Grunt will look for a property with the _new_ task name in the config object. 45 | 46 | ## Options 47 | Inside a task configuration, an `options` property may be specified to override built-in defaults. In addition, each target may have an `options` property which is specific to that target. Target-level options will override task-level options. 48 | 49 | The `options` object is optional and may be omitted if not needed. 50 | 51 | ```js 52 | grunt.initConfig({ 53 | concat: { 54 | options: { 55 | // Task-level options may go here, overriding task defaults. 56 | }, 57 | foo: { 58 | options: { 59 | // "foo" target options may go here, overriding task-level options. 60 | }, 61 | }, 62 | bar: { 63 | // No options specified; this target will use task-level options. 64 | }, 65 | }, 66 | }); 67 | ``` 68 | 69 | ## Files 70 | Because most tasks perform file operations, Grunt has powerful abstractions for declaring on which files the task should operate. There are several ways to define **src-dest** (source-destination) file mappings, offering varying degrees of verbosity and control. Any multi task will understand all the following formats, so choose whichever format best meets your needs. 71 | 72 | All file formats support `src` and `dest` but the [Compact](configuring-tasks#compact-format) and [Files Array](configuring-tasks#files-array-format) formats support a few additional properties: 73 | 74 | * `filter` Either a valid [fs.Stats method name](https://nodejs.org/docs/latest/api/fs.html#fs_class_fs_stats) or a function that is passed the matched `src` filepath and returns `true` or `false`. [See examples](configuring-tasks#custom-filter-function) 75 | * `nonull` If set to `true` then the operation will include non-matching patterns. Combined with grunt's `--verbose` flag, this option can help debug file path issues. 76 | * `dot` Allow patterns to match filenames starting with a period, even if the pattern does not explicitly have a period in that spot. 77 | * `matchBase` If set, patterns without slashes will be matched against the basename of the path if it contains slashes. For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. 78 | * `expand` Process a dynamic src-dest file mapping, see ["Building the files object dynamically"](configuring-tasks#building-the-files-object-dynamically) for more information. 79 | * Other properties will be passed into the underlying libs as matching options. See the [node-glob][] and [minimatch][] documentation for more options. 80 | 81 | ### Difference Between Grunt and Task Options 82 | Most tasks perform file operations, so Grunt provides a built-in infrastructure to retrieve the files a task should process. The advantage is that this logic doesn't have to be implemented again by tasks authors. To allow a user to specify these files, Grunt provides options such as `nonull` and `filter`. 83 | 84 | In addition to the files to work on, each task has its own specific needs. A task author may want to allow its user to configure some options to override the default behavior. These task-specific options shall not be confused with the Grunt options described before. 85 | 86 | To further clarify this difference, let's see an example that uses [grunt-contrib-jshint](https://github.com/gruntjs/grunt-contrib-jshint): 87 | 88 | ```js 89 | grunt.initConfig({ 90 | jshint: { 91 | ignore_warning: { 92 | options: { 93 | '-W015': true, 94 | }, 95 | src: 'js/**', 96 | filter: 'isFile' 97 | } 98 | } 99 | }); 100 | ``` 101 | 102 | This configuration employs the Grunt options `src` and `filter` to specify the files to process. It also uses the grunt-contrib-jshint task-specific option `-W015` to ignore a specific warning (the one having code `W015`). 103 | 104 | ### Compact Format 105 | This form allows a single **src-dest** (source-destination) file mapping per-target. It is most commonly used for read-only tasks, like [grunt-contrib-jshint](https://github.com/gruntjs/grunt-contrib-jshint), where a single `src` property is needed, and no `dest` key is relevant. This format also supports additional properties per src-dest file mapping. 106 | 107 | ```js 108 | grunt.initConfig({ 109 | jshint: { 110 | foo: { 111 | src: ['src/aa.js', 'src/aaa.js'] 112 | }, 113 | }, 114 | concat: { 115 | bar: { 116 | src: ['src/bb.js', 'src/bbb.js'], 117 | dest: 'dest/b.js', 118 | }, 119 | }, 120 | }); 121 | ``` 122 | 123 | ### Files Object Format 124 | This form supports multiple src-dest mappings per-target, where the property name is the destination file, and its value is the source file(s). Any number of src-dest file mappings may be specified in this way, but additional properties may not be specified per mapping. 125 | 126 | ```js 127 | grunt.initConfig({ 128 | concat: { 129 | foo: { 130 | files: { 131 | 'dest/a.js': ['src/aa.js', 'src/aaa.js'], 132 | 'dest/a1.js': ['src/aa1.js', 'src/aaa1.js'], 133 | }, 134 | }, 135 | bar: { 136 | files: { 137 | 'dest/b.js': ['src/bb.js', 'src/bbb.js'], 138 | 'dest/b1.js': ['src/bb1.js', 'src/bbb1.js'], 139 | }, 140 | }, 141 | }, 142 | }); 143 | ``` 144 | 145 | ### Files Array Format 146 | This form supports multiple src-dest file mappings per-target, while also allowing additional properties per mapping. 147 | 148 | ```js 149 | grunt.initConfig({ 150 | concat: { 151 | foo: { 152 | files: [ 153 | {src: ['src/aa.js', 'src/aaa.js'], dest: 'dest/a.js'}, 154 | {src: ['src/aa1.js', 'src/aaa1.js'], dest: 'dest/a1.js'}, 155 | ], 156 | }, 157 | bar: { 158 | files: [ 159 | {src: ['src/bb.js', 'src/bbb.js'], dest: 'dest/b/', nonull: true}, 160 | {src: ['src/bb1.js', 'src/bbb1.js'], dest: 'dest/b1/', filter: 'isFile'}, 161 | ], 162 | }, 163 | }, 164 | }); 165 | ``` 166 | 167 | ### Older Formats 168 | The **dest-as-target** file format is a holdover from before multi tasks and targets existed, where the destination filepath is actually the target name. Unfortunately, because target names are filepaths, running `grunt task:target` can be awkward. Also, you can't specify target-level options or additional properties per src-dest file mapping. 169 | 170 | Consider this format deprecated, and avoid it where possible. 171 | 172 | ```js 173 | grunt.initConfig({ 174 | concat: { 175 | 'dest/a.js': ['src/aa.js', 'src/aaa.js'], 176 | 'dest/b.js': ['src/bb.js', 'src/bbb.js'], 177 | }, 178 | }); 179 | ``` 180 | 181 | ### Custom Filter Function 182 | The `filter` property can help you target files with a greater level of detail. Simply use a valid [fs.Stats method name](https://nodejs.org/docs/latest/api/fs.html#fs_class_fs_stats). The following will clean only if the pattern matches an actual file: 183 | 184 | ```js 185 | grunt.initConfig({ 186 | clean: { 187 | foo: { 188 | src: ['tmp/**/*'], 189 | filter: 'isFile', 190 | }, 191 | }, 192 | }); 193 | ``` 194 | 195 | Or create your own `filter` function and return `true` or `false` whether the file should be matched. For example the following will only clean folders that are empty: 196 | 197 | ```js 198 | grunt.initConfig({ 199 | clean: { 200 | foo: { 201 | src: ['tmp/**/*'], 202 | filter: function(filepath) { 203 | return (grunt.file.isDir(filepath) && require('fs').readdirSync(filepath).length === 0); 204 | }, 205 | }, 206 | }, 207 | }); 208 | ``` 209 | 210 | Another example—which utilizes the [globbing](configuring-tasks#globbing-patterns) and [expand: true](configuring-tasks#building-the-files-object-dynamically) features—allows you to avoid overwriting files which already exist in the destination: 211 | 212 | ```js 213 | grunt.initConfig({ 214 | copy: { 215 | templates: { 216 | files: [{ 217 | expand: true, 218 | cwd: ['templates/css/'], // Parent folder of original CSS templates 219 | src: '**/*.css', // Collects all `*.css` files within the parent folder (and its subfolders) 220 | dest: 'src/css/', // Stores the collected `*.css` files in your `src/css/` folder 221 | filter: function (dest) { // `dest`, in this instance, is the filepath of each matched `src` 222 | var cwd = this.cwd, // Configures variables (these are documented for your convenience only) 223 | src = dest.replace(new RegExp('^' + cwd), ''); 224 | dest = grunt.task.current.data.files[0].dest; 225 | return (!grunt.file.exists(dest + src)); // Copies `src` files ONLY if their destinations are unoccupied 226 | } 227 | }] 228 | } 229 | } 230 | }); 231 | ``` 232 | 233 | Keep in mind the above technique does not account for the [rename property](configuring-tasks#building-the-files-object-dynamically) when checking if the destination exists. 234 | 235 | ### Globbing patterns 236 | It is often impractical to specify all source filepaths individually, so Grunt supports filename expansion (also known as globbing) via the built-in [node-glob][] and [minimatch][] libraries. 237 | 238 | [node-glob]: https://github.com/isaacs/node-glob 239 | [minimatch]: https://github.com/isaacs/minimatch 240 | 241 | While this isn't a comprehensive tutorial on globbing patterns, know that in a filepath: 242 | 243 | * `*` matches any number of characters, but not `/` 244 | * `?` matches a single character, but not `/` 245 | * `**` matches any number of characters, including `/`, as long as it's the only thing in a path part 246 | * `{}` allows for a comma-separated list of "or" expressions 247 | * `!` at the beginning of a pattern will negate the match 248 | 249 | All most people need to know is that `foo/*.js` will match all files ending with `.js` in the `foo/` subdirectory, but `foo/**/*.js` will match all files ending with `.js` in the `foo/` subdirectory _and all of its subdirectories_. 250 | 251 | Also, in order to simplify otherwise complicated globbing patterns, Grunt allows arrays of file paths or globbing patterns to be specified. Patterns are processed in-order, with `!`-prefixed matches excluding matched files from the result set. The result set is uniqued. 252 | 253 | For example: 254 | 255 | ```js 256 | // You can specify single files: 257 | {src: 'foo/this.js', dest: ...} 258 | // Or arrays of files: 259 | {src: ['foo/this.js', 'foo/that.js', 'foo/the-other.js'], dest: ...} 260 | // Or you can generalize with a glob pattern: 261 | {src: 'foo/th*.js', dest: ...} 262 | 263 | // This single node-glob pattern: 264 | {src: 'foo/{a,b}*.js', dest: ...} 265 | // Could also be written like this: 266 | {src: ['foo/a*.js', 'foo/b*.js'], dest: ...} 267 | 268 | // All .js files, in foo/, in alpha order: 269 | {src: ['foo/*.js'], dest: ...} 270 | // Here, bar.js is first, followed by the remaining files, in alpha order: 271 | {src: ['foo/bar.js', 'foo/*.js'], dest: ...} 272 | 273 | // All files except for bar.js, in alpha order: 274 | {src: ['foo/*.js', '!foo/bar.js'], dest: ...} 275 | // All files in alpha order, but with bar.js at the end. 276 | {src: ['foo/*.js', '!foo/bar.js', 'foo/bar.js'], dest: ...} 277 | 278 | // Templates may be used in filepaths or glob patterns: 279 | {src: ['src/<%= basename %>.js'], dest: 'build/<%= basename %>.min.js'} 280 | // But they may also reference file lists defined elsewhere in the config: 281 | {src: ['foo/*.js', '<%= jshint.all.src %>'], dest: ...} 282 | ``` 283 | 284 | For more on glob pattern syntax, see the [node-glob][] and [minimatch][] documentation. 285 | 286 | ### Building the files object dynamically 287 | When you want to process many individual files, a few additional properties may be used to build a files list dynamically. These properties may be specified in both [Compact](configuring-tasks#compact-format) and [Files Array](configuring-tasks#files-array-format) mapping formats. 288 | 289 | `expand` Set to `true` will enable the following properties: 290 | 291 | * `cwd` All `src` matches are relative to (but don't include) this path. 292 | * `src` Pattern(s) to match, relative to the `cwd`. 293 | * `dest` Destination path prefix. 294 | * `ext` Replace any existing extension with this value in generated `dest` paths. 295 | * `extDot` Used to indicate where the period indicating the extension is located. Can take either `'first'` (extension begins after the first period in the file name) or `'last'` (extension begins after the last period), and is set by default to `'first'` *[Added in 0.4.3]* 296 | * `flatten` Remove all path parts from generated `dest` paths. 297 | * `rename` Embeds a customized function, which returns a string containing the new destination and filename. This function is called for each matched `src` file (after extension renaming and flattening). [More information](configuring-tasks#the-rename-property) 298 | 299 | In the following example, the `uglify` task will see the same list of src-dest file mappings for both the `static_mappings` and `dynamic_mappings` targets, because Grunt will automatically expand the `dynamic_mappings` files object into 4 individual static src-dest file mappings—assuming 4 files are found—when the task runs. 300 | 301 | Any combination of static src-dest and dynamic src-dest file mappings may be specified. 302 | 303 | ```js 304 | grunt.initConfig({ 305 | uglify: { 306 | static_mappings: { 307 | // Because these src-dest file mappings are manually specified, every 308 | // time a new file is added or removed, the Gruntfile has to be updated. 309 | files: [ 310 | {src: 'lib/a.js', dest: 'build/a.min.js'}, 311 | {src: 'lib/b.js', dest: 'build/b.min.js'}, 312 | {src: 'lib/subdir/c.js', dest: 'build/subdir/c.min.js'}, 313 | {src: 'lib/subdir/d.js', dest: 'build/subdir/d.min.js'}, 314 | ], 315 | }, 316 | dynamic_mappings: { 317 | // Grunt will search for "**/*.js" under "lib/" when the "uglify" task 318 | // runs and build the appropriate src-dest file mappings then, so you 319 | // don't need to update the Gruntfile when files are added or removed. 320 | files: [ 321 | { 322 | expand: true, // Enable dynamic expansion. 323 | cwd: 'lib/', // Src matches are relative to this path. 324 | src: ['**/*.js'], // Actual pattern(s) to match. 325 | dest: 'build/', // Destination path prefix. 326 | ext: '.min.js', // Dest filepaths will have this extension. 327 | extDot: 'first' // Extensions in filenames begin after the first dot 328 | }, 329 | ], 330 | }, 331 | }, 332 | }); 333 | ``` 334 | 335 | #### The rename Property 336 | The `rename` property is unique, as the only valid value for it is a JavaScript function. Although the function returns a string, you cannot simply use a string as a value for `rename` (doing so results in an error: `Property 'rename' of object # is not a function`). In the following example, the `copy` task will create a backup of README.md. 337 | 338 | ```js 339 | grunt.initConfig({ 340 | copy: { 341 | backup: { 342 | files: [{ 343 | expand: true, 344 | src: ['docs/README.md'], // The README.md file has been specified for backup 345 | rename: function () { // The value for rename must be a function 346 | return 'docs/BACKUP.txt'; // The function must return a string with the complete destination 347 | } 348 | }] 349 | } 350 | } 351 | }); 352 | ``` 353 | 354 | When the function is called, the `dest` and matched `src` path are passed in and can be used for returning the output string. In the following example, files are copied from the `dev` folder to the `dist` folder, and renamed to have the word "beta" removed . 355 | 356 | ```js 357 | grunt.initConfig({ 358 | copy: { 359 | production: { 360 | files: [{ 361 | expand: true, 362 | cwd: 'dev/', 363 | src: ['*'], 364 | dest: 'dist/', 365 | rename: function (dest, src) { // The `dest` and `src` values can be passed into the function 366 | return dest + src.replace('beta',''); // The `src` is being renamed; the `dest` remains the same 367 | } 368 | }] 369 | } 370 | } 371 | }); 372 | ``` 373 | 374 | If multiple matched `src` paths are renamed to an identical destination (i.e. if two different files get renamed to the same file), each output will be added to an array of sources for it. 375 | 376 | ## Templates 377 | Templates specified using `<% %>` delimiters will be automatically expanded when tasks read them from the config. Templates are expanded recursively until no more remain. 378 | 379 | The entire config object is the context in which properties are resolved. Additionally, `grunt` and its methods are available inside templates, eg. `<%= grunt.template.today('yyyy-mm-dd') %>`. 380 | 381 | * `<%= prop.subprop %>` Expand to the value of `prop.subprop` in the config, regardless of type. Templates like this can be used to reference not only string values, but also arrays or other objects. 382 | * `<% %>` Execute arbitrary inline JavaScript code. This is useful with control flow or looping. 383 | 384 | Given the sample `concat` task configuration below, running `grunt concat:sample` will generate a file named `build/abcde.js` by concatenating the banner `/* abcde */` with all files matching `foo/*.js` + `bar/*.js` + `baz/*.js`. 385 | 386 | ```js 387 | grunt.initConfig({ 388 | concat: { 389 | sample: { 390 | options: { 391 | banner: '/* <%= baz %> */\n', // '/* abcde */\n' 392 | }, 393 | src: ['<%= qux %>', 'baz/*.js'], // [['foo/*.js', 'bar/*.js'], 'baz/*.js'] 394 | dest: 'build/<%= baz %>.js', // 'build/abcde.js' 395 | }, 396 | }, 397 | // Arbitrary properties used in task configuration templates. 398 | foo: 'c', 399 | bar: 'b<%= foo %>d', // 'bcd' 400 | baz: 'a<%= bar %>e', // 'abcde' 401 | qux: ['foo/*.js', 'bar/*.js'], 402 | }); 403 | ``` 404 | 405 | ## Importing External Data 406 | In the following Gruntfile, project metadata is imported into the Grunt config from a `package.json` file, and the [grunt-contrib-uglify plugin](https://github.com/gruntjs/grunt-contrib-uglify) `uglify` task is configured to minify a source file and generate a banner comment dynamically using that metadata. 407 | 408 | Grunt has `grunt.file.readJSON` and `grunt.file.readYAML` methods for importing JSON and YAML data. 409 | 410 | ```js 411 | grunt.initConfig({ 412 | pkg: grunt.file.readJSON('package.json'), 413 | uglify: { 414 | options: { 415 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' 416 | }, 417 | dist: { 418 | src: 'src/<%= pkg.name %>.js', 419 | dest: 'dist/<%= pkg.name %>.min.js' 420 | } 421 | } 422 | }); 423 | ``` 424 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | There are a number of Grunt projects. 2 | 3 | * [grunt](https://github.com/gruntjs/grunt) - the main Grunt project 4 | * [grunt-init](https://github.com/gruntjs/grunt-init) - the standalone grunt-init project scaffolding tool 5 | * [gruntjs.com](https://github.com/gruntjs/gruntjs.com) - the gruntjs.com website 6 | * [grunt-contrib collection](https://github.com/gruntjs/grunt-contrib) - a collection of all Grunt "contrib" plugins 7 | 8 | In addition, each individual grunt-contrib plugin is a separate repository listed on the [gruntjs org homepage](https://github.com/gruntjs). Each repository has its own maintainers, you can easily find the maintainers 9 | by looking at recent commits and pushes. Just create an issue in the repository that interests you and `@mention` one of the maintainers to get started. 10 | 11 | ## Contributors License Agreement 12 | 13 | Most forms of contribution aside from providing support to other users requires that you **[sign and submit](https://contribute.jquery.org/cla/)** a Contributors License Agreement (or "CLA" for short) with the jQuery Foundation. 14 | 15 | 16 | In summary, the CLA asserts that when you donate fixes or documentation, you both own the code that you're submitting and that the jQuery Foundation can in turn license that code to other people. 17 | 18 | Sending in a CLA is a one-time thing, and once it's done, you're in the clear to start contributing to all jQuery Foundation projects! To be effective, though, you need to know a little bit about how contributors and Committers coordinate their work, so getting involved and asking questions should be your first step. 19 | 20 | For more on CLAs, read [Alex Russell's Why Do I Need to Sign This?](https://infrequently.org/2008/06/why-do-i-need-to-sign-this/). 21 | 22 | ## Want to contribute? 23 | 24 | If you want to contribute, but don't know where to get started, this is for you. 25 | Issues that are linked below were marked as __needs PR__, this means they need a pull request to be fixed. 26 | Choose any of these issues and make sure to comment if you are working on them. 27 | 28 | * grunt-init - [Contribution guidelines should go into contributing.md](https://github.com/gruntjs/grunt-init/issues/5) 29 | * grunt-contrib-jade - [Add support for basedir option](https://github.com/gruntjs/grunt-contrib-jade/issues/64) 30 | * grunt-init-gruntfile - [Doesn't generate a package.json](https://github.com/gruntjs/grunt-init-gruntfile/issues/6) 31 | * grunt-contrib-coffee - [Support the process option](https://github.com/gruntjs/grunt-contrib-coffee/issues/61) 32 | * grunt - [--gruntfile parameter broken with parent directories](https://github.com/gruntjs/grunt/issues/950) 33 | * grunt-contrib-compress - [Add bzip2 support](https://github.com/gruntjs/grunt-contrib-compress/issues/47) 34 | * grunt-contrib-jasmine - [Enhance logging](https://github.com/gruntjs/grunt-contrib-jasmine/issues/80) 35 | * grunt-contrib-less [Sourcemaps with multiple src files](https://github.com/gruntjs/grunt-contrib-less/issues/89) 36 | 37 | ## Publishing a new version 38 | 39 | To publish a new version of a `grunt-contrib-*` plugin follow these steps: 40 | 41 | * check the plugin GitHub page to make sure it is passing Travis CI. 42 | * `cd` into the plugin directory. 43 | * `git pull` the latest changes from the `master` branch. 44 | * `rm -rf node_modules` remove stale or old node modules. 45 | * `npm install` to get the latest version of the node modules. 46 | * run `npm test` and make sure all tests pass locally. 47 | * bump the version in `package.json` 48 | * update CHANGELOG.md 49 | * run `grunt` in the plugin directory. This should generate the new README. 50 | * commit the changelog, `package.json` and README changes. 51 | * create a new git tag for the new version. use this format for the tag: `vX.Y.Z`. (such as `v0.1.13`) 52 | * push changes to `master`, push tag to the plugin repo. 53 | * Publish to npm: `npm publish .`. If you do not have access to `npm publish` ask one of the core contributors to publish for you. 54 | 55 | # Non-code contributions 56 | 57 | If you don't feel like writing code you can still contribute to the project! 58 | 59 | * You may submit updates and improvements to the [documentation](https://github.com/gruntjs/grunt-docs). 60 | * Submit articles and guides which are also part of the [documentation](https://github.com/gruntjs/grunt-docs). 61 | * Help Grunt users by answering questions on [StackOverflow](https://stackoverflow.com/questions/tagged/gruntjs), [IRC](https://gruntjs.com/help-resources#irc) and [GitHub](https://github.com/search?q=user%3Agruntjs&state=open&type=Issues&utf8=%E2%9C%93). 62 | 63 | ## Filing issues 64 | If something isn't working like you think it should, please read [the documentation](https://github.com/gruntjs/grunt/wiki), especially the [[Getting Started]] guide. If you'd like to chat with someone, [[pop into IRC|contributing#discussing-grunt]] discussing-grunt and ask your question there. 65 | 66 | If you have a question not covered in the documentation or want to report a bug, the best way to ensure it gets addressed is to file it in the appropriate issues tracker. 67 | 68 | * **If there's an issue with grunt, grunt-init, a grunt-lib-??? module, or a specific grunt-contrib-??? plugin** 69 | * Please file an issue on that project's issues tracker. 70 | * **If you'd like to contribute a new plugin** 71 | * Please file an issue on the [grunt-contrib collection issues tracker](https://github.com/gruntjs/grunt-contrib/issues). We don't accept all plugins, but we'll certainly consider yours. 72 | * **If there's an issue with the [website](https://gruntjs.com/)** 73 | * Please file an issue on the [gruntjs.com website issues tracker](https://github.com/gruntjs/gruntjs.com/issues). 74 | * **If there's an issue that isn't specific to any of the above** 75 | * Please file an issue on the [grunt issues tracker](https://github.com/gruntjs/grunt/issues) and let us know why you're filing it there. 76 | 77 | ### Simplify the issue 78 | Try to [reduce your code](http://www.webkit.org/quality/reduction.html) to the bare minimum required to reproduce the issue. This makes it much easier (and much faster) to isolate and fix the issue. 79 | 80 | ### Explain the issue 81 | If we can't reproduce the issue, we can't fix it. Please list the exact steps required to reproduce the issue. Include versions of your OS, Node.js, grunt, etc. Include relevant logs or sample code. 82 | 83 | ## Discussing grunt 84 | Join the [freenode](http://freenode.net/): IRC #grunt channel for general discussion or #grunt-dev for core and plugin development discussion. We've got a bot and everything. 85 | 86 | _No private messages, please._ 87 | 88 | ## Modifying grunt 89 | First, ensure that you have the latest [Node.js](https://nodejs.org/) and [npm](https://www.npmjs.com/) installed. 90 | 91 | 1. Ensure grunt-cli is installed (see the [[Getting started]] guide for more information) 92 | 2. Fork and clone the repo. 93 | 3. Check out the master branch (most grunt/grunt-contrib development happens there). 94 | 4. Run `npm install` to install all Grunt dependencies. 95 | 5. Run `npm uninstall grunt` this will remove the extra Grunt in your `node_modules`, see [npm issue 3958](https://github.com/npm/npm/issues/3958) 96 | 6. Run `grunt` to Grunt grunt. 97 | 98 | Assuming that you don't see any red, you're ready to go. Just be sure to run `grunt` after making any changes, to ensure that nothing has broken. 99 | 100 | ### Submitting pull requests 101 | 102 | 1. Create a new branch, please don't work in `master` directly. 103 | 2. Add failing tests for the change you want to make. Run `grunt` to see the tests fail. 104 | 3. Fix stuff. 105 | 4. Run `grunt` to see if the tests pass. Repeat steps 2-4 until done. 106 | 5. Update the documentation to reflect any changes. 107 | 6. Push to your fork and submit a pull request. 108 | 109 | ### Syntax 110 | 111 | * Two space indents. Don't use tabs anywhere. Use `\t` if you need a tab character in a string. 112 | * No trailing whitespace, except in markdown files where a linebreak must be forced. 113 | * Don't go overboard with the whitespace. 114 | * No more than [one assignment](https://benalman.com/news/2012/05/multiple-var-statements-javascript/) per `var` statement. 115 | * Delimit strings with single-quotes `'`, not double-quotes `"`. 116 | * Prefer `if` and `else` to ["clever"](https://softwareengineering.stackexchange.com/a/25281) uses of `? :` conditional or `||`, `&&` logical operators. 117 | * Comments are great. Just put them _before_ the line of code, _not_ at the _end_ of the line. 118 | * **When in doubt, follow the conventions you see used in the source already.** 119 | 120 | ### READMEs 121 | All of the grunt-contrib-* plugins use [grunt-contrib-internal](https://github.com/gruntjs/grunt-contrib-internal) to construct the `README.md` and `CONTRIBUTING.md` files. The source files are located in the corresponding `docs/` folder. The change logs in the READMEs are generated from the `CHANGELOG` file. 122 | 123 | When submitting changes to the README files please just edit the source files rather than the README directly. 124 | -------------------------------------------------------------------------------- /Creating-plugins.md: -------------------------------------------------------------------------------- 1 | 1. Install [grunt-init](https://github.com/gruntjs/grunt-init) with `npm install -g grunt-init` 2 | 2. Install the gruntplugin template with `git clone git://github.com/gruntjs/grunt-init-gruntplugin.git ~/.grunt-init/gruntplugin` (`%USERPROFILE%\.grunt-init\gruntplugin` on Windows). 3 | 3. Run `grunt-init gruntplugin` in an empty directory. 4 | 4. Run `npm install` to prepare the development environment. 5 | 5. Author your plugin. 6 | 6. Run `npm publish` to publish the Grunt plugin to npm! 7 | 8 | ## Notes 9 | 10 | ### Naming your task 11 | 12 | The "grunt-contrib" namespace is reserved for tasks maintained by the Grunt team, please name your task something appropriate that avoids that naming scheme. 13 | 14 | ### Debugging 15 | Grunt hides error stack traces by default, but they can be enabled for easier task debugging with the `--stack` option. If you want Grunt to always log stack traces on errors, create an alias in your shell. Eg, in bash, you could do `alias grunt='grunt --stack'`. 16 | 17 | ### Storing task files 18 | 19 | Only store data files in a .grunt/[npm-module-name]/ directory at the project's root and clean up after yourself when appropriate. This is not a solution for temporary scratch files, use one of the common npm modules (eg [temporary](https://www.npmjs.org/package/temporary), [tmp](https://www.npmjs.org/package/tmp)) that take advantage of the OS level temporary directories for that case. 20 | 21 | ### Avoid Changing the Current Working Directory: `process.cwd()` 22 | By default, the current working directory is set to be the directory that contains the gruntfile. The user can change it using `grunt.file.setBase()` in their gruntfile, but plugins should take care to not change it. 23 | 24 | `path.resolve('foo')` can be used to get the absolute path of the filepath 'foo' relative to the `Gruntfile`. 25 | 26 | ### Creating your task 27 | 28 | You might also want to know how to [create your own tasks](https://gruntjs.com/creating-tasks) or take a look at the [API](https://gruntjs.com/api) reference. 29 | -------------------------------------------------------------------------------- /Creating-tasks.md: -------------------------------------------------------------------------------- 1 | Tasks are grunt's bread and butter. The stuff you do most often, like `jshint` or `nodeunit`. Every time Grunt is run, you specify one or more tasks to run, which tells Grunt what you'd like it to do. 2 | 3 | If you don't specify a task, but a task named "default" has been defined, that task will run (unsurprisingly) by default. 4 | 5 | ## Alias Tasks 6 | If a task list is specified, the new task will be an alias for one or more other tasks. Whenever this "alias task" is run, every specified tasks in `taskList` will be run, in the order specified. The `taskList` argument must be an array of tasks. 7 | 8 | ```js 9 | grunt.registerTask(taskName, [description, ] taskList) 10 | ``` 11 | 12 | This example alias task defines a "default" task whereby the "jshint", "qunit", "concat" and "uglify" tasks are run automatically if Grunt is executed without specifying any tasks: 13 | 14 | ```js 15 | grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']); 16 | ``` 17 | 18 | Task arguments can be specified as well. In this example, the alias "dist" runs both the "concat" and "uglify" tasks, each with a "dist" argument: 19 | 20 | ```js 21 | grunt.registerTask('dist', ['concat:dist', 'uglify:dist']); 22 | ``` 23 | 24 | ## Multi Tasks 25 | When a multi task is run, Grunt looks for a property of the same name in the Grunt configuration. Multi-tasks can have multiple configurations, defined using arbitrarily named "targets." 26 | 27 | Specifying both a task and target like `grunt concat:foo` or `grunt concat:bar` will process just the specified target's configuration, while running `grunt concat` will iterate over _all_ targets, processing each in turn. Note that if a task has been renamed with [grunt.task.renameTask](grunt.task#grunt.task.renameTask), Grunt will look for a property with the _new_ task name in the config object. 28 | 29 | Most of the contrib tasks, including the [grunt-contrib-jshint plugin jshint task](https://github.com/gruntjs/grunt-contrib-jshint#jshint-task) and [grunt-contrib-concat plugin concat task](https://github.com/gruntjs/grunt-contrib-concat#concat-task) are multi tasks. 30 | 31 | ```js 32 | grunt.registerMultiTask(taskName, [description, ] taskFunction) 33 | ``` 34 | 35 | Given the specified configuration, this example multi task would log `foo: 1,2,3` if Grunt was run via `grunt log:foo`, or it would log `bar: hello world` if Grunt was run via `grunt log:bar`. If Grunt was run as `grunt log` however, it would log `foo: 1,2,3` then `bar: hello world` then `baz: false`. 36 | 37 | ```js 38 | grunt.initConfig({ 39 | log: { 40 | foo: [1, 2, 3], 41 | bar: 'hello world', 42 | baz: false 43 | } 44 | }); 45 | 46 | grunt.registerMultiTask('log', 'Log stuff.', function() { 47 | grunt.log.writeln(this.target + ': ' + this.data); 48 | }); 49 | ``` 50 | 51 | 52 | ## "Basic" Tasks 53 | When a basic task is run, Grunt doesn't look at the configuration or environment—it just runs the specified task function, passing any specified colon-separated arguments in as function arguments. 54 | 55 | ```js 56 | grunt.registerTask(taskName, [description, ] taskFunction) 57 | ``` 58 | 59 | This example task logs `foo, testing 123` if Grunt is run via `grunt foo:testing:123`. If the task is run without arguments as `grunt foo` the task logs `foo, no args`. 60 | 61 | ```js 62 | grunt.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) { 63 | if (arguments.length === 0) { 64 | grunt.log.writeln(this.name + ", no args"); 65 | } else { 66 | grunt.log.writeln(this.name + ", " + arg1 + " " + arg2); 67 | } 68 | }); 69 | ``` 70 | 71 | ## Custom tasks 72 | You can go crazy with tasks. If your tasks don't follow the "multi task" structure, use a custom task. 73 | 74 | ```js 75 | grunt.registerTask('default', 'My "default" task description.', function() { 76 | grunt.log.writeln('Currently running the "default" task.'); 77 | }); 78 | ``` 79 | 80 | Inside a task, you can run other tasks. 81 | 82 | ```js 83 | grunt.registerTask('foo', 'My "foo" task.', function() { 84 | // Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order. 85 | grunt.task.run('bar', 'baz'); 86 | // Or: 87 | grunt.task.run(['bar', 'baz']); 88 | }); 89 | ``` 90 | 91 | Tasks can be asynchronous. 92 | 93 | ```js 94 | grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() { 95 | // Force task into async mode and grab a handle to the "done" function. 96 | var done = this.async(); 97 | // Run some sync stuff. 98 | grunt.log.writeln('Processing task...'); 99 | // And some async stuff. 100 | setTimeout(function() { 101 | grunt.log.writeln('All done!'); 102 | done(); 103 | }, 1000); 104 | }); 105 | ``` 106 | 107 | Tasks can access their own name and arguments. 108 | 109 | ```js 110 | grunt.registerTask('foo', 'My "foo" task.', function(a, b) { 111 | grunt.log.writeln(this.name, a, b); 112 | }); 113 | 114 | // Usage: 115 | // grunt foo 116 | // logs: "foo", undefined, undefined 117 | // grunt foo:bar 118 | // logs: "foo", "bar", undefined 119 | // grunt foo:bar:baz 120 | // logs: "foo", "bar", "baz" 121 | ``` 122 | 123 | Tasks can fail if any errors were logged. 124 | 125 | ```js 126 | grunt.registerTask('foo', 'My "foo" task.', function() { 127 | if (failureOfSomeKind) { 128 | grunt.log.error('This is an error message.'); 129 | } 130 | 131 | // Fail by returning false if this task had errors 132 | if (ifErrors) { return false; } 133 | 134 | grunt.log.writeln('This is the success message'); 135 | }); 136 | ``` 137 | 138 | When tasks fail, all subsequent tasks will be aborted unless `--force` was specified. 139 | 140 | ```js 141 | grunt.registerTask('foo', 'My "foo" task.', function() { 142 | // Fail synchronously. 143 | return false; 144 | }); 145 | 146 | grunt.registerTask('bar', 'My "bar" task.', function() { 147 | var done = this.async(); 148 | setTimeout(function() { 149 | // Fail asynchronously. 150 | done(false); 151 | }, 1000); 152 | }); 153 | ``` 154 | 155 | Tasks can be dependent on the successful execution of other tasks. Note that `grunt.task.requires` won't actually RUN the other task(s). It'll just check to see that it has run and not failed. 156 | 157 | ```js 158 | grunt.registerTask('foo', 'My "foo" task.', function() { 159 | return false; 160 | }); 161 | 162 | grunt.registerTask('bar', 'My "bar" task.', function() { 163 | // Fail task if "foo" task failed or never ran. 164 | grunt.task.requires('foo'); 165 | // This code executes if the "foo" task ran successfully. 166 | grunt.log.writeln('Hello, world.'); 167 | }); 168 | 169 | // Usage: 170 | // grunt foo bar 171 | // doesn't log, because foo failed. 172 | // ***Note: This is an example of space-separated sequential commands, 173 | // (similar to executing two lines of code: `grunt foo` then `grunt bar`) 174 | // grunt bar 175 | // doesn't log, because foo never ran. 176 | ``` 177 | 178 | Tasks can fail if required configuration properties don't exist. 179 | 180 | ```js 181 | grunt.registerTask('foo', 'My "foo" task.', function() { 182 | // Fail task if "meta.name" config prop is missing 183 | // Format 1: String 184 | grunt.config.requires('meta.name'); 185 | // or Format 2: Array 186 | grunt.config.requires(['meta', 'name']); 187 | // Log... conditionally. 188 | grunt.log.writeln('This will only log if meta.name is defined in the config.'); 189 | }); 190 | ``` 191 | 192 | Tasks can access configuration properties. 193 | 194 | ```js 195 | grunt.registerTask('foo', 'My "foo" task.', function() { 196 | // Log the property value. Returns null if the property is undefined. 197 | grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name')); 198 | // Also logs the property value. Returns null if the property is undefined. 199 | grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name'])); 200 | }); 201 | ``` 202 | 203 | Take a look at the [contrib tasks](https://github.com/gruntjs/) for more examples. 204 | 205 | ## CLI options / environment 206 | 207 | Use `process.env` to access the [environment variables](https://en.wikipedia.org/wiki/Environment_variable). 208 | 209 | Read more about the available command-line options on the [Using the CLI](https://gruntjs.com/using-the-cli) page. 210 | 211 | ## Why doesn't my asynchronous task complete? 212 | Chances are this is happening because you have forgotten to call the [this.async](https://gruntjs.com/api/inside-tasks#this.async) method to tell Grunt that your task is asynchronous. For simplicity's sake, Grunt uses a synchronous coding style, which can be switched to asynchronous by calling `this.async()` within the task body. 213 | 214 | Note that passing `false` to the `done()` function tells Grunt that the task has failed. 215 | 216 | For example: 217 | 218 | ```js 219 | grunt.registerTask('asyncme', 'My asynchronous task.', function() { 220 | var done = this.async(); 221 | doSomethingAsync(done); 222 | }); 223 | ``` 224 | 225 | ## Extra Reference 226 | 227 | Checkout the [API](https://gruntjs.com/api) documentation if you need extra reference to create your tasks. 228 | -------------------------------------------------------------------------------- /Development-Team.md: -------------------------------------------------------------------------------- 1 | | | | | 2 | | ------------- | ----------- | 3 | | ![](https://avatars0.githubusercontent.com/u/54051?s=100) | **Ben Alman** | [GitHub](https://github.com/cowboy), [Twitter](https://twitter.com/cowboy), [Website](http://benalman.com/) | 4 | | ![](https://avatars3.githubusercontent.com/u/1004324?s=100) | **Tyler Kellen** | [GitHub](https://github.com/tkellen), [Twitter](https://twitter.com/tkellen), [Website](http://goingslowly.com/) | 5 | | ![](https://avatars2.githubusercontent.com/u/99604?s=100) | **Kyle Robinson Young** | [GitHub](https://github.com/shama), [Twitter](https://twitter.com/shamakry), [Website](http://dontkry.com/) | 6 | | ![](https://avatars3.githubusercontent.com/u/128755?s=100) | **Vlad Filippov** | [GitHub](https://github.com/vladikoff), [Twitter](https://twitter.com/vladikoff), [Website](http://vf.io/) | 7 | | ![](https://avatars0.githubusercontent.com/u/170270?s=100) | **Sindre Sorhus** | [GitHub](https://github.com/sindresorhus), [Twitter](https://twitter.com/sindresorhus), [Website](http://sindresorhus.com/hi/) | 8 | | ![](https://avatars0.githubusercontent.com/u/1379244?s=100) | **Isaac Durazo** | [GitHub](https://github.com/isaacdurazo), [Twitter](https://twitter.com/isaacdurazo), [Website](http://www.isaacdurazo.com/) | 9 | | ![](https://avatars3.githubusercontent.com/u/842798?s=100) | **Jarrod Overson** | [GitHub](https://github.com/tkellen), [Twitter](https://twitter.com/jsoverson), [Website](http://jarrodoverson.com/) | 10 | | ![](https://avatars1.githubusercontent.com/u/181635?s=100) | **Tim Branyen** | [GitHub](https://github.com/tbranyen), [Twitter](https://twitter.com/tbranyen), [Website](http://tbranyen.com/) | 11 | | ![](https://avatars2.githubusercontent.com/u/52585?s=100) | **Jörn Zaefferer** | [GitHub](https://github.com/jzaefferer), [Twitter](https://twitter.com/bassistance), [Website](http://bassistance.de/) | 12 | | ![](https://avatars2.githubusercontent.com/u/2322305?s=100) | **James Smith** | [GitHub](https://github.com/jmeas), [Twitter](https://twitter.com/jmeaspls), [Website](http://www.jmeas.com/) | 13 | | ![](https://avatars2.githubusercontent.com/u/515722?s=100) | **Dave Geddes** | [GitHub](https://github.com/geddski) | 14 | -------------------------------------------------------------------------------- /Development-helpers.md: -------------------------------------------------------------------------------- 1 | Good to do when publishing everything all-at-once. 2 | 3 | ```shell 4 | eachdir grunt grunt-{contrib,lib}-* -- 'git pull' 5 | eachdir grunt grunt-{contrib,lib}-* -- 'rm -rf node_modules; linken . --src ..; npm install' 6 | 7 | # Make sure symlinks were created, if not there's a version mismatch 8 | eachdir grunt grunt-{contrib,lib}-* -- 'll node_modules | grep grunt' 9 | 10 | # Make sure everything passes 11 | eachdir grunt grunt-{contrib,lib}-* -- grunt 12 | 13 | # Make sure all versions are final 14 | eachdir grunt grunt-{contrib,lib}-* -- 'git branch; node -pe "require(\"./package.json\").version"' 15 | ``` 16 | -------------------------------------------------------------------------------- /Documentation.md: -------------------------------------------------------------------------------- 1 | Welcome to the Grunt documentation page. Here you can find helpful resources, links, and information to start using Grunt. The first step to perform to use the tool is [to install it](https://gruntjs.com/installing-grunt) on your machine. 2 | 3 | ## Getting started 4 | 5 | If you're new to Grunt's world, we suggest to learn more about our CLI and what actions you need to complete to use Grunt in your project. The best resource for that is our [Getting started guide](https://gruntjs.com/getting-started). If you already know what Grunt is and how it works, the next step is to familiarize yourself with [the creation of a `Gruntfile`](https://gruntjs.com/configuring-tasks). A `Gruntfile` contains the configuration of the tasks you wish to employ. If you are curious to know how it looks like, you can check out [our sample](https://gruntjs.com/sample-gruntfile). 6 | 7 | ## Advanced 8 | 9 | Once mastered all the basic concepts you might want to create your own Grunt tasks. Our [step-by-step guide](https://gruntjs.com/creating-plugins) and [the API documentation page](https://gruntjs.com/api/grunt) will help you in achieving this goal. 10 | 11 | Grunt helps you ship better projects by automating many tasks. If you feel grateful and want to give something back, the project is always on the outlook for new contributors. To see how you can help, take a look at the [Contributing page](https://gruntjs.com/contributing). 12 | 13 | ## Help and support 14 | 15 | Do you feel lost? We got you covered. Our dedicated [F.A.Q. page](https://gruntjs.com/frequently-asked-questions) should give the answers you need. If you can't find what you're looking for, you can search for more support in our [Help Resources page](https://gruntjs.com/help-resources). In addition, our community will try to assist you in our [#grunt channel on irc.freenode.net](http://webchat.freenode.net/?channels=grunt). 16 | 17 | ## Where to go next? 18 | 19 | Here's a summary of the documentation pages you can find on this website: 20 | 21 |
22 |
23 |

Documentation

24 | 25 | 33 |
34 |
35 |

Advanced

36 | 37 | 43 |
44 |
45 | -------------------------------------------------------------------------------- /Exit-Codes.md: -------------------------------------------------------------------------------- 1 | * `0` - No errors! 2 | * `1` - Fatal error 3 | * `2` - Missing gruntfile error 4 | * `3` - Task error 5 | * `4` - Template processing error 6 | * `5` - Invalid shell auto-completion rules error 7 | * `6` - Warning 8 | -------------------------------------------------------------------------------- /Frequently-Asked-Questions.md: -------------------------------------------------------------------------------- 1 | ## How do I install grunt? 2 | For general installation instructions, please read the [[Getting Started]] guide. If you need more specific information after having read that, read the comprehensive [[Installing grunt]] guide. 3 | 4 | ## When will I be able to use in-development feature 'X'? 5 | Installing both published and unpublished development versions of Grunt is covered in the [[Installing grunt]] guide. 6 | 7 | ## Does Grunt work on Windows? 8 | Grunt works fine on Windows, because [Node.js](https://nodejs.org/) and [npm](https://www.npmjs.com/) both work fine on Windows. Usually the problematic part is [Cygwin](http://www.cygwin.com/), because it bundles an outdated version of Node.js. 9 | 10 | The best way to avoid this issue is to use the [msysGit installer](http://msysgit.github.com/) to install the `git` binary and the [Node.js installer](https://nodejs.org/#download) to install the `node` and `npm` binaries, and to use the built-in [Windows command prompt](http://www.cs.princeton.edu/courses/archive/spr05/cos126/cmd-prompt.html) or [PowerShell](http://support.microsoft.com/kb/968929) instead of Cygwin. 11 | 12 | ## Why doesn't my asynchronous task complete? 13 | Chances are this is happening because you have forgotten to call the [this.async](grunt.task#wiki-this-async) method to tell Grunt that your task is asynchronous. For simplicity's sake, Grunt uses a synchronous coding style, which can be switched to asynchronous by calling `this.async()` within the task body. 14 | 15 | Note that passing `false` to the `done()` function tells Grunt that the task has failed. 16 | 17 | For example: 18 | 19 | ```js 20 | grunt.registerTask('asyncme', 'My asynchronous task.', function() { 21 | var done = this.async(); 22 | doSomethingAsync(done); 23 | }); 24 | ``` 25 | 26 | ## How do I enable shell tab auto-completion? 27 | To enable bash tab auto-completion for grunt, add the following line to your `~/.bashrc` file: 28 | 29 | ```shell 30 | eval "$(grunt --completion=bash)" 31 | ``` 32 | 33 | This assumes that Grunt has been installed globally with `npm install -g grunt`. Currently, the only supported shell is bash. 34 | 35 | ## How can I share parameters across multiple tasks? 36 | While each task can accept its own parameters, there are a few options available for sharing parameters across multiple tasks. 37 | 38 | ### "Dynamic" alias tasks 39 | **This is the preferred method for sharing parameters across multiple tasks.** 40 | 41 | Whereas [alias tasks](grunt#wiki-grunt-registerTask) are necessarily simple, a regular task can use [grunt.task.run](grunt.task#wiki-grunt-task-run) to make it effectively function as a "dynamic" alias task. In this example, running `grunt build:001` on the command line would result in the `foo:001`, `bar:001` and `baz:001` tasks being run. 42 | 43 | ```js 44 | grunt.registerTask('build', 'Run all my build tasks.', function(n) { 45 | if (n == null) { 46 | grunt.warn('Build num must be specified, like build:001.'); 47 | } 48 | grunt.task.run('foo:' + n, 'bar:' + n, 'baz:' + n); 49 | }); 50 | ``` 51 | 52 | ### -- options 53 | 54 | Another way to share a parameter across multiple tasks would be to use [grunt.option](grunt#wiki-grunt-option). In this example, running `grunt deploy --target=staging` on the command line would cause `grunt.option('target')` to return `"staging"`. 55 | 56 | ```js 57 | grunt.registerTask('upload', 'Upload code to specified target.', function() { 58 | var target = grunt.option('target'); 59 | // do something useful with target here 60 | }); 61 | grunt.registerTask('deploy', ['validate', 'upload']); 62 | ``` 63 | 64 | _Note that boolean options can be specified using just a key without a value. For example, running `grunt deploy --staging` on the command line would cause `grunt.option('staging')` to return `true`._ 65 | 66 | ### Globals and configs 67 | 68 | In other cases, you may want to expose a way to set configuration or global values. In those cases, register a task that sets its arguments as a global or config value. 69 | 70 | In this example, running `grunt set_global:name:peter set_config:target:staging deploy` on the command line would cause `global.name` to be `"peter"` and `grunt.config('target')` to return `"staging"`. Presumably, the `deploy` task would use those values. 71 | 72 | ```js 73 | grunt.registerTask('set_global', 'Set a global variable.', function(name, val) { 74 | global[name] = val; 75 | }); 76 | 77 | grunt.registerTask('set_config', 'Set a config property.', function(name, val) { 78 | grunt.config.set(name, val); 79 | }); 80 | ``` 81 | 82 | ## How I get a stack trace when an error occurs? 83 | 84 | Use the `--stack` option to see stack traces. Such as `grunt task --stack` 85 | 86 | ## Why am I getting a "Maximum call stack size exceeded" error? 87 | 88 | You probably created an alias task with the same name as one of your regular tasks. 89 | Example: `grunt.registerTask('uglify', ['uglify:my_target']);` should be `grunt.registerTask('myUglify', ['uglify:my_target']);`. 90 | 91 | ## How do I uninstall or remove unwanted plugins? 92 | 93 | At least two ways. One way is to use `npm uninstall [GRUNT_PLUGIN] --save-dev`, this will remove the plugin from your `package.json` and from `node_modules`. You may also delete the dependencies you don't want from your `package.json` manually and then run `npm prune`. 94 | 95 | ## Error "Fail to install with npm error: No compatible version found" 96 | 97 | Make sure you have the latest stable version of [NPM and Node.JS](https://nodejs.org/) 98 | 99 | 100 | *** 101 | 102 | 103 | ## grunt 0.3 Questions 104 | 105 | ## On Windows with Grunt 0.3, why does my JS editor open when I try to run grunt? 106 | If you're in the same directory as the [Gruntfile](Getting-started), Windows tries to execute _that file_ when you type grunt. So you need to type `grunt.cmd` instead. 107 | 108 | An alternative would be to use the `DOSKEY` command to create a Grunt macro, following [these directions](https://gist.github.com/vladikoff/38307908088d58af206b). That would allow you to use `grunt` instead of `grunt.cmd`. 109 | 110 | This is the `DOSKEY` command you'd use: 111 | 112 | ``` 113 | DOSKEY grunt=grunt.cmd $* 114 | ``` 115 | -------------------------------------------------------------------------------- /Getting-started.md: -------------------------------------------------------------------------------- 1 | Grunt and Grunt plugins are installed and managed via [npm](https://www.npmjs.org/), the [Node.js](https://nodejs.org/) package manager. 2 | Grunt 0.4.x requires stable Node.js versions `>= 0.8.0`. 3 | 4 | Before setting up Grunt ensure that your [npm](https://www.npmjs.org/) is up-to-date by running `npm update -g npm` (this might require `sudo` on certain systems). 5 | 6 | If you already have installed Grunt and are now searching for some quick reference, please checkout our [`Gruntfile` example](https://gruntjs.com/sample-gruntfile) and how to [configure a task](https://gruntjs.com/configuring-tasks). 7 | 8 | ## Installing the CLI 9 | **Using Grunt 0.3? Please see [Grunt 0.3 Notes](upgrading-from-0.3-to-0.4#grunt-0.3-notes)** 10 | 11 | In order to get started, you'll want to install Grunt's command line interface (CLI) globally. You may need to use sudo (for OSX, *nix, BSD etc) or run your command shell as Administrator (for Windows) to do this. 12 | 13 | ```shell 14 | npm install -g grunt-cli 15 | ``` 16 | 17 | This will put the `grunt` command in your system path, allowing it to be run from any directory. 18 | 19 | Note that installing `grunt-cli` does not install the Grunt task runner! The job of the Grunt CLI is simple: run the version of Grunt which has been installed next to a `Gruntfile`. 20 | This allows multiple versions of Grunt to be installed on the same machine simultaneously. 21 | 22 | ## How the CLI works 23 | 24 | Each time `grunt` is run, it looks for a locally installed Grunt using node's `require()` system. Because of this, you can run `grunt` from any subfolder in your project. 25 | 26 | If a locally installed Grunt is found, the CLI loads the local installation of the Grunt library, applies the configuration from your `Gruntfile`, and executes any tasks you've requested for it to run. To really understand what is happening, [read the code](https://github.com/gruntjs/grunt-cli/blob/master/bin/grunt). 27 | 28 | ## Working with an existing Grunt project 29 | Assuming that the Grunt CLI has been installed and that the project has already been configured with a `package.json` and a `Gruntfile`, it's very easy to start working with Grunt: 30 | 31 | 1. Change to the project's root directory. 32 | 2. Install project dependencies with `npm install`. 33 | 3. Run Grunt with `grunt`. 34 | 35 | That's really all there is to it. Installed Grunt tasks can be listed by running `grunt --help` but it's usually a good idea to start with the project's documentation. 36 | 37 | ## Preparing a new Grunt project 38 | A typical setup will involve adding two files to your project: `package.json` and the `Gruntfile`. 39 | 40 | **package.json**: This file is used by [npm] to store metadata for projects published as npm modules. You will list grunt and the Grunt plugins your project needs as [devDependencies] in this file. 41 | 42 | **Gruntfile**: This file is named `Gruntfile.js` or `Gruntfile.coffee` and is used to configure or define tasks and load Grunt plugins. 43 | **When this documentation mentions a `Gruntfile` it is talking about a file, which is either a `Gruntfile.js` or a `Gruntfile.coffee`**. 44 | 45 | ## package.json 46 | 47 | The `package.json` file belongs in the root directory of your project, next to the `Gruntfile`, and should be committed with your project source. Running `npm install` in the same folder as a `package.json` file will install the correct version of each dependency listed therein. 48 | 49 | There are a few ways to create a `package.json` file for your project: 50 | 51 | * Most [grunt-init] templates will automatically create a project-specific `package.json` file. 52 | * The [npm init] command will create a basic `package.json` file. 53 | * Start with the example below, and expand as needed, following this [specification][json]. 54 | 55 | ```js 56 | { 57 | "name": "my-project-name", 58 | "version": "0.1.0", 59 | "devDependencies": { 60 | "grunt": "~0.4.5", 61 | "grunt-contrib-jshint": "~0.10.0", 62 | "grunt-contrib-nodeunit": "~0.4.1", 63 | "grunt-contrib-uglify": "~0.5.0" 64 | } 65 | } 66 | ``` 67 | 68 | ### Installing Grunt and gruntplugins 69 | The easiest way to add Grunt and gruntplugins to an existing `package.json` is with the command `npm install --save-dev`. Not only will this install `` locally, but it will automatically be added to the [devDependencies] section, using a [tilde version range]. 70 | 71 | For example, this will install the latest version of Grunt in your project folder, adding it to your devDependencies: 72 | 73 | ```shell 74 | npm install grunt --save-dev 75 | ``` 76 | 77 | The same can be done for gruntplugins and other node modules. As seen in the following example installing the JSHint task module: 78 | 79 | ```shell 80 | npm install grunt-contrib-jshint --save-dev 81 | ``` 82 | 83 | Checkout the current available gruntplugins to be installed and used on your project at the [plugins](https://gruntjs.com/plugins) page. 84 | 85 | Be sure to commit the updated `package.json` file with your project when you're done! 86 | 87 | ## The Gruntfile 88 | The `Gruntfile.js` or `Gruntfile.coffee` file is a valid JavaScript or CoffeeScript file that belongs in the root directory of your project, next to the `package.json` file, and should be committed with your project source. 89 | 90 | A `Gruntfile` is comprised of the following parts: 91 | 92 | * The "wrapper" function 93 | * Project and task configuration 94 | * Loading Grunt plugins and tasks 95 | * Custom tasks 96 | 97 | ### An example Gruntfile 98 | In the following `Gruntfile`, project metadata is imported into the Grunt config from the project's `package.json` file and the [grunt-contrib-uglify] plugin's `uglify` task is configured to minify a source file and generate a banner comment dynamically using that metadata. When `grunt` is run on the command line, the `uglify` task will be run by default. 99 | 100 | ```js 101 | module.exports = function(grunt) { 102 | 103 | // Project configuration. 104 | grunt.initConfig({ 105 | pkg: grunt.file.readJSON('package.json'), 106 | uglify: { 107 | options: { 108 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' 109 | }, 110 | build: { 111 | src: 'src/<%= pkg.name %>.js', 112 | dest: 'build/<%= pkg.name %>.min.js' 113 | } 114 | } 115 | }); 116 | 117 | // Load the plugin that provides the "uglify" task. 118 | grunt.loadNpmTasks('grunt-contrib-uglify'); 119 | 120 | // Default task(s). 121 | grunt.registerTask('default', ['uglify']); 122 | 123 | }; 124 | ``` 125 | 126 | Now that you've seen the whole `Gruntfile`, let's look at its component parts. 127 | 128 | ### The "wrapper" function 129 | Every `Gruntfile` (and gruntplugin) uses this basic format, and all of your Grunt code must be specified inside this function: 130 | 131 | ```js 132 | module.exports = function(grunt) { 133 | // Do grunt-related things in here 134 | }; 135 | ``` 136 | 137 | ### Project and task configuration 138 | Most Grunt tasks rely on configuration data defined in an object passed to the [[grunt.initConfig|grunt#grunt.initconfig]] method. 139 | 140 | In this example, `grunt.file.readJSON('package.json')` imports the JSON metadata stored in `package.json` into the grunt config. Because `<% %>` template strings may reference any config properties, configuration data like filepaths and file lists may be specified this way to reduce repetition. 141 | 142 | You may store any arbitrary data inside of the configuration object, and as long as it doesn't conflict with properties your tasks require, it will be otherwise ignored. Also, because this is JavaScript, you're not limited to JSON; you may use any valid JS here. You can even programmatically generate the configuration if necessary. 143 | 144 | Like most tasks, the [grunt-contrib-uglify] plugin's `uglify` task expects its configuration to be specified in a property of the same name. Here, the `banner` option is specified, along with a single uglify target named `build` that minifies a single source file to a single destination file. 145 | 146 | ```js 147 | // Project configuration. 148 | grunt.initConfig({ 149 | pkg: grunt.file.readJSON('package.json'), 150 | uglify: { 151 | options: { 152 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' 153 | }, 154 | build: { 155 | src: 'src/<%= pkg.name %>.js', 156 | dest: 'build/<%= pkg.name %>.min.js' 157 | } 158 | } 159 | }); 160 | ``` 161 | 162 | ### Loading Grunt plugins and tasks 163 | Many commonly used tasks like [concatenation], [minification][grunt-contrib-uglify] and [linting] are available as [grunt plugins](https://github.com/gruntjs). As long as a plugin is specified in `package.json` as a dependency, and has been installed via `npm install`, it may be enabled inside your `Gruntfile` with a simple command: 164 | 165 | ```js 166 | // Load the plugin that provides the "uglify" task. 167 | grunt.loadNpmTasks('grunt-contrib-uglify'); 168 | ``` 169 | 170 | **Note:** the `grunt --help` command will list all available tasks. 171 | 172 | ### Custom tasks 173 | You can configure Grunt to run one or more tasks by default by defining a `default` task. In the following example, running `grunt` at the command line without specifying a task will run the `uglify` task. This is functionally the same as explicitly running `grunt uglify` or even `grunt default`. Any number of tasks (with or without arguments) may be specified in the array. 174 | 175 | ```js 176 | // Default task(s). 177 | grunt.registerTask('default', ['uglify']); 178 | ``` 179 | 180 | If your project requires tasks not provided by a Grunt plugin, you may define custom tasks right inside the `Gruntfile`. For example, this `Gruntfile` defines a completely custom `default` task that doesn't even utilize task configuration: 181 | 182 | ```js 183 | module.exports = function(grunt) { 184 | 185 | // A very basic default task. 186 | grunt.registerTask('default', 'Log some stuff.', function() { 187 | grunt.log.write('Logging some stuff...').ok(); 188 | }); 189 | 190 | }; 191 | ``` 192 | 193 | Custom project-specific tasks don't need to be defined in the `Gruntfile`; they may be defined in external `.js` files and loaded via the [[grunt.loadTasks|grunt#grunt.loadtasks]] method. 194 | 195 | ## Further Reading 196 | 197 | * The [[Installing grunt]] guide has detailed information about installing specific, production or in-development, versions of Grunt and grunt-cli. 198 | * The [[Configuring Tasks]] guide has an in-depth explanation on how to configure tasks, targets, options and files inside the `Gruntfile`, along with an explanation of templates, globbing patterns and importing external data. 199 | * The [[Creating Tasks]] guide lists the differences between the types of Grunt tasks and shows a number of sample tasks and configurations. 200 | * For more information about writing custom tasks or Grunt plugins, check out the [[developer documentation|grunt]]. 201 | 202 | [npm]: https://www.npmjs.org/ 203 | [devDependencies]: https://docs.npmjs.com/files/package.json#devdependencies 204 | [json]: https://docs.npmjs.com/files/package.json 205 | [npm init]: https://docs.npmjs.com/cli/init 206 | [grunt-init]: Project-Scaffolding 207 | [tilde version range]: https://docs.npmjs.com/cli/v6/using-npm/semver#ranges 208 | [grunt-contrib-uglify]: https://github.com/gruntjs/grunt-contrib-uglify 209 | [concatenation]: https://github.com/gruntjs/grunt-contrib-concat 210 | [linting]: https://github.com/gruntjs/grunt-contrib-jshint 211 | [grunt.loadTasks]: https://github.com/gruntjs/grunt/wiki/grunt.task 212 | -------------------------------------------------------------------------------- /Grunt-Brand-Guide.md: -------------------------------------------------------------------------------- 1 | We have a few guidelines for using Grunt’s brand resources—please take a moment to familiarize yourself with them. 2 | 3 | ## Logomark 4 | 5 | The Grunt Logomark is a badass warthog. We use it as a standalone graphic and in combination with the Wordmark Grunt. 6 | 7 |
8 | Grunt warthog logo 9 | Wordmark Grunt warthog logo with "GRUNT" caption 10 |
11 | 12 | ## Wordmark 13 | 14 | When the name "Grunt" is written stand-alone, or being treated graphically, the Grunt wordmark should be written in uppercase (i.e. GRUNT). 15 | 16 | However, when referring to Grunt in a sentence, the Grunt wordmark should be written as a proper-noun, capitalizing only the first letter (e.g. "We use Grunt to assemble our project!"). 17 | 18 | ## Safety space 19 | 20 | When using the Grunt Logo with other logos or graphic elements, ensure a 'safety space' is surrounding the Grunt logo: 21 | * 25% of the logo's width should be padded to the left and right 22 | * 25% of the logo's height should be padded above and below 23 | 24 | In other words, the Grunt logo and its safety space should have a size that's 150% of the the logo itself. 25 | 26 |
27 | From the logo's dimensions, there should be 25% padding surrounding the Grunt logo 28 |
29 | 30 | ## Typography 31 | 32 | When using the Grunt wordmark graphically (and in all-caps), please use the open source font "Lato". 33 | 34 | Lato was created by [Łukasz Dziedzic](https://plus.google.com/106163021290874968147/about), and Google hosts a copy of this font. You can download here: 35 | 36 | Lato Font 37 | 38 | Whilst we use the original Lato font on the Grunt website, we've slightly modified the font in the wordmarked logo. 39 | 40 | ## Usage 41 | 42 | Grunt is an Open Source Project, and whilst you're free to use our logo, we ask that you respect our guidelines. Although you might have the best intentions, we don't want you to alter the official Grunt logo. Here are some examples of logo usage that we do NOT support: 43 | 44 |
45 | Don't add embellishments to the Grunt logo 46 | Don't stretch the logo, or change the x:y ratio of its dimensions 47 | Don't alter the "GRUNT" caption, or embed a customised caption 48 | Don't alter the colors of the logo, using filters or otherwise 49 |
50 | 51 | ## Brand Colors 52 | 53 | These are Grunt's brand colors. You can copy the HEX codes below or the Pantone 54 | 55 |
56 |
57 |
58 |
#452F13
59 |
Pantone 476 C
60 |
61 |
62 |
63 |
#E68724
64 |
Pantone 7569 C
65 |
66 |
67 |
68 |
#FAA918
69 |
Pantone 7409 C
70 |
71 |
72 |
73 |
#C9C8C8
74 |
Pantone 420 C
75 |
76 |
77 | 78 | ## Promotion 79 | 80 | Every Open Source Project benefits from the promotion of its users, and Grunt is no exception. Are you using Grunt in your project and want to brag about it? Want to share the Grunt project with the world? Here are a few suggestions for you: 81 | 82 | ## Twitter 83 | 84 | The word “Grunt” might be too generic for Twitter, so use the hashtag #GruntJS instead to share your love 85 | 86 | ## [Badges](/built-with-grunt-badge) 87 | 88 | Do you use Grunt in a project and want to proudly display that in your project's README, or on your project's website? Now you can with the official "Built with Grunt" badge! 89 | 90 | [![Built with Grunt](https://cdn.gruntjs.com/builtwith.svg)](https://gruntjs.com/) 91 | 92 | ### Using the Badge 93 | 94 | Just copy the following Markdown code snippet and paste it right underneath the headline in your project README. You can also put it on your project website homepage or footer. 95 | 96 | ```markdown 97 | [![Built with Grunt](https://cdn.gruntjs.com/builtwith.svg)](https://gruntjs.com/) 98 | ``` 99 | 100 | If you need an HTML version, we've got you covered. 101 | 102 | ```html 103 | 104 | Built with Grunt 105 | 106 | ``` 107 | 108 | ### For example... 109 | 110 | As you can see, the "Built with Grunt" badge is modern, stylish, and has been designed to fit nicely next to all your project's other mini-badges. You can put it first, last, or anywhere in the middle. Have fun! 111 | 112 | [![NPM version](https://badge.fury.io/js/grunt.svg)](http://badge.fury.io/) 113 | [![Coverage Status](https://s3.amazonaws.com/assets.coveralls.io/badges/coveralls_100.svg)](https://coveralls.io/) 114 | [![Build Status](https://secure.travis-ci.org/gruntjs/grunt.svg?branch=master)](https://travis-ci.org/) 115 | [![Built with Grunt](https://cdn.gruntjs.com/builtwith.svg)](https://gruntjs.com/) 116 | 117 | ## Legal 118 | 119 | All the Grunt graphics are proprietary and protected under intellectual property laws, so please use them correctly. 120 | 121 | Don’t display these graphics in a way that implies a relationship, affiliation, or endorsment by Grunt of your product, service, or business. 122 | 123 | Don’t use these graphics as part of your own product, business, or service’s name. 124 | 125 | Don’t alter these graphics in any way, or combine them with any other graphics, without written consent from the Grunt team. 126 | 127 | If you wish to use any Grunt graphics beyond the scope of this document, apply by [creating an issue ticket](https://github.com/gruntjs/gruntjs.com/issues) or sending us an email ([info@gruntjs.com](info@gruntjs.com)). 128 | 129 | ## Assets 130 | 131 | Download the assets 132 | 133 |

Logomark

134 | 135 | EPS 136 | JPG (300dpi) 137 | PNG 138 | 139 | ## Logomark + Wordmark 140 | 141 | EPS 142 | JPG (300dpi) 143 | PNG 144 | 145 | ## Contact Us 146 | 147 | If something is not covered here, or you have any questions, please let us know, as it will help us to improve this brand guide. You can reach us in the following ways: 148 | * Create an [issue ticket](https://github.com/gruntjs/gruntjs.com/issues) 149 | * Send us an email ([info@gruntjs.com](info@gruntjs.com)) 150 | -------------------------------------------------------------------------------- /Grunt-Plugins.md: -------------------------------------------------------------------------------- 1 | This plugin listing is automatically generated from the npm module database. 2 | Officially maintained "contrib" plugins are marked with a star 3 | icon. 4 | 5 | To install and use any plugin listed here, checkout [how to install and use the Grunt plugins section](https://gruntjs.com/getting-started#installing-grunt-and-gruntplugins). 6 | 7 | You may also be interested on how to [create your own Grunt plugin](https://gruntjs.com/creating-plugins). 8 | 9 |
10 | In order for a Grunt plugin to be listed here, it must be published on 11 | npm with the 12 | gruntplugin keyword. 13 | Additionally, we recommend that you use the 14 | gruntplugin grunt-init template 15 | when creating a Grunt plugin. 16 |
17 | -------------------------------------------------------------------------------- /Help-Resources.md: -------------------------------------------------------------------------------- 1 | ## Forums 2 | 3 | You can post a question at [StackOverflow and tag it with "gruntjs"](http://stackoverflow.com/questions/tagged/gruntjs). 4 | -------------------------------------------------------------------------------- /Home.md: -------------------------------------------------------------------------------- 1 | > Welcome to the home of **Grunt**, a JavaScript automation tool. 2 | 3 | Stable Version: **1.6.x** 4 | 5 | Development Version: **main** 6 | 7 | ## Documentation 8 | 9 | - [[Getting Started]] 10 | - [[Configuring Tasks]] 11 | - [[Sample Gruntfile]] 12 | - [[Creating Tasks]] 13 | - [[Creating Plugins]] 14 | - [[Using the CLI]] 15 | 16 | ### Advanced 17 | 18 | - [[API]] 19 | - [[Installing Grunt]] 20 | - [[Frequently Asked Questions]] 21 | - [[Project Scaffolding]] 22 | 23 | ### Community 24 | 25 | - [[Support]] 26 | - [[Help Resources]] 27 | - [[Who uses Grunt]] 28 | - [[Built with Grunt Badge]] 29 | - [[Contributing]] 30 | - [[Development Team]] 31 | 32 | ### Migration guides 33 | 34 | - [[Upgrading from 0.3 to 0.4]] 35 | - [[Upgrading from 0.4 to 1.0]] 36 | 37 | ## API 38 | 39 | - [[grunt]] 40 | - [[grunt.config]] 41 | - [[grunt.event]] 42 | - [[grunt.fail]] 43 | - [[grunt.file]] 44 | - [[grunt.log]] 45 | - [[grunt.option]] 46 | - [[grunt.task]] 47 | - [[grunt.template]] 48 | - [[grunt.util]] 49 | 50 | ### Other 51 | 52 | - [[Inside Tasks]] 53 | - [[Exit Codes]] 54 | -------------------------------------------------------------------------------- /Inside-Tasks.md: -------------------------------------------------------------------------------- 1 | While a task is running, Grunt exposes many task-specific utility properties and methods inside the task function via the `this` object. This same object is also exposed as `grunt.task.current` for use in [templates](grunt.template), eg. the property `this.name` is also available as `grunt.task.current.name`. 2 | 3 | ## Inside All Tasks 4 | 5 | ### this.async 6 | If a task is asynchronous, this method must be invoked to instruct Grunt to wait. It returns a handle to a "done" function that should be called when the task has completed. Either `false` or an `Error` object may be passed to the done function to instruct Grunt that the task has failed. 7 | 8 | If the `this.async` method isn't invoked, the task will execute synchronously. 9 | 10 | ```js 11 | // Tell Grunt this task is asynchronous. 12 | var done = this.async(); 13 | // Your async code. 14 | setTimeout(function() { 15 | // Let's simulate an error, sometimes. 16 | var success = Math.random() > 0.5; 17 | // All done! 18 | done(success); 19 | }, 1000); 20 | ``` 21 | 22 | ### this.requires 23 | If one task depends on the successful completion of another task (or tasks), this method can be used to force Grunt to abort if the other task didn't run, or if the other task failed. The tasks list can be an array of task names or individual task names, as arguments. 24 | 25 | Note that this won't actually run the specified task(s), it will just fail the current task if they haven't already run successfully. 26 | 27 | ```js 28 | this.requires(tasksList) 29 | ``` 30 | 31 | ### this.requiresConfig 32 | Fail the current task if one or more required [config](grunt.config) properties is missing. One or more string or array config properties may be specified. 33 | 34 | ```js 35 | this.requiresConfig(prop [, prop [, ...]]) 36 | ``` 37 | 38 | See the [grunt.config documentation](grunt.config) for more information about config properties. 39 | 40 | _This method is an alias for the [grunt.config.requires](grunt.config#grunt.config.requires) method._ 41 | 42 | ### this.name 43 | The name of the task, as defined in `grunt.registerTask`. For example, if a "sample" task was run as `grunt sample` or `grunt sample:foo`, inside the task function, `this.name` would be `"sample"`. 44 | 45 | _Note that if a task has been renamed with [grunt.task.renameTask](grunt.task#grunt.task.renameTask) this property will reflect the new name._ 46 | 47 | 48 | ### this.nameArgs 49 | The name of the task, including any colon-separated arguments or flags specified on the command-line. For example, if a "sample" task was run as `grunt sample:foo`, inside the task function, `this.nameArgs` would be `"sample:foo"`. 50 | 51 | _Note that if a task has been renamed with [grunt.task.renameTask](grunt.task#grunt.task.renameTask) this property will reflect the new name._ 52 | 53 | ### this.args 54 | An array of arguments passed to the task. For example, if a "sample" task was run as `grunt sample:foo:bar`, inside the task function, `this.args` would be `["foo", "bar"]`. 55 | 56 | _Note that in multi tasks, the current target is omitted from the `this.args` array._ 57 | 58 | ### this.flags 59 | An object generated from the arguments passed to the task. For example, if a "sample" task was run as `grunt sample:foo:bar`, inside the task function, `this.flags` would be `{foo: true, bar: true}`. 60 | 61 | _Note that inside multi tasks, the target name is **not** set as a flag._ 62 | 63 | ### this.errorCount 64 | The number of [grunt.log.error](grunt.log#grunt.log.error) calls that occurred during this task. This can be used to fail a task if errors were logged during the task. 65 | 66 | ### this.options 67 | Returns an options object. Properties of the optional `defaultsObj` argument will be overridden by any task-level `options` object properties, which will be further overridden in multi tasks by any target-level `options` object properties. 68 | 69 | ```js 70 | this.options([defaultsObj]) 71 | ``` 72 | 73 | This example shows how a task might use the `this.options` method: 74 | 75 | ```js 76 | var options = this.options({ 77 | enabled: false, 78 | }); 79 | 80 | doSomething(options.enabled); 81 | ``` 82 | 83 | The [Configuring tasks](configuring-tasks#options) guide shows an example of how options may be specified, from the task user's point of view. 84 | 85 | ## Inside Multi Tasks 86 | 87 | ### this.target 88 | In a multi task, this property contains the name of the target currently being iterated over. For example, if a "sample" multi task was run as `grunt sample:foo` with the config data `{sample: {foo: "bar"}}`, inside the task function, `this.target` would be `"foo"`. 89 | 90 | ### this.files 91 | In a multi task, all files specified using any Grunt-supported [file formats and options](configuring-tasks#files), [globbing patterns](configuring-tasks#globbing-patterns) or [dynamic mappings](configuring-tasks#building-the-files-object-dynamically) will automatically be normalized into a single format: the [Files Array file format](configuring-tasks#files-array-format). 92 | 93 | What this means is that tasks don't need to contain a ton of boilerplate for explicitly handling custom file formats, globbing patterns, mapping source files to destination files or filtering out files or directories. _A task user can just specify files per the [Configuring tasks](configuring-tasks#files) guide, and **Grunt will handle all the details.**_ 94 | 95 | Your task should iterate over the `this.files` array, utilizing the `src` and `dest` properties of each object in that array. The `this.files` property will always be an array. The `src` property will also always be an array, in case your task cares about multiple source files per destination file. 96 | 97 | _Note that it's possible that nonexistent files might be included in `src` values, so you may want to explicitly test that source files exist before using them._ 98 | 99 | This example shows how a simple "concat" task might use the `this.files` property: 100 | 101 | ```js 102 | this.files.forEach(function(file) { 103 | var contents = file.src.filter(function(filepath) { 104 | // Remove nonexistent files (it's up to you to filter or warn here). 105 | if (!grunt.file.exists(filepath)) { 106 | grunt.log.warn('Source file "' + filepath + '" not found.'); 107 | return false; 108 | } else { 109 | return true; 110 | } 111 | }).map(function(filepath) { 112 | // Read and return the file's source. 113 | return grunt.file.read(filepath); 114 | }).join('\n'); 115 | // Write joined contents to destination filepath. 116 | grunt.file.write(file.dest, contents); 117 | // Print a success message. 118 | grunt.log.writeln('File "' + file.dest + '" created.'); 119 | }); 120 | ``` 121 | 122 | _If you need the original file object properties, they are available on each individual file object under the `orig` property, but there is no known use-case for accessing the original properties._ 123 | 124 | ### this.filesSrc 125 | In a multi task, all `src` files specified via any [file format](configuring-tasks#files) are reduced to a single array. If your task is "read only" and doesn't care about destination filepaths, use this array instead of `this.files`. 126 | 127 | This example shows how a simple "lint" task might use the `this.filesSrc` property: 128 | 129 | ```js 130 | // Lint specified files. 131 | var files = this.filesSrc; 132 | var errorCount = 0; 133 | files.forEach(function(filepath) { 134 | if (!lint(grunt.file.read(filepath))) { 135 | errorCount++; 136 | } 137 | }); 138 | 139 | // Fail task if errors were logged. 140 | if (errorCount > 0) { return false; } 141 | 142 | // Otherwise, print a success message. 143 | grunt.log.ok('Files lint free: ' + files.length); 144 | ``` 145 | 146 | ### this.data 147 | In a multi task, this is the actual data stored in the Grunt config object for the given target. 148 | For example, if a "sample" multi task was run as `grunt sample:foo` with the config data `{sample: {foo: "bar"}}`, inside the task function, `this.data` would be `"bar"`. 149 | 150 | _It is recommended that `this.options` `this.files` and `this.filesSrc` are used instead of `this.data`, as their values are normalized._ 151 | -------------------------------------------------------------------------------- /Installing-grunt.md: -------------------------------------------------------------------------------- 1 | This document explains how to install specific versions of Grunt and Grunt plugins. If you haven't read the [[Getting Started]] guide, you should check that out first. 2 | 3 | ## Overview 4 | Grunt and Grunt plugins should be defined as [devDependencies](https://docs.npmjs.com/files/package.json#devdependencies) in your project's [package.json](https://docs.npmjs.com/files/package.json). This will allow you to install all of your project's dependencies with a single command: `npm install`. The current stable and development versions of Grunt are always listed on the wiki's [home page](https://github.com/gruntjs/grunt/wiki/). 5 | 6 | ## Installing a specific version 7 | If you need a specific version of Grunt or a Grunt plugin, run `npm install grunt@VERSION --save-dev` where `VERSION` is the version you need. This will install the specified version, adding it to your package.json devDependencies. 8 | 9 | Note that a [tilde version range] will be used in your `package.json` when you add the `--save-dev` flag to `npm install`. This is typically good, as new patch releases of the specified version will automatically be upgraded as development continues, per [semver]. 10 | 11 | [tilde version range]: https://docs.npmjs.com/cli/v6/using-npm/semver#ranges 12 | [semver]: http://semver.org 13 | 14 | ## Installing a published development version 15 | Periodically, as new functionality is being developed, Grunt builds may be published to npm. These builds will _never_ be installable without explicitly specifying a version number, and will typically have a build number or alpha/beta/release candidate designation. 16 | 17 | Like installing a specific version of grunt, run `npm install grunt@VERSION --save-dev` where `VERSION` is the version you need, and npm will install that version of Grunt in your project folder, adding it to your `package.json` devDependencies. 18 | 19 | Note that regardless of the version you specify, a [tilde version range][] will be specified in `package.json`. **This is very bad**, as new, possibly incompatible, patch releases of the specified development version may be installed by npm, breaking your build. 20 | 21 | _In this case it is **very important** that you manually edit your `package.json` and remove the ~ (tilde) from the version number. This will lock in the exact development version that you have specified._ 22 | 23 | The same process may be used to install a published development version of a Grunt plugin. 24 | 25 | ## Installing directly from GitHub 26 | If you want to install a bleeding-edge, unpublished version of Grunt or Grunt plugin, follow the instructions for specifying a [git URL as a dependency](https://docs.npmjs.com/files/package.json#git-urls-as-dependencies) and be sure to specify an actual commit SHA (not a branch name) as the `commit-ish`. This will guarantee that your project always uses that exact version of grunt. 27 | 28 | The specified git URL may be that of the official Grunt repo or a fork. 29 | -------------------------------------------------------------------------------- /Plugin-Release-Candidate-Versions.md: -------------------------------------------------------------------------------- 1 | Note: because these are pre-release versions, please follow the instructions in the "Installing a published development version of Grunt" section of the [Installing Grunt guide](https://github.com/gruntjs/grunt/wiki/Installing-grunt). And as a reminder, **do not** specify a version range (using ~ or <=) when including a pre-release version of Grunt or Grunt plugin in your project. 2 | 3 | Grunt contrib plugins published to npm that work with Grunt 0.4.0rc8: 4 | 5 | * grunt-contrib-clean@0.4.0rc6 6 | * grunt-contrib-coffee@0.4.0rc7 7 | * grunt-contrib-compass@0.1.1rc8 8 | * grunt-contrib-compress@0.4.0rc7 9 | * grunt-contrib-concat@0.1.2rc6 10 | * grunt-contrib-connect@0.1.1rc6 11 | * grunt-contrib-copy@0.4.0rc7 12 | * grunt-contrib-handlebars@0.5.4rc7 13 | * grunt-contrib-htmlmin@0.1.1rc7 14 | * grunt-contrib-imagemin@0.1.1rc8 15 | * grunt-contrib-jade@0.4.0.rc7 16 | * grunt-contrib-jasmine@0.3.0rc7 17 | * grunt-contrib-jshint@0.1.1rc6 18 | * grunt-contrib-jst@0.4.0rc7 19 | * grunt-contrib-less@0.5.0rc7 20 | * grunt-contrib-livereload@0.1.0rc8 21 | * grunt-contrib-mincss@0.4.0rc7 22 | * grunt-contrib-nodeunit@0.1.2rc6 23 | * grunt-contrib-qunit@0.1.1rc6 24 | * grunt-contrib-requirejs@0.4.0rc7 25 | * grunt-contrib-sass@0.2.2rc7 26 | * grunt-contrib-stylus@0.4.0rc7 27 | * grunt-contrib-uglify@0.1.1rc6 28 | * grunt-contrib-watch@0.2.0rc7 29 | * grunt-contrib-yuidoc@0.4.0rc7 30 | -------------------------------------------------------------------------------- /Project-Scaffolding.md: -------------------------------------------------------------------------------- 1 | ## grunt-init 2 | Grunt-init is a scaffolding tool used to automate project creation. It will build an entire directory structure based on current environment and answers to some questions. The exact files and contents created depend on the template chosen along with the answers to the questions asked. 3 | 4 | _Note: This standalone utility used to be built-in to Grunt as the "init" task. See the Grunt [Upgrading from 0.3 to 0.4](https://gruntjs.com/upgrading-from-0.3-to-0.4) guide for more information about this change._ 5 | 6 | ## Installation 7 | In order to use grunt-init, you'll want to install it globally. 8 | 9 | ```shell 10 | npm install -g grunt-init 11 | ``` 12 | 13 | This will put the `grunt-init` command in your system path, allowing it to be run from anywhere. 14 | 15 | _Notes: You may need to use sudo or run your command shell as Administrator to do this._ 16 | 17 | ## Usage 18 | * Get program help and a listing of available templates with `grunt-init --help` 19 | * Create a project based around an available template with `grunt-init TEMPLATE` 20 | * Create a project based around a arbitrarily-located template with `grunt-init /path/to/TEMPLATE` 21 | 22 | Note that most templates generate their files in the current directory, so be sure to change to a new directory first if you don't want to overwrite existing files. 23 | 24 | ## Installing templates 25 | Once templates are installed into your `~/.grunt-init/` directory (`%USERPROFILE%\.grunt-init\` on Windows) they will be available for use via grunt-init. It's recommended that you use git to clone a template into that directory. For example, the [grunt-init-jquery](https://github.com/gruntjs/grunt-init-jquery) template can be installed like so: 26 | 27 | ```shell 28 | git clone https://github.com/gruntjs/grunt-init-jquery.git ~/.grunt-init/jquery 29 | ``` 30 | 31 | _Note: if you want to make the template available locally as "foobarbaz" you could specify `~/.grunt-init/foobarbaz` while cloning. Grunt-init will use the actual template directory name as it exists inside of the `~/.grunt-init/` directory._ 32 | 33 | A few grunt-init templates are maintained officially: 34 | 35 | * [grunt-init-commonjs](https://github.com/gruntjs/grunt-init-commonjs) - Create a commonjs module, including Nodeunit unit tests. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-commonjs-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-commonjs-sample#project-creation-transcript)) 36 | * [grunt-init-gruntfile](https://github.com/gruntjs/grunt-init-gruntfile) - Create a basic Gruntfile. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-gruntfile-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-gruntfile-sample#project-creation-transcript)) 37 | * [grunt-init-gruntplugin](https://github.com/gruntjs/grunt-init-gruntplugin) - Create a Grunt plugin, including Nodeunit unit tests. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-gruntplugin-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-gruntplugin-sample#project-creation-transcript)) 38 | * [grunt-init-jquery](https://github.com/gruntjs/grunt-init-jquery) - Create a jQuery plugin, including QUnit unit tests. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-jquery-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-jquery-sample#project-creation-transcript)) 39 | * [grunt-init-node](https://github.com/gruntjs/grunt-init-node) - Create a Node.js module, including Nodeunit unit tests. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-node-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-node-sample#project-creation-transcript)) 40 | 41 | ## Custom templates 42 | You can create and use custom templates. Your template must follow the same structure as the aforementioned templates. 43 | 44 | A sample template named `my-template` would follow this general file structure: 45 | 46 | * `my-template/template.js` - the main template file. 47 | * `my-template/rename.json` - template-specific rename rules, processed as templates. 48 | * `my-template/root/` - files to be copied into the target location. 49 | 50 | Assuming these files exist at `/path/to/my-template`, the command `grunt-init /path/to/my-template` would be used to process the template. Multiple uniquely-named templates may exist in the same directory. 51 | 52 | Additionally, if you place this custom template in your `~/.grunt-init/` directory (`%USERPROFILE%\.grunt-init\` on Windows) it will be automatically available to be used with just `grunt-init my-template`. 53 | 54 | ### Copying files 55 | As long as a template uses the `init.filesToCopy` and `init.copyAndProcess` methods, any files in the `root/` subdirectory will be copied to the current directory when the init template is run. 56 | 57 | Note that all copied files will be processed as templates, with any `{% %}` template being processed against the collected `props` data object, unless the `noProcess` option is set. See the [jquery template](https://github.com/gruntjs/grunt-init-jquery) for an example. 58 | 59 | ### Renaming or excluding template files 60 | The `rename.json` describes `sourcepath` to `destpath` rename mappings. The `sourcepath` must be the path of the file-to-be-copied relative to the `root/` folder, but the `destpath` value can contain `{% %}` templates, describing what the destination path will be. 61 | 62 | If `false` is specified as a `destpath` the file will not be copied. Also, glob patterns are supported for `srcpath`. 63 | 64 | ## Specifying default prompt answers 65 | Each init prompt either has a default value hard-coded or it looks at the current environment to attempt to determine that default value. If you want to override a particular prompt's default value, you can do so in the optional OS X or Linux `~/.grunt-init/defaults.json` or Windows `%USERPROFILE%\.grunt-init\defaults.json` file. 66 | 67 | For example, my `defaults.json` file looks like this, because I want to use a slightly different name than the default name, I want to exclude my email address, and I want to specify an author URL automatically. 68 | 69 | ```json 70 | { 71 | "author_name": "\"Cowboy\" Ben Alman", 72 | "author_email": "none", 73 | "author_url": "http://benalman.com/" 74 | } 75 | ``` 76 | 77 | _Note: until all the built-in prompts have been documented, you can find their names and default values in the [source code](https://github.com/gruntjs/grunt-init/blob/master/tasks/init.js)._ 78 | 79 | ## Defining an init template 80 | 81 | ### exports.description 82 | This brief template description will be displayed along with the template name when the user runs `grunt init` or `grunt-init ` to display a list of all available init templates. 83 | 84 | ```js 85 | exports.description = descriptionString; 86 | ``` 87 | 88 | ### exports.notes 89 | If specified, this optional extended description will be displayed before any prompts are displayed. This is a good place to give the user a little help explaining naming conventions, which prompts may be required or optional, etc. 90 | 91 | ```js 92 | exports.notes = notesString; 93 | ``` 94 | 95 | ### exports.warnOn 96 | If this optional (but recommended) wildcard pattern or array of wildcard patterns is matched, Grunt will abort with a warning that the user can override with `--force`. This is very useful in cases where the init template could potentially override existing files. 97 | 98 | ```js 99 | exports.warnOn = wildcardPattern; 100 | ``` 101 | 102 | While the most common value will be `'*'`, matching any file or directory, the [minimatch](https://github.com/isaacs/minimatch) wildcard pattern syntax used allows for a lot of flexibility. For example: 103 | 104 | ```js 105 | exports.warnOn = 'Gruntfile.js'; // Warn on a Gruntfile.js file. 106 | exports.warnOn = '*.js'; // Warn on any .js file. 107 | exports.warnOn = '*'; // Warn on any non-dotfile or non-dotdir. 108 | exports.warnOn = '.*'; // Warn on any dotfile or dotdir. 109 | exports.warnOn = '{.*,*}'; // Warn on any file or dir (dot or non-dot). 110 | exports.warnOn = '!*/**'; // Warn on any file (ignoring dirs). 111 | exports.warnOn = '*.{png,gif,jpg}'; // Warn on any image file. 112 | 113 | // This is another way of writing the last example. 114 | exports.warnOn = ['*.png', '*.gif', '*.jpg']; 115 | ``` 116 | 117 | ### exports.template 118 | While the `exports` properties are defined outside this function, all the actual init code is specified inside. Three arguments are passed into this function. The `grunt` argument is a reference to grunt, containing all the [grunt methods and libs](api/grunt). The `init` argument is an object containing methods and properties specific to this init template. The `done` argument is a function that must be called when the init template is done executing. 119 | 120 | ```js 121 | exports.template = function(grunt, init, done) { 122 | // See the "Inside an init template" section. 123 | }; 124 | ``` 125 | 126 | ## Inside an init template 127 | 128 | ### init.addLicenseFiles 129 | Add properly-named license files to the files object. 130 | 131 | ```js 132 | var files = {}; 133 | var licenses = ['MIT']; 134 | init.addLicenseFiles(files, licenses); 135 | // files === {'LICENSE-MIT': 'licenses/LICENSE-MIT'} 136 | ``` 137 | 138 | ### init.availableLicenses 139 | Return an array of available licenses. 140 | 141 | ```js 142 | var licenses = init.availableLicenses(); 143 | // licenses === [ 'Apache-2.0', 'GPL-2.0', 'MIT', 'MPL-2.0' ] 144 | ``` 145 | 146 | ### init.copy 147 | Given an absolute or relative source path, and an optional relative 148 | destination path, copy a file, optionally processing it through the 149 | passed callback. 150 | 151 | ```js 152 | init.copy(srcpath[, destpath], options) 153 | ``` 154 | 155 | ### init.copyAndProcess 156 | Iterate over all files in the passed object, copying the source file to 157 | the destination, processing the contents. 158 | 159 | ```js 160 | init.copyAndProcess(files, props[, options]) 161 | ``` 162 | 163 | ### init.defaults 164 | User-specified default init values from `defaults.json`. 165 | 166 | ```js 167 | init.defaults 168 | ``` 169 | 170 | ### init.destpath 171 | Absolute destination file path. 172 | 173 | ```js 174 | init.destpath() 175 | ``` 176 | 177 | ### init.expand 178 | Same as [grunt.file.expand](https://github.com/gruntjs/grunt/wiki/grunt.file#wiki-grunt-file-expand). 179 | 180 | Return a unique array of all file or directory paths that match the given wildcard pattern(s). This method accepts either comma separated wildcard patterns or an array of wildcard patterns. Paths matching patterns that begin with ! will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant. 181 | 182 | ```js 183 | init.expand([options, ] patterns) 184 | ``` 185 | 186 | ### init.filesToCopy 187 | Return an object containing files to copy with their absolute source path and relative destination path, renamed (or omitted) according to rules in rename.json (if it exists). 188 | 189 | ```js 190 | var files = init.filesToCopy(props); 191 | /* files === { '.gitignore': 'template/root/.gitignore', 192 | '.jshintrc': 'template/root/.jshintrc', 193 | 'Gruntfile.js': 'template/root/Gruntfile.js', 194 | 'README.md': 'template/root/README.md', 195 | 'test/test_test.js': 'template/root/test/name_test.js' } */ 196 | ``` 197 | 198 | ### init.getFile 199 | Get a single task file path. 200 | 201 | ```js 202 | init.getFile(filepath[, ...]) 203 | ``` 204 | 205 | ### init.getTemplates 206 | Returns an object of all the available templates. 207 | 208 | ```js 209 | init.getTemplates() 210 | ``` 211 | 212 | ### init.initSearchDirs 213 | Initialize the directories to search for init templates. `template` is the 214 | location of a template. Will also include `~/.grunt-init/` and the core init 215 | tasks within grunt-init. 216 | 217 | ```js 218 | init.initSearchDirs([filename]) 219 | ``` 220 | 221 | ### init.process 222 | Start up the process to begin prompting for input. 223 | 224 | ```js 225 | init.process(options, prompts, done) 226 | ``` 227 | 228 | ```js 229 | init.process({}, [ 230 | // Prompt for these values 231 | init.prompt('name'), 232 | init.prompt('description'), 233 | init.prompt('version') 234 | ], function(err, props) { 235 | // All finished, do something with the properties 236 | }); 237 | ``` 238 | 239 | ### init.prompt 240 | Prompt a user for a value. 241 | 242 | ```js 243 | init.prompt(name[, default]) 244 | ``` 245 | 246 | ### init.prompts 247 | An object of all the prompts. 248 | 249 | ```js 250 | var prompts = init.prompts; 251 | ``` 252 | 253 | ### init.readDefaults 254 | Read JSON defaults from task files (if they exist), merging them into one data object. 255 | 256 | ```js 257 | init.readDefaults(filepath[, ...]) 258 | ``` 259 | 260 | ### init.renames 261 | The rename rules for the template. 262 | 263 | ```js 264 | var renames = init.renames; 265 | // renames === { 'test/name_test.js': 'test/{%= name %}_test.js' } 266 | ``` 267 | 268 | ### init.searchDirs 269 | An array of directories to search for templates in. 270 | 271 | ```js 272 | var dirs = init.searchDirs; 273 | /* dirs === [ '/Users/shama/.grunt-init', 274 | '/usr/local/lib/node_modules/grunt-init/templates' ] */ 275 | ``` 276 | 277 | ### init.srcpath 278 | Search init template paths for filename and return an absolute path. 279 | 280 | ```js 281 | init.srcpath(filepath[, ...]) 282 | ``` 283 | 284 | ### init.userDir 285 | Returns the absolute path to the user's template directory. 286 | 287 | ```js 288 | var dir = init.userDir(); 289 | // dir === '/Users/shama/.grunt-init' 290 | ``` 291 | 292 | ### init.writePackageJSON 293 | Save a package.json file in the destination directory. The callback can be used to post-process properties to add/remove/whatever. 294 | 295 | ```js 296 | init.writePackageJSON(filename, props[, callback]) 297 | ``` 298 | 299 | ## Built-in prompts 300 | 301 | ### author_email 302 | Author's email address to use in the `package.json`. Will attempt to find a default value from the user's git config. 303 | 304 | ### author_name 305 | Author's full name to use in the `package.json` and copyright notices. Will attempt to find a default value from the user's git config. 306 | 307 | ### author_url 308 | A public URL to the author's website to use in the `package.json`. 309 | 310 | ### bin 311 | A relative path from the project root for a cli script. 312 | 313 | ### bugs 314 | A public URL to the project's issues tracker. Will default to the GitHub issue tracker if the project has a GitHub repository. 315 | 316 | ### description 317 | A description of the project. Used in the `package.json` and README files. 318 | 319 | ### grunt_version 320 | A valid semantic version range descriptor of Grunt the project requires. 321 | 322 | ### homepage 323 | A public URL to the project's home page. Will default to the GitHub URL if a GitHub repository. 324 | 325 | ### jquery_version 326 | If a jQuery project, the version of jQuery the project requires. Must be a valid semantic version range descriptor. 327 | 328 | ### licenses 329 | The license(s) for the project. Multiple licenses are separated by spaces. The licenses built-in are: `MIT`, `MPL-2.0`, `GPL-2.0`, and `Apache-2.0`. Defaults to `MIT`. Add custom licenses with [init.addLicenseFiles](project-scaffolding#init.addlicensefiles). 330 | 331 | ### main 332 | The primary entry point of the project. Defaults to the project name within the `lib` folder. 333 | 334 | ### name 335 | The name of the project. Will be used heavily throughout the project template. Defaults to the current working directory. 336 | 337 | ### node_version 338 | The version of Node.js the project requires. Must be a valid semantic version range descriptor. 339 | 340 | ### npm_test 341 | The command to run tests on your project. Defaults to `grunt`. 342 | 343 | ### repository 344 | Project's git repository. Defaults to a guess of a GitHub URL. 345 | 346 | ### title 347 | A human readable project name. Defaults to the actual project name altered to be more human readable. 348 | 349 | ### version 350 | The version of the project. Defaults to the first valid semantic version, `0.1.0`. 351 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## [View Grunt Documentation](https://gruntjs.com/getting-started) 2 | 3 | This repository contains the wiki files for the official grunt documentation. 4 | Grunt documentation is based on the [Gollum Wiki](https://github.com/gollum/gollum/wiki) 5 | -------------------------------------------------------------------------------- /Roadmap.md: -------------------------------------------------------------------------------- 1 | ## Grunt 0.next 2 | 3 | * Drop Node.JS 0.8 support 4 | * New logging () 5 | * A logger to listen to events and output them to the console. Deals with stderr/stdout, or Grunt itself has this built in. 6 | * node-task () 7 | * Tasks as npm modules that can be required and run independent of any task runner (if you want to manually build a compliant config object to execute it). Can pipe data between multiple tasks (think coffeescript transpilation + uglify in a single step). All task output emitted as events. 8 | * A library for parsing configurations (merge options, template expansion, glob expansion (using lib from item #2) from the current Gruntfile format, into a valid form for running node-task compliant modules. Will support user-defined middleware for controlling config output. 9 | * A task runner which uses config parsing library from item #3 to execute node-task compatible modules (can be used programmatically, or via cli). Supports defining "alias" tasks which compile a set of tasks which can be run in parallel See: 10 | 11 | ## Grunt 0.5 12 | 13 | ### Update Release 14 | 15 | * Updates dependencies 16 | * Removes external libraries under `grunt.util.` 17 | * A library for glob expansion that handles arrays of globs, negation, etc. See 18 | 19 | See for updated information. 20 | 21 | 22 | 23 | 24 | ## Out of Date Information / Drafts 25 | 26 | **0.5 Gruntfile Ideas** 27 | 28 | ```js 29 | var grunt = require('grunt'); 30 | 31 | grunt.initConfig({ 32 | // defaults for cli 33 | grunt: { 34 | dryRun: true, 35 | stack: true, 36 | verbose: true, 37 | // what about defining loggers specific to a task? 38 | // is this required in your gruntfile or on by default? 39 | logger: [require('grunt-logger')] 40 | }, 41 | jshint: { 42 | // ... 43 | }, 44 | concat: { 45 | // ... 46 | }, 47 | min: { 48 | // ... 49 | } 50 | }); 51 | 52 | grunt.registerTask(require('grunt-contrib-jshint')); 53 | grunt.registerTask(require('grunt-contrib-concat')); 54 | grunt.registerTask(require('grunt-contrib-uglify'), 'min'); // optional second param renames 55 | 56 | // generates a node-task compliant object and runs grunt.registerTask on it 57 | grunt.registerTask('name','description', function (config) { 58 | //... 59 | }); 60 | 61 | // load a set of tasks to be run in parallel 62 | grunt.registerTask('name', ['jshint', 'concat'], { parallel:true }); 63 | 64 | // i think the cli should call this, but putting it here because you mentioned thinking it should go here. 65 | grunt.run(); 66 | ``` 67 | 68 | ***Please ignore the section below. It is a jumbled mess/work in progress and should not be considered anything resembling a roadmap.*** 69 | 70 | 527 - parallel execution of tasks 71 | 545 - conditional compilation (probably belongs on the watch task) 72 | 493 - cwd handling 73 | 74 | * more specific error codes 75 | * Task not found 76 | * Task failed 77 | * Task requirement not met 78 | * Config requirement not met 79 | 80 | ## grunt-log 81 | * Log to stderr/stdout. [#586](https://github.com/gruntjs/grunt/issues/586) [#570](https://github.com/gruntjs/grunt/issues/570) [#120](https://github.com/gruntjs/grunt/issues/120) 82 | * 83 | 84 | ## grunt-file 85 | * 86 | 87 | ## grunt-util 88 | * 89 | -------------------------------------------------------------------------------- /Sample-Gruntfile.md: -------------------------------------------------------------------------------- 1 | In this page we walk you through the creation of a `Gruntfile` that covers the usual needs of a simple project. If you already know how to set up a `Gruntfile` and you're looking for a quick example, here's one: 2 | 3 | ```js 4 | module.exports = function(grunt) { 5 | 6 | grunt.initConfig({ 7 | jshint: { 8 | files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], 9 | options: { 10 | globals: { 11 | jQuery: true 12 | } 13 | } 14 | }, 15 | watch: { 16 | files: ['<%= jshint.files %>'], 17 | tasks: ['jshint'] 18 | } 19 | }); 20 | 21 | grunt.loadNpmTasks('grunt-contrib-jshint'); 22 | grunt.loadNpmTasks('grunt-contrib-watch'); 23 | 24 | grunt.registerTask('default', ['jshint']); 25 | 26 | }; 27 | ``` 28 | 29 | ## Requirements 30 | 31 | Every project has its own needs, but most of them have something in common. In this guide we introduce you to a few Grunt plugins to automate basic requirements. The final goal is to teach you how to configure these Grunt plugins so that you can use them in your projects. 32 | 33 | For the sake of the example, let's say that you're creating a JavaScript library. The typical folder structure features the following folders: `src`, `dist`, and `test`. The `src` folder (sometimes called `app`) contains the source code of the library as you author it. The `dist` folder (sometimes called `build`) contains the distribution, a minified version of the source code. A minified file is one where all unnecessary characters, such as spaces, new lines, comments are removed, without affecting the functionality of the source code. Minified source code is especially useful for users of the project because it reduces the amount of data that needs to be transferred. Finally, the `test` folder contains the code to test the project. This set up will be used in the next sections when creating the `Gruntfile` configuration. 34 | 35 | While developing the library and releasing new versions there are a few tasks that you need to perform on a regular basis. For example, you might want to ensure that the code you write adheres to best practices, or that the code you've written doesn't result in unexpected behaviors. To do that, you can employ a tool called [JSHint](http://jshint.com/about/). Grunt has an official plugin for it called [grunt-contrib-jshint](https://github.com/gruntjs/grunt-contrib-jshint) which we'll adopt in this example. In particular, you might want to ensure that as you modify your code, you don't break any rules or best practices. So, a good strategy is to check the code at every change you perform. To do that, we'll cover a Grunt plugin called [grunt-contrib-watch](https://github.com/gruntjs/grunt-contrib-watch). The latter runs predefined tasks, such as `grunt-contrib-jshint`, whenever files are added, changed, or deleted. 36 | 37 | Checking that your source code follows best practices is not enough to guarantee that it's stable and doesn't contain bugs. To create a robust project, you need to test it. There are several libraries you can adopt such as [QUnit](https://qunitjs.com/) or [Jasmine](http://jasmine.github.io/). In this guide, we describe how to configure QUnit, and specifically [grunt-contrib-qunit](https://github.com/gruntjs/grunt-contrib-qunit), to test your code. 38 | 39 | When it comes to distributing your work, you want to offer a version as small in size as possible. To create a minified version you need a Grunt plugin like [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify). Moreover, unless the project you're developing is very small, chances are that you've split the code in multiple files. While this is a good practice for the developer, you want users to include only one file. So, before minifying the code, you should concatenate the source files to create a single one. To achieve this goal you need a Grunt plugin like [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat). 40 | 41 | To sum up, in this guide we'll use the following five Grunt plugins: 42 | 43 | * [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify) 44 | * [grunt-contrib-qunit](https://github.com/gruntjs/grunt-contrib-qunit) 45 | * [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat) 46 | * [grunt-contrib-jshint](https://github.com/gruntjs/grunt-contrib-jshint) 47 | * [grunt-contrib-watch](https://github.com/gruntjs/grunt-contrib-watch) 48 | 49 | If you're curious about what the final result looks like, the entire `Gruntfile` can be found at the bottom of this page. 50 | 51 | ## Setting up the `Gruntfile` 52 | 53 | The first part is the "wrapper" function, which encapsulates your Grunt configuration. 54 | 55 | ```js 56 | module.exports = function(grunt) { 57 | }; 58 | ``` 59 | 60 | Within that function we can initialize our configuration object: 61 | 62 | ```js 63 | grunt.initConfig({ 64 | }); 65 | ``` 66 | 67 | Next, we can store the project settings from the `package.json` file into the `pkg` property. This allows us to refer to the values of properties within our `package.json` file, as we'll see shortly. 68 | 69 | ```js 70 | pkg: grunt.file.readJSON('package.json') 71 | ``` 72 | 73 | This leaves us with this so far: 74 | 75 | ```js 76 | module.exports = function(grunt) { 77 | grunt.initConfig({ 78 | pkg: grunt.file.readJSON('package.json') 79 | }); 80 | }; 81 | ``` 82 | 83 | Now we can define a configuration for each of the tasks we mentioned. The configuration object for a plugin lives as a property on the configuration object, that often shares the same name as its plugin. The configuration for `grunt-contrib-concat` goes in the configuration object under the `concat` key as shown below: 84 | 85 | ```js 86 | concat: { 87 | options: { 88 | // define a string to put between each file in the concatenated output 89 | separator: ';' 90 | }, 91 | dist: { 92 | // the files to concatenate 93 | src: ['src/**/*.js'], 94 | // the location of the resulting JS file 95 | dest: 'dist/<%= pkg.name %>.js' 96 | } 97 | } 98 | ``` 99 | 100 | Note how in the snippet above we refer to the `name` property that's in the JSON file. We access it by using `pkg.name` as earlier we defined the `pkg` property to be the result of loading the `package.json` file, which is then parsed to a JavaScript object. Grunt has a simple template engine to output the values of properties in the configuration object. Here we tell the `concat` task to concatenate all files that exist within `src/` and end in `.js`. 101 | 102 | Now let's configure the `grunt-contrib-uglify` plugin, which minifies the JavaScript code: 103 | 104 | ```js 105 | uglify: { 106 | options: { 107 | // the banner is inserted at the top of the output 108 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' 109 | }, 110 | dist: { 111 | files: { 112 | 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] 113 | } 114 | } 115 | } 116 | ``` 117 | 118 | This snippet tells `grunt-contrib-uglify` to create a file within `dist/` that contains the result of minifying the JavaScript files. Here we use `<%= concat.dist.dest %>` so uglify will minify the file that the concat task produces. 119 | 120 | Up to this point, we have configured the plugins to create the distribution version the library. It's now time to use `grunt-contrib-qunit` to automate the testing of the code. To do that, we need to give to specify the location of the test runner files, which are the HTML files QUnit runs on. The resulting code is reported below: 121 | 122 | ```js 123 | qunit: { 124 | files: ['test/**/*.html'] 125 | }, 126 | ``` 127 | 128 | Once done, it's time to set up the configuration to ensure that the code of the project adheres to best practices. JSHint is a tool that can detect issues or potential issues like a high cyclomatic complexity, the use of the equality operator instead of the strict equality operator, and the definition of unused variables and functions. 129 | 130 | We advise you to analyze with `grunt-contrib-jshint` all the JavaScript files of your project, including `Gruntfile` and the test files. An example of configuration of `grunt-contrib-jshint` is the following: 131 | 132 | ```js 133 | jshint: { 134 | // define the files to lint 135 | files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], 136 | // configure JSHint (documented at http://www.jshint.com/docs/) 137 | options: { 138 | // more options here if you want to override JSHint defaults 139 | globals: { 140 | jQuery: true, 141 | console: true, 142 | module: true 143 | } 144 | } 145 | } 146 | ``` 147 | 148 | This plugin takes an array of files and then an object of options. These are all [documented on the JSHint site](http://www.jshint.com/docs/). If you're happy with the plugin defaults, there's no need to redefine them in the Gruntfile. 149 | 150 | The last plugin left to configure is `grunt-contrib-watch`. We'll use it to run the `jshint` and the `qunit` tasks as soon as a JavaScript file is added, deleted, or modified. When it detects any of the files specified have changed (here, we use the same files we told JSHint to check), it will run the tasks you specify, in the order they appear. This can be run on the command line with `grunt watch`. 151 | 152 | Turning the previous description into a configuration for `grunt-contrib-watch` results in the snippet below: 153 | 154 | ```js 155 | watch: { 156 | files: ['<%= jshint.files %>'], 157 | tasks: ['jshint', 'qunit'] 158 | } 159 | ``` 160 | 161 | With this snippet, we've set up the configuration for all the plugins mentioned in the introduction. The last step to perform is to load in the Grunt plugins we need. All of these should have been previously installed through npm. 162 | 163 | ```js 164 | grunt.loadNpmTasks('grunt-contrib-uglify'); 165 | grunt.loadNpmTasks('grunt-contrib-jshint'); 166 | grunt.loadNpmTasks('grunt-contrib-qunit'); 167 | grunt.loadNpmTasks('grunt-contrib-watch'); 168 | grunt.loadNpmTasks('grunt-contrib-concat'); 169 | ``` 170 | 171 | And finally set up some tasks. The most important of these tasks is the default task: 172 | 173 | ```js 174 | // this would be run by typing "grunt test" on the command line 175 | grunt.registerTask('test', ['jshint', 'qunit']); 176 | 177 | // the default task can be run just by typing "grunt" on the command line 178 | grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']); 179 | ``` 180 | 181 | The default task is executed when you invoke `Grunt` without specifying a task to execute (`grunt`). 182 | 183 | ## The resulting `Gruntfile` 184 | 185 | If you've followed this guide correctly you should have the following `Gruntfile`: 186 | 187 | ```js 188 | module.exports = function(grunt) { 189 | 190 | grunt.initConfig({ 191 | pkg: grunt.file.readJSON('package.json'), 192 | concat: { 193 | options: { 194 | separator: ';' 195 | }, 196 | dist: { 197 | src: ['src/**/*.js'], 198 | dest: 'dist/<%= pkg.name %>.js' 199 | } 200 | }, 201 | uglify: { 202 | options: { 203 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' 204 | }, 205 | dist: { 206 | files: { 207 | 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] 208 | } 209 | } 210 | }, 211 | qunit: { 212 | files: ['test/**/*.html'] 213 | }, 214 | jshint: { 215 | files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], 216 | options: { 217 | // options here to override JSHint defaults 218 | globals: { 219 | jQuery: true, 220 | console: true, 221 | module: true, 222 | document: true 223 | } 224 | } 225 | }, 226 | watch: { 227 | files: ['<%= jshint.files %>'], 228 | tasks: ['jshint', 'qunit'] 229 | } 230 | }); 231 | 232 | grunt.loadNpmTasks('grunt-contrib-uglify'); 233 | grunt.loadNpmTasks('grunt-contrib-jshint'); 234 | grunt.loadNpmTasks('grunt-contrib-qunit'); 235 | grunt.loadNpmTasks('grunt-contrib-watch'); 236 | grunt.loadNpmTasks('grunt-contrib-concat'); 237 | 238 | grunt.registerTask('test', ['jshint', 'qunit']); 239 | 240 | grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']); 241 | 242 | }; 243 | ``` 244 | -------------------------------------------------------------------------------- /Support.md: -------------------------------------------------------------------------------- 1 | We support the latest version with security and bug fixes. The previous versions are all end-of-life and will not receive any security or bug fixes. 2 | 3 | Our OpenJS Ecosystem Sustainability Program partner [HeroDevs](https://www.herodevs.com/support#request-technologies) provides drop-in replacements for older versions of Grunt that are kept up-to-date for security and compliance issues. Learn More. 4 | 5 | ### Version Support 6 | 7 | | Version | Supported? | Commercial Support | 8 | | ------- | ---------- | ----------------------------------------------------------------------- | 9 | | 1.6 | YES | | 10 | | 1.5 | NO | [Available Here](https://www.herodevs.com/support#request-technologies) | 11 | | 1.4 | NO | [Available Here](https://www.herodevs.com/support#request-technologies) | 12 | | 1.3 | NO | [Available Here](https://www.herodevs.com/support#request-technologies) | 13 | | 1.2 | NO | [Available Here](https://www.herodevs.com/support#request-technologies) | 14 | | 1.1 | NO | [Available Here](https://www.herodevs.com/support#request-technologies) | 15 | | 1.0 | NO | [Available Here](https://www.herodevs.com/support#request-technologies) | 16 | | 0.4 | NO | [Available Here](https://www.herodevs.com/support#request-technologies) | 17 | -------------------------------------------------------------------------------- /Testing-Tasks.md: -------------------------------------------------------------------------------- 1 | _TODO_ 2 | -------------------------------------------------------------------------------- /Upgrading-from-0.3-to-0.4.md: -------------------------------------------------------------------------------- 1 | > Versions 0.4 and older are no longer maintained. Find out more and see additional support options [here](support). 2 | 3 | _Note that even if you are familiar with grunt, it would be worthwhile to read the new [[Getting started]] guide._ 4 | 5 | Grunt is now split into three parts: `grunt`, `grunt-cli` and `grunt-init`. 6 | 7 | 1. The npm module `grunt` should be installed locally to your project. It contains the code and logic for running tasks, loading plugins, etc. 8 | 2. The npm module `grunt-cli` should be installed globally. It puts the `grunt` command in your PATH so you can execute it anywhere. By itself, it doesn't do anything; its job is to load and run the Grunt that has been installed locally to your project, regardless of the version. For more information about why this has changed, please read [npm 1.0: Global vs Local installation](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation). 9 | 3. The `init` task has been broken into its own npm module, `grunt-init`. It should be installed globally with `npm install -g grunt-init` and run with the `grunt-init` command. In the coming months, [Yeoman](http://yeoman.io/) will completely replace grunt-init. See the [grunt-init project page](https://github.com/gruntjs/grunt-init) for more information. 10 | 11 | ## Grunt 0.3 Notes 12 | 13 | If you are upgrading from Grunt 0.3, make sure to uninstall global `grunt`: 14 | 15 | ```shell 16 | npm uninstall -g grunt 17 | ``` 18 | 19 | _Note that for 0.3.x, plugin names and task configuration options may be different than those shown in "The Gruntfile" section._ 20 | 21 | _This file was named `grunt.js` for 0.3.x versions of Grunt._ 22 | 23 | ## Pre-existing tasks and plugins 24 | 25 | All `grunt-contrib-*` series plugins are Grunt 0.4 ready. However, it is highly unlikely that third party plugins written for Grunt 0.3 will continue to work with 0.4 until they have been updated. We are actively working with plugin authors to ensure this happens as swiftly as possible. 26 | 27 | _A forthcoming Grunt release will be focused on decoupling grunt's architecture so that plugins are not affected by future updates._ 28 | 29 | ## Requirements 30 | 31 | - Grunt now requires Node.js version `>= 0.8.0` 32 | 33 | ## The Gruntfile 34 | 35 | - The "Gruntfile" has changed from `grunt.js` to `Gruntfile.js`. 36 | - CoffeeScript is supported in your `Gruntfile.coffee` project `Gruntfile` or `*.coffee` task files (transpiling to JS happens automatically). 37 | 38 | See the "The Gruntfile" section of the [[Getting started]] guide for more information. 39 | 40 | ## Core Tasks are now Grunt Plugins 41 | 42 | The eight core tasks that were included in Grunt 0.3 are now separate Grunt plugins. Each is a discrete npm module that must be installed as a plugin per the "Loading Grunt plugins and tasks" section of the [[Getting started]] guide. 43 | 44 | - concat → [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat) plugin 45 | - init → stand-alone [grunt-init] utility 46 | - lint → [grunt-contrib-jshint](https://github.com/gruntjs/grunt-contrib-jshint) plugin 47 | - min → [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify) plugin 48 | - qunit → [grunt-contrib-qunit](https://github.com/gruntjs/grunt-contrib-qunit) plugin 49 | - server → [grunt-contrib-connect](https://github.com/gruntjs/grunt-contrib-connect) plugin 50 | - test → [grunt-contrib-nodeunit](https://github.com/gruntjs/grunt-contrib-nodeunit) plugin 51 | - watch → [grunt-contrib-watch](https://github.com/gruntjs/grunt-contrib-watch) plugin 52 | 53 | Some task names and options have changed. Be sure to see each plugin's documentation as linked above for the latest configuration details. 54 | 55 | ## Configuration 56 | 57 | The configuration format for Grunt 0.4 tasks has been standardized and greatly enhanced. See the [[Configuring tasks]] guide, as well as individual plugin documentation for more information. 58 | 59 | - File globbing (wildcard) patterns may now be negated to exclude matched files. 60 | - Tasks now support a standard `options` object. 61 | - Tasks now support a standard `files` object. 62 | 63 | `<% %>` style template strings specified as config data inside the `Gruntfile` are automatically expanded, see the [[grunt.template]] documentation for more information. 64 | 65 | **Directives have been removed**, but their functionality has been retained. These replacements can be made: 66 | 67 | - `''` → `'<%= prop.subprop %>'` 68 | - `''` → `grunt.file.readJSON('file.json')` 69 | - `''` → `grunt.template.process(grunt.file.read('file.js'))` 70 | 71 | Instead of specifying a banner in a file list with `''` or `''`, the [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat) and [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify) plugins each have a `banner` option. 72 | 73 | Instead of stripping banners from files individually with `''`, the [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat) and [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify) plugins each have an option to strip/preserve banners. 74 | 75 | ## Alias task changes 76 | 77 | When specifying an alias task, the list of tasks to run must now be specified as an array. 78 | 79 | ```js 80 | // v0.3.x (old format) 81 | grunt.registerTask("default", "jshint nodeunit concat"); 82 | // v0.4.x (new format) 83 | grunt.registerTask("default", ["jshint", "nodeunit", "concat"]); 84 | ``` 85 | 86 | ## Task arguments may now contain spaces 87 | 88 | The aforementioned alias task change (task lists must be specified as an array) makes this possible. Just be sure to surround task arguments containing spaces with quotes when specifying them on the command line, so they can be properly parsed. 89 | 90 | ```shell 91 | grunt my-task:argument-without-spaces "other-task:argument with spaces" 92 | ``` 93 | 94 | ## Character encodings 95 | 96 | The [file.defaultEncoding](grunt.file#wiki-grunt-file-defaultEncoding) method was added to normalize character encodings, and all `grunt.file` methods have been updated to support the specified encoding. 97 | 98 | ## Helpers 99 | 100 | Grunt's helper system has been removed in favor of node `require`. For a concise example on how to share functionality between Grunt plugins, please see [grunt-lib-legacyhelpers](https://github.com/gruntjs/grunt-lib-legacyhelpers). Plugin authors are encouraged to upgrade their plugins. 101 | 102 | ## API 103 | 104 | The Grunt API saw substantial changes from 0.3 to 0.4. 105 | 106 | - [grunt](grunt) 107 | - Removed `grunt.registerHelper` and `grunt.renameHelper` methods. 108 | - [grunt.config](grunt.config) 109 | - Changed [config.get](grunt.config#wiki-grunt-config-get) method to automatically recursively expand `<% %>` templates. 110 | - Added [config.getRaw](grunt.config#wiki-grunt-config-getRaw) method that will retrieve raw (unexpanded) config data. 111 | - Changed [config.process](grunt.config#wiki-grunt-config-process) method to now process a value as if it had been retrieved from the config, expanding templates recursively. This method is called internally inside of `config.get`, but _not_ inside of `config.getRaw`. 112 | - [grunt.event](grunt.event) added so that tasks may emit events. 113 | - [grunt.fail](grunt.fail) 114 | - Won't emit a beep if `--no-color` option specified. 115 | - Added `fail.code` exit code map. 116 | - Removed `fail.warnAlternate` method. 117 | - [grunt.file](grunt.file) 118 | - Tasks are no longer automatically loaded from `~/.grunt/tasks/` directory (install them locally to your project!). 119 | - Added [file.defaultEncoding](grunt.file#wiki-grunt-file-defaultEncoding) method for normalizing character encoding across all `grunt.file` methods. 120 | - Added [file.delete](grunt.file#wiki-grunt-file-delete) method. 121 | - Added relatively self-explanatory [file.exists](grunt.file#wiki-grunt-file-exists), [file.isDir](grunt.file#wiki-grunt-file-isDir), [file.isFile](grunt.file#wiki-grunt-file-isFile), [file.isLink](grunt.file#wiki-grunt-file-isLink), [file.isPathCwd](grunt.file#wiki-grunt-file-isPathCwd), [file.isPathInCwd](grunt.file#wiki-grunt-file-isPathInCwd), [file.doesPathContain](grunt.file#wiki-grunt-file-doesPathContain), [file.arePathsEquivalent](grunt.file#wiki-grunt-file-arePathsEquivalent) testing methods. 122 | - Added [file.match](grunt.file#wiki-grunt-file-match) and [file.isMatch](grunt.file#wiki-grunt-file-isMatch) methods to facilitate matching wildcard patterns against file paths. 123 | - Added [file.expandMapping](grunt.file#wiki-grunt-file-expandMapping) method for use in generating 1-to-1 src-dest file mappings. 124 | - Added [file.readYAML](grunt.file#wiki-grunt-file-readYAML) method. 125 | - Changed [file.findup](grunt.file#wiki-grunt-file-findup) to use the [findup-sync](https://github.com/cowboy/node-findup-sync) module. 126 | - Changed [file.glob](grunt.file#wiki-grunt-file-glob) to use the [glob](https://github.com/isaacs/node-glob) module. 127 | - Added [file.minimatch](grunt.file#wiki-grunt-file-minimatch) which exposes the [minimatch](https://github.com/isaacs/minimatch) module. 128 | - Removed `file.userDir` method (moved into [grunt-init]). 129 | - Removed `file.clearRequireCache` method. 130 | - Removed `file.expandFiles` and `file.expandDirs` methods, use the `filter` option of `file.expand` instead. 131 | - Removed `file.expandFileURLs` method. Don't specify URLs where files should be specified (eg. the qunit task now allows for a `urls` option). 132 | - [grunt.task](grunt#wiki-grunt-task) 133 | - Tasks registered with both [task.registerTask](grunt.task#wiki-grunt-task-registerTask) and [task.registerMultiTask](grunt.task#wiki-grunt-task-registerMultiTask) get a `this.options` method. 134 | - Added [task.normalizeMultiTaskFiles](grunt.task#wiki-grunt-task-normalizeMultiTaskFiles) method to facilitate the normalization of multi task `files` objects into the `this.file` property. 135 | - Removed `task.registerHelper` and `task.renameHelper` methods. 136 | - Removed `task.searchDirs` property. 137 | - Removed `task.expand` `task.expandDirs` `task.expandFiles` `task.getFile` `task.readDefaults` methods (moved into [grunt-init]). 138 | - [grunt.package](grunt#wiki-grunt-package) reflects the metadata stored in grunt's `package.json`. 139 | - [grunt.version](grunt#wiki-grunt-version) is the current version of Grunt as a string. 140 | - [grunt.template](grunt.template) 141 | - Added [template.addDelimiters](grunt.template#wiki-grunt-template-addDelimiters) method to add new template delimiters. 142 | - Added [template.setDelimiters](grunt.template#wiki-grunt-template-setDelimiters) method to select template delimiters. 143 | - The `init` and `user` template delimiters have been removed, but you can add them in again if you need to with `template.addDelimiters` ([grunt-init] uses this to enable the `{% %}` template delimiters). 144 | - [grunt.util](grunt.util) replaces the now-removed `grunt.utils`. 145 | - Changed `util._` to use [Lo-Dash](http://lodash.com/) 146 | - Added the [util.callbackify](grunt.util#wiki-grunt-util-callbackify) method. 147 | - Changed the [util.spawn](grunt.util#wiki-grunt-util-spawn) method to be much better behaved and pass more consistent arguments into its callback. 148 | 149 | ## Task / plugin authors 150 | 151 | **Plugin authors, please indicate clearly on your repository README which version number of your Grunt plugin breaks compatibility with Grunt 0.3.** 152 | 153 | ### Tasks 154 | 155 | - Multi tasks 156 | - Multiple src-dest file mappings may now be specified per target in a `files` object (this is optional). 157 | - [this.files / grunt.task.current.files](grunt.task#wiki-this-files) 158 | - The `this.files` property is an array of src-dest file mapping objects to be iterated over in your multi task. It will always be an array, and you should always iterate over it, even if the most common use case is to specify a single file. 159 | - Each src-dest file mapping object has a `src` and `dest` property (and possibly others, depending on what the user specified). The `src` property is already expanded from whatever glob pattern the user may have specified. 160 | - [this.filesSrc / grunt.task.current.filesSrc](grunt.task#wiki-this-filesSrc) 161 | - The `this.filesSrc` property is a reduced, uniqued array of all files matched by all specified `src` properties. Useful for read-only tasks. 162 | - [this.options / grunt.task.current.options](grunt.task#wiki-this-options) 163 | - The `this.options` method may be used within tasks to normalize options. Inside a task, you may specify options defaults like: `var options = this.options({option: 'defaultvalue', ...});` 164 | 165 | ### Plugins 166 | 167 | - An updated `gruntplugin` template has been created for Grunt 0.4-compatible plugins, and is available in the standalone [grunt-init]. 168 | 169 | ## Troubleshooting 170 | 171 | - If you had previously installed a development version of Grunt 0.4 or any grunt-contrib plugins, be sure to flush your npm cache with `npm cache clean` first to ensure that you are pulling the final version of Grunt and grunt-contrib plugins. 172 | 173 | [grunt-init]: https://github.com/gruntjs/grunt-init 174 | -------------------------------------------------------------------------------- /Upgrading-from-0.4-to-1.0.md: -------------------------------------------------------------------------------- 1 | > Old versions, such as 1.5 and older are no longer maintained. Find out more and see additional support options [here](support). 2 | 3 | This guide is here to help you update your projects and plugins from Grunt 0.4.x to Grunt 1.0. 4 | 5 | **Be advised Grunt 1.0.0 no longer supports Node.js v0.8.** 6 | 7 | ## For Projects that use Grunt 8 | 9 | ### Peer Dependencies 10 | 11 | You might receive `peerDependencies` errors when you install a project with Grunt 1.0. 12 | We ask you to send pull requests to your favourite plugins and ask them to update the peerDependencies section of their package.json. 13 | See below for details about plugin updates. 14 | 15 | ## For Plugins and Plugin developers 16 | 17 |

Peer Dependencies

18 | 19 | If you have a Grunt plugin that includes grunt in the peerDependencies section of your package.json, 20 | we recommend tagging with "grunt": ">=0.4.0". Otherwise when grunt@1.0.0 is released, npm@2 users will 21 | receive a hard error when trying to install your plugin and npm@3 users will get a warning. 22 | 23 | Be aware, peer dependencies are no longer installed for users as of npm@3. 24 | Users of Grunt plugins are expected to npm install grunt --save-dev alongside any Grunt plugin install. 25 | 26 | We ask you to update your plugin with `"grunt": ">=0.4.0"` in it and publish that on npm. 27 | 28 | ### Changes in 1.0.0 29 | 30 | - Prevent async callback from being called multiple times. Pull #1464. 31 | - Update copyright to jQuery Foundation and remove redundant headers. Fixes #1478. 32 | - Update glob to 7.0.x. Fixes #1467. 33 | - Removing duplicate BOM strip code. Pull #1482. 34 | - Updated to latest cli ~1.2.0 35 | - Ensure a grunt bin gets created upon install. 36 | 37 | ### Changes in Grunt 1.0 RC1: 38 | 39 | Be aware, some APIs have changed warranting a major version update: 40 | 41 | - `coffee-script` is upgraded to `~1.10.0` which could incur breaking changes 42 | when using the language with plugins and Gruntfiles. 43 | - `nopt` is upgraded to `~3.0.6` which has fixed many issues, including passing 44 | multiple arguments and dealing with numbers as options. Be aware previously 45 | `--foo bar` used to pass the value `'bar'` to the option `foo`. It will now 46 | set the option `foo` to `true` and run the task `bar`. 47 | - `glob` is upgraded to `~6.0.4` and `minimatch` is upgraded to `~3.0.0`. Results 48 | are now sorted by default with `grunt.file.expandMapping()`. Pass the 49 | `nosort: true` option if you don't want the results to be sorted. 50 | - `lodash` was upgraded to `~4.3.0`. Many changes have occurred. Some of which 51 | that directly effect Grunt are `grunt.util._.template()` returns a compile 52 | function and `grunt.util._.flatten` no longer flattens deeply. 53 | `grunt.util._` is deprecated and we highly encourage you to 54 | `npm install lodash` and `var _ = require('lodash')` to use `lodash`. 55 | Please see the lodash changelog for a full list of changes: 56 | - `iconv-lite` is upgraded to `~0.4.13` and strips the BOM by default. 57 | - `js-yaml` is upgraded to `~3.5.2` and may affect `grunt.file.readYAML`. 58 | We encourage you to please `npm install js-yaml` and use 59 | `var YAML = require('js-yaml')` directly in case of future deprecations. 60 | - A file `mode` option can be passed into 61 | [grunt.file.write()](https://gruntjs.com/api/grunt.file#grunt.file.write). 62 | - `Done, without errors.` was changed to `Done.` to avoid failing by mistake on the word `errors`. 63 | -------------------------------------------------------------------------------- /Using-plugins.md: -------------------------------------------------------------------------------- 1 | Grunt plugins define tasks that implement certain build steps and can be reused across multiple projects. The examples will use the plugin _"grunt-contrib-uglify"_. Check the [Grunt website](https://gruntjs.com/) for a list of available plugins. 2 | 3 | ## Installing a Grunt plugin 4 | 5 | The first step to using an existing Grunt plugin is to install it.Grunt plugins are packaged as node modules and can be installed using [npm](http://npmjs.org) like this: 6 | 7 | `npm install --save-dev grunt-contrib-uglify` 8 | 9 | This will install the Grunt plugin _"grunt-contrib-uglify"_ locally into the `node_modules` folder (cf. [npm folders](https://docs.npmjs.com/files/folders)). 10 | Plugins must be installed locally to avoid version conflicts when working with multiple projects. 11 | 12 | Specifying `--save-dev` as option automatically adds this Grunt plugin to the _"devDependency"_ section in the `package.json` file. This file lists all node dependencies of a project. 13 | Adding the Grunt plugin there will allow other developers working on the project to simply run `npm install` to locally install these required dependencies. 14 | 15 | ## Loading plugin tasks 16 | 17 | Now that the plugin is installed, it is time to tell Grunt about it and let it load all defined tasks. To do this, add the following line to your `Gruntfile.js`: 18 | 19 | `grunt.loadNpmTasks('grunt-contrib-uglify')` 20 | 21 | This line should be added within the top level function scope (not the initConfig section) where other `grunt.registerTask()` calls are made. 22 | 23 | ### Monorepos 24 | 25 | Since v1.2.0, Grunt will load its plugins that are located in any location that is visible to Node.js and NPM, instead of node_modules directly inside package that have a dev dependency to these plugins. 26 | 27 | ## Running plugin tasks 28 | 29 | Plugin tasks can be run like other Grunt tasks either by specifying them on the command line: 30 | 31 | `grunt uglify` 32 | 33 | Or by registering a new task alias which calls this task, and running that task: 34 | 35 | `grunt.registerTask("dist", ["uglify"])` 36 | 37 | ## Configuring plugins 38 | 39 | Plugin configuration depends on the specific plugin, so check the plugin's documentation for further information. Generally the configuration is located in the `initConfig` section of the Gruntfile. 40 | 41 | **TODO**: Configuration Targets/options (Merge [Configuring tasks](Configuring tasks)?) 42 | -------------------------------------------------------------------------------- /Using-the-CLI.md: -------------------------------------------------------------------------------- 1 | ## Installing the CLI 2 | 3 | Run `sudo npm install -g grunt-cli` (Windows users should omit "sudo ", and may need to run the command-line with elevated privileges). 4 | 5 | The `grunt` command-line interface comes with a series of options. Use `grunt -h` from your terminal to show these options. 6 | 7 | ### --help, -h 8 | 9 | Display help text 10 | 11 | ### --base, -b 12 | 13 | Specify an alternate base path. By default, all file paths are relative to the `Gruntfile`. 14 | 15 | Alternative to `grunt.file.setBase(...)` 16 | 17 | ### --no-color 18 | 19 | Disable colored output. 20 | 21 | ### --gruntfile 22 | 23 | Specify an alternate `Gruntfile`. 24 | 25 | By default, grunt looks in the current or parent directories for the nearest `Gruntfile.js` or `Gruntfile.[ext]` file. 26 | 27 | ### --debug, -d 28 | 29 | Enable debugging mode for tasks that support it. 30 | 31 | ### --stack 32 | 33 | Print a stack trace when exiting with a warning or fatal error. 34 | 35 | ### --force, -f 36 | 37 | A way to force your way past warnings. 38 | 39 | Want a suggestion? Don't use this option, fix your code. 40 | 41 | ### --tasks 42 | 43 | Additional directory paths to scan for task and "extra" files. 44 | 45 | Alternative to `grunt.loadTasks(...)` 46 | 47 | ### --npm 48 | 49 | Npm-installed grunt plugins to scan for task and "extra" files. 50 | 51 | Alternative to `grunt.loadNpmTasks(...)` 52 | 53 | ### --no-write 54 | 55 | Disable writing files (dry run). 56 | 57 | ### --verbose, -v 58 | 59 | Verbose mode. A lot more information output. 60 | 61 | ### --version, -V 62 | 63 | Print the grunt version. Combine with --verbose for more info. 64 | 65 | ### --completion 66 | 67 | Output shell auto-completion rules. See the grunt-cli documentation for more information. 68 | 69 | ### --preload 70 | 71 | Specify a language interpreter to require first if you are writing your Gruntfile in a language Grunt doesn't support by default. 72 | 73 | ### --require (Grunt 1.3.0 and below) 74 | 75 | Specify a language interpreter to require first if you are writing your Gruntfile in a language Grunt doesn't support by default. -------------------------------------------------------------------------------- /Who-uses-Grunt.md: -------------------------------------------------------------------------------- 1 | *Not accepting additional entries at the moment*. 2 | 3 | ### [INK](http://ink.sapo.pt) 4 | 5 | ### [Adobe](http://www.adobe.com/) 6 | * [Brackets](http://brackets.io/) ([Gruntfile](https://github.com/adobe/brackets/blob/master/Gruntfile.js)) 7 | * [CSS FilterLab](http://html.adobe.com/webstandards/csscustomfilters/cssfilterlab/) ([Gruntfile](https://github.com/adobe/cssfilterlab/blob/master/grunt.js)) 8 | 9 | ### [jQuery](https://jquery.com/) 10 | * [jQuery](https://jquery.com/) - ([Gruntfile](https://github.com/jquery/jquery/blob/master/Gruntfile.js)) 11 | * [jQuery UI](https://jqueryui.com/) - ([Gruntfile](https://github.com/jquery/jquery-ui/blob/master/Gruntfile.js)) 12 | * [QUnit](http://qunitjs.com/) - ([Gruntfile](https://github.com/jquery/qunit/blob/master/Gruntfile.js)) 13 | 14 | ### [Twitter](https://twitter.com/) 15 | * [Tweetdeck](https://tweetdeck.twitter.com/) 16 | * [Typeahead](https://github.com/twitter/typeahead.js) ([Gruntfile](https://github.com/twitter/typeahead.js/blob/master/Gruntfile.js)) 17 | 18 | ### [Mozilla](https://mozilla.org/) 19 | * [Firefox Accounts projects](https://accounts.firefox.com) ([Gruntfile](https://github.com/mozilla/fxa-content-server/blob/master/Gruntfile.js), [Gruntfile](https://github.com/mozilla/fxa-auth-server/blob/master/Gruntfile.js), [Gruntfile](https://github.com/mozilla/fxa-js-client/blob/master/Gruntfile.js)) 20 | 21 | ### [Bootstrap](http://getbootstrap.com/) 22 | * [Gruntfile](https://github.com/twbs/bootstrap/blob/master/Gruntfile.js) 23 | 24 | ### [Cloudant](https://cloudant.com/) 25 | * [Backbone Cloudant](https://github.com/cloudant-labs/backbone.cloudant) ([Gruntfile](https://github.com/cloudant-labs/backbone.cloudant/blob/master/Gruntfile.js)) 26 | 27 | ### [Bitovi](http://bitovi.com/) 28 | * [CanJS](http://canjs.us/) ([Gruntfile](https://github.com/bitovi/canjs/blob/master/Gruntfile.js)) 29 | 30 | ### [TestObject](https://www.testobject.com) 31 | 32 | ### [Filament Group](http://filamentgroup.com/) 33 | * [X-rayHTML](https://github.com/filamentgroup/X-rayHTML) ([Gruntfile](https://github.com/filamentgroup/X-rayHTML/blob/master/grunt.js)) 34 | * [Grunticon](https://github.com/filamentgroup/grunticon) ([Gruntfile](https://github.com/filamentgroup/grunticon/blob/master/Gruntfile.js)) 35 | 36 | ### [Fuel UX](http://exacttarget.github.com/fuelux/) 37 | * [Fuel UX](http://exacttarget.github.com/fuelux/) ([Gruntfile](https://github.com/ExactTarget/fuelux/blob/master/Gruntfile.js)) 38 | 39 | ### [SauceLabs](https://saucelabs.com/) 40 | * [Appium](https://saucelabs.com/appium) ([Gruntfile](https://github.com/appium/appium/blob/master/Gruntfile.js)) 41 | 42 | ### [Modernizr](http://modernizr.com/) 43 | * [Modernizr](http://modernizr.com/) ([Gruntfile](https://github.com/Modernizr/Modernizr/blob/master/Gruntfile.js)) 44 | 45 | ### [Opera](http://opera.com) 46 | * [Opera GitHub Projects](https://github.com/operasoftware) 47 | 48 | ### [LiveChat](http://www.livechatinc.com) 49 | * [LiveChat Grunt Workflow](http://developers.livechatinc.com/blog/how-livechat-uses-grunt-js-for-easy-product-deployment/) 50 | 51 | ### [WordPress](https://wordpress.org/) 52 | * [WordPress Build Process](https://make.wordpress.org/core/2013/08/06/a-new-frontier-for-core-development/) ([Gruntfile](https://core.trac.wordpress.org/browser/trunk/Gruntfile.js)) 53 | * [bbPress](https://bbpress.org) ([Gruntfile](https://bbpress.trac.wordpress.org/browser/trunk/Gruntfile.js)) 54 | * [BuddyPress](https://buddypress.org) ([Gruntfile](https://buddypress.trac.wordpress.org/browser/trunk/Gruntfile.js)) 55 | 56 | ### [Walmart](http://www.walmart.com/) 57 | * [Thorax](https://github.com/walmartlabs/thorax) ([Gruntfile](https://github.com/walmartlabs/thorax/blob/master/Gruntfile.js)) 58 | * [Lumbar](http://walmartlabs.github.io/lumbar/) ([Gruntfile](https://github.com/walmartlabs/lumbar/blob/master/Gruntfile.js)) 59 | 60 | ### [Bazaarvoice](http://www.bazaarvoice.com/) 61 | 62 | ### [dscout](http://dscout.com/) 63 | * [Velge](https://github.com/dscout/velge) ([Gruntfile](https://github.com/dscout/velge/blob/master/Gruntfile.js)) 64 | 65 | ### [Ghost](https://ghost.org/) 66 | * [Gruntfile](https://github.com/TryGhost/Ghost/blob/master/Gruntfile.js) 67 | 68 | ### [JS Bin](http://jsbin.com/) 69 | * [Gruntfile](https://github.com/remy/jsbin/blob/master/Gruntfile.js) 70 | 71 | ### [SitePen](http://sitepen.com/) 72 | * [generator-dojo](https://github.com/bryanforbes/generator-dojo/) ([Gruntfile](https://github.com/bryanforbes/generator-dojo/blob/master/app/templates/Gruntfile.js)) 73 | * [Intern](http://theintern.io/) ([Gruntfile](https://github.com/theintern/intern-examples/blob/master/grunt-example/Gruntfile.js)) 74 | 75 | ### [Phaser](http://phaser.io/) 76 | * [phaser](https://github.com/photonstorm/phaser/) ([Gruntfile](https://github.com/photonstorm/phaser/blob/master/Gruntfile.js)) 77 | 78 | ### [BufferApp](https://bufferapp.com) 79 | 80 | ### [Shopetti](https://www.shopetti.com) 81 | 82 | ### [Consunet Pty Ltd](https://www.consunet.com.au) 83 | * [WhisperNote](https://www.consunet.com.au/products/whispernote/) - ([Gruntfile](https://github.com/Consunet/Apps/blob/master/WhisperNote/Gruntfile.js)) 84 | * [EveryPass](https://www.consunet.com.au/products/everypass/) - ([Gruntfile](https://github.com/Consunet/Apps/blob/master/EveryPass/Gruntfile.js)) 85 | 86 | ### [Assemble](http://assemble.io/) 87 | * [Gruntfile](https://github.com/assemble/assemble/blob/master/Gruntfile.js) 88 | 89 | ### [Sourcey](http://sourcey.com) 90 | * [Mesh](https://github.com/sourcey/mesh) ([Gruntfile](https://github.com/sourcey/mesh/blob/master/Gruntfile.js)) 91 | * [Symple](https://github.com/sourcey/symple) ([Gruntfile](https://github.com/sourcey/symple/blob/master/client/Gruntfile.js)) 92 | 93 | ### [Happy Cog](http://happycog.com) 94 | 95 | ### [Hitori Inc.](http://hitori-inc.com) 96 | 97 | ### [MadGlory](http://madglory.com) 98 | 99 | ### [Victoria's Secret](http://www.victoriassecret.com) 100 | 101 | ### [Clevertim CRM](http://www.clevertim.com) 102 | 103 | ### [Olapic](http://www.olapic.com) 104 | 105 | ### [Kickoff](http://tmwagency.github.io/kickoff/) 106 | * [Gruntfile](https://github.com/tmwagency/kickoff/blob/master/Gruntfile.js) 107 | 108 | ### [Vodori](http://vodori.com) 109 | 110 | ### [Jimdo](http://www.jimdo.com/) 111 | * [angular-spectrum-colorpicker](https://github.com/Jimdo/angular-spectrum-colorpicker) ([Gruntfile](https://github.com/Jimdo/angular-spectrum-colorpicker/blob/master/Gruntfile.js)) 112 | * [angular-directive-seed](https://github.com/Jimdo/angular-directive-seed) ([Gruntfile](https://github.com/Jimdo/angular-directive-seed/blob/master/Gruntfile.js)) 113 | 114 | ### [Crowdfunder.co.uk](http://www.crowdfunder.co.uk/) 115 | 116 | ### [Microsoft](http://www.microsoft.com/) 117 | * [Visual Studio 2015](http://visualstudio.com/free) has native support for Grunt 118 | * [Visual Studio 2013](http://visualstudio.com/free/) has Grunt support using the free [Task Runner Explorer](https://visualstudiogallery.msdn.microsoft.com/8e1b4368-4afb-467a-bc13-9650572db708) extension 119 | 120 | ### [Spring Source](http://spring.io) 121 | * [Spring XD](http://projects.spring.io/spring-xd/) uses grunt for managing its UI module dependencies 122 | ([Gruntfile](https://github.com/spring-projects/spring-xd/blob/9a2520622dc2e88ee8893d1df618d40281dacabf/spring-xd-ui/Gruntfile.js)) 123 | 124 | ### [Wire](https://www.wire.com/) 125 | * [Wire for Web](https://app.wire.com/) 126 | -------------------------------------------------------------------------------- /blog/Blog-2013-02-15-Updating-plugins-to-Grunt-0.4.md: -------------------------------------------------------------------------------- 1 | If your plugin is not already Grunt 0.4 compatible, would you please consider updating it? For an overview of what's changed, please see our [migration guide](https://github.com/gruntjs/grunt/wiki/Upgrading-from-0.3-to-0.4). 2 | 3 | If you'd like to develop against the final version of Grunt before Monday, please specify `"grunt": "0.4.0rc8"` as a devDependency in your project. After Monday's release, you'll be able to use `"grunt": "~0.4.0"` to actually publish your plugin. If you depend on any plugins from the grunt-contrib series, please see our [list of release candidates](https://github.com/gruntjs/grunt/wiki/Plugin-Release-Candidate-Versions) for compatible versions. All of these will be updated to final status when Grunt 0.4 is published. 4 | 5 | Also, in an effort to reduce duplication of effort and fragmentation in the developer community, could you review the [grunt-contrib](https://github.com/gruntjs) series of plugins to see if any of your functionality overlaps significantly with them? Grunt-contrib is community maintained with 40+ contributors—we'd love to discuss any additions you'd like to make. 6 | 7 | Finally, we're working on a new task format that doesn't depend on Grunt: it's called [node-task](https://github.com/tkellen/node-task). Once this is complete, there will be one more conversion, and then we'll never ask you to upgrade your plugins to support our changes again. Until that happens, thanks for bearing with us! 8 | 9 | If you have any questions about how to proceed, please respond here, or join us in `#grunt on irc.freenode.net`. 10 | 11 | Thanks, we really appreciate your work! 12 | -------------------------------------------------------------------------------- /blog/Blog-2013-02-18-Grunt-0.4.0-released.md: -------------------------------------------------------------------------------- 1 | As of this morning, Grunt v0.4 final is available on npm! For a lengthy writeup on the release, please see [@tkellen's](http://goingslowly.com) article [on the Bocoup blog](http://weblog.bocoup.com/tearing-grunt-apart/). 2 | 3 | ### The Biggest Stuff 4 | 5 | 1. Grunt no longer ships with built in tasks. They've been extracted into officially maintained, standalone plugins under the grunt-contrib namespace. See the [plugin listing](https://gruntjs.com/plugins) on our website for more details. 6 | 2. Grunt no longer ships with a binary. In order to get the `grunt` command, install [grunt-cli](https://github.com/gruntjs/grunt-cli) globally with `npm install -g grunt-cli`. This package will run any version of Grunt (including 0.3x) after it's been installed locally to your project. 7 | 8 | ### The Future 9 | 10 | Grunt v0.5 will ship with support for a new plugin format called [node-task](https://github.com/tkellen/node-task). It defines a stateless, promise-based, event emitting API that doesn't depend on Grunt. It has a real-live spec, and the Grunt team is working with the front-end developer community in the hopes that compliant modules will be compatible with every task runner under the sun. 11 | 12 | ### Grunt on 13 | If you'd like to know more about Grunt, please read our [Getting Started Guide](https://gruntjs.com/getting-started), and check out all of the ways you can [configure your tasks](https://gruntjs.com/configuring-tasks), too. 14 | -------------------------------------------------------------------------------- /blog/Blog-2013-03-13-Grunt-0.4.1-released.md: -------------------------------------------------------------------------------- 1 | Grunt 0.4.1 is now available from [npm](https://www.npmjs.org/package/grunt). 2 | 3 | This patch release fixes a number of minor issues that cropped up with the recent release of [Node.js v0.10.0](http://blog.nodejs.org/2013/03/11/node-v0-10-0-stable/), most notably due to changes in the [path](https://nodejs.org/api/path.html) API. If you want to use the latest version of Node.js in your projects, you should probably update Grunt to `~0.4.1` in the [package.json](https://gruntjs.com/getting-started#package.json) file for those projects. 4 | 5 | Either way, Grunt still works with Node.js v0.8.x, so you don't *need* to update if you haven't upgraded to Node.js v0.10.0. 6 | 7 | In addition to the Node.js v0.10.0 changes, we used this opportunity to fix a number of other small issues, like properly handling multibyte I/O when spawning child processes and ensuring the [Gruntfile](https://gruntjs.com/getting-started#the-gruntfile) name is case-insensitive. For a complete list of changes, see the [v0.4.0 - v0.4.1 changelog](https://github.com/gruntjs/grunt/compare/v0.4.0...v0.4.1). 8 | -------------------------------------------------------------------------------- /blog/Blog-2013-11-21-Grunt-0.4.2-released.md: -------------------------------------------------------------------------------- 1 | Grunt 0.4.2 is now available on [npm](https://www.npmjs.org/package/grunt). 2 | 3 | This release should address a lot of issues for Windows developers, such as pipe-redirection, console output and BOM preservation. 4 | 5 | Besides a number of bug fixes, we have made a few decisions going forward regarding external dependencies in Grunt. **These external libraries are deprecated and should now be required as npm modules:** 6 | 7 | * Use [glob](https://www.npmjs.org/package/glob) instead of `grunt.file.glob` 8 | * Use [minimatch](https://www.npmjs.org/package/minimatch) instead of `grunt.file.minimatch` 9 | * Use [findup](https://www.npmjs.org/package/findup) instead of `grunt.file.findup` 10 | * Use [lodash](https://www.npmjs.org/package/lodash) instead of `grunt.util._` 11 | * Use [underscore.string](https://www.npmjs.org/package/underscore.string) instead of `grunt.util._.str` 12 | * Use [hooker](https://www.npmjs.org/package/hooker) instead of `grunt.util.hooker` 13 | * Use [async](https://www.npmjs.org/package/async) instead of `grunt.util.async` 14 | * Use [getobject](https://github.com/cowboy/node-getobject) instead of `grunt.util.namespace` 15 | 16 | If you want to use these external libraries in your tasks, please install them as you would [Grunt or any Grunt plugin](https://gruntjs.com/getting-started#installing-grunt-and-gruntplugins) using `npm install --save-dev`. For example, if you used `grunt.util._` before, you'll now require [Lo-Dash](http://lodash.com/) instead with `npm install lodash --save-dev`. 17 | 18 | ```js 19 | // Then change this code: 20 | var newArr = grunt.util._.map(arr, fn); 21 | 22 | // To this: 23 | var _ = require('lodash'); 24 | var newArr = _.map(arr, fn); 25 | ``` 26 | 27 | The team is also looking for feedback about the future of Grunt, so if you have time, please join the 0.5.0 milestone 28 | [discussions](https://github.com/gruntjs/grunt/issues?direction=desc&milestone=7&page=1&sort=updated&state=open). 29 | 30 | See the 0.4.2 changelog [here](https://github.com/gruntjs/grunt/blob/v0.4.2/CHANGELOG). 31 | 32 | **Happy Grunting!** 33 | -------------------------------------------------------------------------------- /blog/Blog-2014-03-07-Grunt-0.4.3-released.md: -------------------------------------------------------------------------------- 1 | Grunt 0.4.3 is now available on [npm](https://www.npmjs.org/package/grunt). 2 | 3 | This is mostly a bugfix release. Thanks to [Jonathan Krause](https://github.com/jonykrause), 4 | [PatrickJS](https://github.com/gdi2290), [Jason Cust](https://github.com/GlobalDomestic), 5 | [Fabio Crisci](https://github.com/piuccio), [James M. Greene](https://github.com/JamesMGreene) 6 | and [Mike Pennisi](https://github.com/jugglinmike) for their pull requests. 7 | 8 | In addition to closing over 30 issues, we have extracted `grunt.util` into 9 | [its own module](https://github.com/gruntjs/grunt-legacy-util). As mentioned 10 | in the [0.4.2](https://gruntjs.com/blog/2013-11-21-grunt-0.4.2-released) release, 11 | we are in process of deprecating the `grunt.util.*` API. Task developers who use 12 | these APIs should update their plugins to use the libraries recommended in 13 | the [grunt-legacy-util](https://github.com/gruntjs/grunt-legacy-util) README. 14 | You may use `grunt-legacy-util` directly as a stopgap, but we will no longer be supporting it. 15 | 16 | For a full list of changes, see the 0.4.3 changelog [here](https://github.com/gruntjs/grunt/blob/v0.4.3/CHANGELOG). 17 | 18 | **Happy Grunting!** 19 | -------------------------------------------------------------------------------- /blog/Blog-2014-03-14-Grunt-0.4.4-released.md: -------------------------------------------------------------------------------- 1 | Grunt 0.4.4 is now available on [npm](https://www.npmjs.org/package/grunt). 2 | 3 | This release fixes a [regression](https://github.com/gruntjs/grunt/pull/1026) that was introduced in version 0.4.3. 4 | 5 | See the changelog [here](https://github.com/gruntjs/grunt/blob/v0.4.4/CHANGELOG). 6 | -------------------------------------------------------------------------------- /blog/Blog-2014-05-12-Grunt-0.4.5-released.md: -------------------------------------------------------------------------------- 1 | Grunt 0.4.5 is now available on [npm](https://www.npmjs.org/package/grunt). 2 | 3 | Thanks to [Gary Burgess](https://github.com/garyb), [James Smith](https://github.com/jmeas) and [Carlos Mantilla](https://github.com/ceoaliongroo) for their patches. Also, thanks to [Vlad Filippov](https://github.com/vladikoff) for helping triage issues, troubleshooting Windows CI testing and putting together the changelog. 4 | 5 | In this release, we closed around a dozen issues, added the much-requested [grunt.task.exists](https://gruntjs.com/api/grunt.task#grunt.task.exists) and [grunt.config.merge](https://gruntjs.com/api/grunt.config#grunt.config.merge) methods, and set up Windows CI testing through [AppVeyor](http://www.appveyor.com/). Additionally, the logging API has been broken out into a separate module, [grunt-legacy-log](https://github.com/gruntjs/grunt-legacy-log), in order to facilitate maintenance. 6 | 7 | For a full list of changes, see the [0.4.5 changelog](https://github.com/gruntjs/grunt/blob/v0.4.5/CHANGELOG). 8 | 9 | Additionally, we have accepted a number of patches for [Grunt contrib plugins](https://gruntjs.com/plugins/contrib) and would like to thank [Kevin Mårtensson](https://github.com/kevva), [Alexander Futekov](https://github.com/futekov), [Shinnosuke Watanabe](https://github.com/shinnn), [Shane Daniel](https://github.com/simshanith), [Artem Sapegin](https://github.com/sapegin), [Christoph Pojer](https://github.com/cpojer), [Zhang Yichao](https://github.com/echaozh), [Jevon Wright](https://github.com/soundasleep), [Jacob Lauritzen](https://github.com/Jacse), [XhmikosR](https://github.com/XhmikosR) and [Edan Schwartz](https://github.com/eschwartz) for their contributions. 10 | 11 | **Happy Grunting!** 12 | -------------------------------------------------------------------------------- /blog/Blog-2016-02-11-Grunt-1.0.0-rc1-released.md: -------------------------------------------------------------------------------- 1 | **The Grunt team is pleased to announce the first release candidate for `1.0.0`.** 2 | 3 | This release is made possible by [@shama](https://github.com/shama), [@vladikoff](https://github.com/vladikoff), [@jkaussieskater](https://github.com/jkaussieskater). With support from the jQuery foundation, in particular [@dmethvin](https://github.com/dmethvin) and [@aulvi](https://github.com/aulvi). 4 | 5 | Also thanks to contributions by [@XhmikosR](https://github.com/XhmikosR), [@paladox](https://github.com/paladox), [@FredyC](https://github.com/FredyC), [@sindresorhus](https://github.com/sindresorhus), [@mrjoelkemp](https://github.com/mrjoelkemp) and more. 6 | 7 | This release focuses on fixing critical issues and improved support with Node.js 8 | v0.10, v0.12, v4.0, v5.0 and io.js on Windows, OSX and Linux. We ask you to test the `rc1` and [report any issues](https://github.com/gruntjs/grunt/issues) you are experiencing. 9 | 10 | > npm install grunt@1.0.0-rc1 --save-dev 11 | 12 | Be advised Grunt `1.0.0` will no longer support Node.js v0.8. 13 | 14 | ## Peer Dependencies 15 | If you have a Grunt plugin that includes `grunt` in the `peerDependencies` section of your `package.json`, we recommend tagging with `"grunt": ">=0.4.0"`. Otherwise when `grunt@1.0.0` is released, npm@2 users will receive a hard error when trying to install your plugin and npm@3 users will get a warning. 16 | 17 | Be aware, peer dependencies are no longer installed for users as of npm@3. Users of Grunt plugins are expected to `npm install grunt --save-dev` alongside any Grunt plugin install. 18 | 19 | **We ask you to send pull requests to your favourite plugins and ask them to update the `peerDependencies` section of their `package.json`.** 20 | 21 | ## Request For Comments 22 | We have created an [new repo](https://github.com/gruntjs/rfcs) to encourage 23 | members of the community interested in shaping the future of Grunt to submit a 24 | RFC. 25 | 26 | Submitting an RFC will allow you to formally propose a significant change to 27 | Grunt and elicit feedback from the core team and community. 28 | 29 | The active proposals will help portray the future roadmap for Grunt and hopefully 30 | expedite community contributions into future Grunt releases. 31 | 32 | ## npm scripts 33 | We now install `grunt-cli` as part of `grunt`. Many users do not wish to perform 34 | the extra step of `npm install grunt-cli -g`. To better conform to the idioms 35 | of Node.js, you can now `npm install grunt --save-dev` then include Grunt in your 36 | npm scripts: 37 | 38 | ```json 39 | { 40 | "scripts": { 41 | "grunt": "grunt" 42 | } 43 | } 44 | ``` 45 | 46 | Your users now only have to `npm install` and `npm run grunt` to run your 47 | `Gruntfile.js`. 48 | 49 | Users on `npm >= 2.0.0` can also pass tasks and options with: 50 | `npm run grunt -- task --option=foo` which is equivalent to 51 | `grunt task --option=foo`. 52 | 53 | If you would like the `grunt` command on your computer, please continue to 54 | `npm install grunt-cli -g` and use as before. 55 | 56 | ## API Changes 57 | Be aware, some APIs have changed warranting a major version update: 58 | 59 | * `coffee-script` is upgraded to `~1.10.0` which could incur breaking changes 60 | when using the language with plugins and Gruntfiles. 61 | * `nopt` is upgraded to `~3.0.6` which has fixed many issues, including passing 62 | multiple arguments and dealing with numbers as options. Be aware previously 63 | `--foo bar` used to pass the value `'bar'` to the option `foo`. It will now 64 | set the option `foo` to `true` and run the task `bar`. 65 | * `glob` is upgraded to `~6.0.4` and `minimatch` is upgraded to `~3.0.0`. Results 66 | are now sorted by default with `grunt.file.expandMapping()`. Pass the 67 | `nosort: true` option if you don't want the results to be sorted. 68 | * `lodash` was upgraded to `~4.3.0`. Many changes have occurred. Some of which 69 | that directly affect Grunt are `grunt.util._.template()` returns a compile 70 | function and `grunt.util._.flatten` no longer flattens deeply. 71 | `grunt.util._` is deprecated and we highly encourage you to 72 | `npm install lodash` and `var _ = require('lodash')` to use `lodash`. 73 | Please see the lodash changelog for a full list of changes: 74 | * `iconv-lite` is upgraded to `~0.4.13` and strips the BOM by default. 75 | * `js-yaml` is upgraded to `~3.5.2` and may affect `grunt.file.readYAML`. 76 | We encourage you to please `npm install js-yaml` and use 77 | `var YAML = require('js-yaml')` directly in case of future deprecations. 78 | * A file `mode` option can be passed into 79 | [grunt.file.write()](https://gruntjs.com/api/grunt.file#grunt.file.write). 80 | * `Done, without errors.` was changed to `Done.` to avoid failing by mistake on the word `errors`. 81 | 82 | We encourage you to try out this release. 83 | 84 | We are also looking for contributors to all [Grunt repositories](https://github.com/gruntjs/) and are willing to mentor you to get more experience with open source. 85 | -------------------------------------------------------------------------------- /blog/Blog-2016-04-04-Grunt-1.0.0-released.md: -------------------------------------------------------------------------------- 1 | The Grunt team is pleased to announce the release Grunt `1.0.0`. 2 | 3 | This release is made possible by [@shama](https://github.com/shama), [@vladikoff](https://github.com/vladikoff), [@jkaussieskater](https://github.com/jkaussieskater), [@dmethvin](https://github.com/dmethvin). 4 | 5 | Also thanks to contributions by [@XhmikosR](https://github.com/XhmikosR), [@AurelioDeRosa](https://github.com/AurelioDeRosa), [@Arkni](https://github.com/Arkni), [@arithmetric](https://github.com/arithmetric), [@ascripcaru](https://github.com/ascripcaru). 6 | 7 | **Be advised Grunt `1.0.0` will no longer support Node.js v0.8.** 8 | 9 | We ask you to test this release and [report any issues](https://github.com/gruntjs/grunt/issues) you are experiencing. 10 | 11 | Update to Grunt 1.0.0 today using: 12 | 13 | > npm install grunt@1.0.0 --save-dev 14 | 15 | **[Please read the RC1 blog post](https://gruntjs.com/blog/2016-02-11-grunt-1.0.0-rc1-released) for more details about changes to Grunt with version 1.0.** 16 | 17 | ## Peer Dependencies 18 | If you have a Grunt plugin that includes `grunt` in the `peerDependencies` section of your `package.json`, we recommend tagging with `"grunt": ">=0.4.0"`. 19 | Otherwise for npm@2 users `grunt@1.0.0` will receive a hard error when trying to install your plugin and npm@3 users will get a warning. 20 | We have sent over two thousand pull requests to existing plugins to make this change. 21 | 22 | **We ask you to send pull requests to your favourite plugins and ask them to update the `peerDependencies` section of their `package.json`.** 23 | 24 | ## Changes in 1.0.0 25 | 26 | * Prevent async callback from being called multiple times. Pull #1464. 27 | * Update copyright to jQuery Foundation and remove redundant headers. Fixes #1478. 28 | * Update glob to 7.0.x. Fixes #1467. 29 | * Removing duplicate BOM strip code. Pull #1482. 30 | * Updated to latest cli ~1.2.0 31 | * Ensure a grunt bin gets created upon install. 32 | 33 | ### Changes in RC1 34 | 35 | * `coffee-script` is upgraded to `~1.10.0` which could incur breaking changes 36 | when using the language with plugins and Gruntfiles. 37 | * `nopt` is upgraded to `~3.0.6` which has fixed many issues, including passing 38 | multiple arguments and dealing with numbers as options. Be aware previously 39 | `--foo bar` used to pass the value `'bar'` to the option `foo`. It will now 40 | set the option `foo` to `true` and run the task `bar`. 41 | * `glob` is upgraded to `~6.0.4` and `minimatch` is upgraded to `~3.0.0`. Results 42 | are now sorted by default with `grunt.file.expandMapping()`. Pass the 43 | `nosort: true` option if you don't want the results to be sorted. 44 | * `lodash` was upgraded to `~4.3.0`. Many changes have occurred. Some of which 45 | that directly effect Grunt are `grunt.util._.template()` returns a compile 46 | function and `grunt.util._.flatten` no longer flattens deeply. 47 | `grunt.util._` is deprecated and we highly encourage you to 48 | `npm install lodash` and `var _ = require('lodash')` to use `lodash`. 49 | Please see the lodash changelog for a full list of changes: 50 | * `iconv-lite` is upgraded to `~0.4.13` and strips the BOM by default. 51 | * `js-yaml` is upgraded to `~3.5.2` and may affect `grunt.file.readYAML`. 52 | We encourage you to please `npm install js-yaml` and use 53 | `var YAML = require('js-yaml')` directly in case of future deprecations. 54 | * A file `mode` option can be passed into 55 | [grunt.file.write()](https://gruntjs.com/api/grunt.file#grunt.file.write). 56 | * `Done, without errors.` was changed to `Done.` to avoid failing by mistake on the word `errors`. 57 | 58 | As we mentioned before, we are also looking for contributors to all [Grunt repositories](https://github.com/gruntjs/) and are willing to mentor you to get more experience with open source. 59 | -------------------------------------------------------------------------------- /blog/Blog-2018-08-15-Grunt-CLI-1.3.0-released.md: -------------------------------------------------------------------------------- 1 | The Grunt team is pleased to announce the release Grunt CLI `1.3.0`. 2 | 3 | > npm install grunt-cli -g 4 | 5 | This release is made possible by [@shama](https://github.com/shama), [@vladikoff](https://github.com/vladikoff), [@Arkni](https://github.com/Arkni), [@phated](https://github.com/phated), and all the [Liftoff contributors](https://github.com/js-cli/js-liftoff/graphs/contributors). 6 | 7 | --- 8 | 9 | This release is significant as it allows you to now write your Gruntfile in your 10 | preferred language. Previously Gruntfiles, by default, could only be wrote in 11 | either JavaScript or CoffeeScript. 12 | 13 | With `>= 1.3.0`, if you would like to write your Gruntfile in [TypeScript](https://www.typescriptlang.org/), 14 | rename your Gruntfile to end with the appropriate extension: `Gruntfile.ts` 15 | and install the appropriate interpreter, `npm install typescript`. 16 | 17 | Running the command `grunt` will now interpret the Gruntfile accordingly. 18 | 19 | Another example, if you would like to write your Gruntfile using [Babel](https://babeljs.io/), 20 | rename your Gruntfile to `Gruntfile.babel.js` and `npm install babel`. 21 | 22 | By default, the Grunt CLI can interpret a number of popular file extensions thanks 23 | to [interpret](https://www.npmjs.com/package/interpret), including: 24 | 25 | * `Gruntfile.babel.js` -> `npm install babel` 26 | * `Gruntfile.buble.js` -> `npm install buble` 27 | * `Gruntfile.coffee` -> `npm install coffeescript` 28 | * `Gruntfile.coffee.md` -> `npm install coffeescript` 29 | * `Gruntfile.csv` -> `npm install require-csv` 30 | * `Gruntfile.ini` -> `npm install require-ini` 31 | * `Gruntfile.json` 32 | * `Gruntfile.ls` -> `npm install livescript` 33 | * `Gruntfile.ts` -> `npm install typescript` 34 | * `Gruntfile.yaml` -> `npm install require-yaml` 35 | 36 | If the Grunt CLI doesn't support your preferred language, you can add support by 37 | using the `--require` option: 38 | 39 | > grunt --require myscript/register 40 | 41 | Then Grunt will require your custom module to interpret the Gruntfile. 42 | 43 | This is all possible as the Grunt CLI now runs using [Liftoff](https://www.npmjs.com/package/liftoff). 44 | 45 | ## CoffeeScript 46 | 47 | Previously Gruntfiles could be wrote by default in CoffeeScript. That version of 48 | CoffeeScript has been and will be locked to `~1.10.0`. 49 | 50 | Relying on your `Gruntfile.coffee` file to be automatically interpreted is now deprecated. 51 | 52 | If your Gruntfile is wrote in CoffeeScript, please additionally run 53 | `npm install coffeescript --save-dev`. This will allow you to use your preferred 54 | version of CoffeeScript and not be locked to the version installed with Grunt. 55 | In the next major version release of Grunt, the CoffeeScript dependency will be 56 | removed and it will be required to additionally `npm install coffeescript` to 57 | write your Gruntfiles in CoffeeScript. 58 | -------------------------------------------------------------------------------- /blog/Blog-2020-03-16-Grunt-1.1.0-released.md: -------------------------------------------------------------------------------- 1 | The Grunt team is pleased to announce the release of Grunt `1.1.0`. 2 | 3 | This release is made possible by [@vladikoff](https://github.com/vladikoff) and [@shama](https://github.com/shama). 4 | 5 | --- 6 | 7 | Here are the changes: 8 | 9 | * Update to mkdirp ~1.0.3 10 | * Only support versions of Node >= 8 11 | 12 | You can find Grunt on [npm](https://www.npmjs.com/package/grunt) and [GitHub](https://github.com/gruntjs/grunt). 13 | -------------------------------------------------------------------------------- /blog/Blog-2020-07-03-Grunt-1.2.0-released.md: -------------------------------------------------------------------------------- 1 | The Grunt team is pleased to announce the release of Grunt `1.2.0`. 2 | 3 | This release is made possible by [@vladikoff](https://github.com/vladikoff) and contributors: 4 | 5 | * philz - https://github.com/philz 6 | * Brian Lim - https://github.com/bhldev 7 | * micellius - https://github.com/micellius 8 | 9 | and more! 10 | 11 | --- 12 | 13 | Here are the changes: 14 | 15 | * Allow usage of grunt plugins that are located in any location that 16 | is visible to Node.js and NPM, instead of node_modules directly 17 | inside package that have a dev dependency to these plugins. 18 | (PR: https://github.com/gruntjs/grunt/pull/1677) 19 | * Removed coffeescript from dependencies. To ease transition, if 20 | coffeescript is still around, Grunt will attempt to load it. 21 | If it is not, and the user loads a CoffeeScript file, 22 | Grunt will print a useful error indicating that the 23 | coffeescript package should be installed as a dev dependency. 24 | This is considerably more user-friendly than dropping the require entirely, 25 | but doing so is feasible with the latest grunt-cli as users 26 | may simply use grunt --require coffeescript/register. 27 | (PR: https://github.com/gruntjs/grunt/pull/1675) 28 | * Exposes Grunt Option keys for ease of use. 29 | (PR: https://github.com/gruntjs/grunt/pull/1570) 30 | * Avoiding infinite loop on very long command names. 31 | (PR: https://github.com/gruntjs/grunt/pull/1697) 32 | * Dependency updates are also included. 33 | 34 | You can find Grunt on [npm](https://www.npmjs.com/package/grunt) and [GitHub](https://github.com/gruntjs/grunt). 35 | -------------------------------------------------------------------------------- /blog/Blog-2021-04-22-Grunt-1.4.0-released.md: -------------------------------------------------------------------------------- 1 | The Grunt team is pleased to announce the release of Grunt `1.4.0`. 2 | 3 | This release is made possible by [@vladikoff](https://github.com/vladikoff) and contributors: 4 | 5 | * [@XhmikosR](https://github.com/XhmikosR) 6 | 7 | and more! 8 | 9 | --- 10 | 11 | Here are the changes: 12 | 13 | * Security fixes in production and dev dependencies 14 | * Liftup/Liftoff upgrade breaking change. Update your scripts to use --preload instead of --require. Ref: https://github.com/js-cli/js-liftoff/commit/e7a969d6706e730d90abb4e24d3cb4d3bce06ddb. 15 | 16 | You can find Grunt on [npm](https://www.npmjs.com/package/grunt) and [GitHub](https://github.com/gruntjs/grunt). 17 | -------------------------------------------------------------------------------- /grunt.config.md: -------------------------------------------------------------------------------- 1 | Access project-specific configuration data defined in the `Gruntfile`. 2 | 3 | Note that any method marked with a ☃ (unicode snowman) is also available directly on the `grunt` object, and any method marked with a ☆ (white star) is also available inside tasks on the `this` object. Just so you know. 4 | 5 | ## Initializing Config Data 6 | _Note that the following method is also available on the `grunt` object as `grunt.initConfig`._ 7 | 8 | ### grunt.config.init ☃ 9 | Initialize a configuration object for the current project. The specified `configObject` is used by tasks and can be accessed using the `grunt.config` method. Nearly every project's `Gruntfile` will call this method. 10 | 11 | ```js 12 | grunt.config.init(configObject) 13 | ``` 14 | 15 | Note that any specified `<% %>` template strings will be processed when config data is retrieved. 16 | 17 | This example contains sample config data for the [grunt-contrib-jshint plugin](https://github.com/gruntjs/grunt-contrib-jshint) `jshint` task: 18 | 19 | ```js 20 | grunt.config.init({ 21 | jshint: { 22 | all: ['lib/*.js', 'test/*.js', 'Gruntfile.js'] 23 | } 24 | }); 25 | ``` 26 | 27 | See the [[Getting started]] guide for more configuration examples. 28 | 29 | _This method is also available as `grunt.initConfig`._ 30 | 31 | 32 | ## Accessing Config Data 33 | The following methods allow Grunt configuration data to be accessed either via dot-delimited string like `'pkg.author.name'` or via array of property name parts like `['pkg', 'author', 'name']`. 34 | 35 | Note that if a specified property name contains a `.` dot, it must be escaped with a literal backslash, eg. `'concat.dist/built\\.js'`. If an array of parts is specified, Grunt will handle the escaping internally with the `grunt.config.escape` method. 36 | 37 | ### grunt.config 38 | Get or set a value from the project's Grunt configuration. This method serves as an alias to other methods; if two arguments are passed, `grunt.config.set` is called, otherwise `grunt.config.get` is called. 39 | 40 | ```js 41 | grunt.config([prop [, value]]) 42 | ``` 43 | 44 | ### grunt.config.get 45 | Get a value from the project's Grunt configuration. If `prop` is specified, that property's value is returned, or `null` if that property is not defined. If `prop` isn't specified, a copy of the entire config object is returned. Templates strings will be recursively processed using the `grunt.config.process` method. 46 | 47 | ```js 48 | grunt.config.get([prop]) 49 | ``` 50 | 51 | ### grunt.config.process 52 | Process a value, recursively expanding `<% %>` templates (via the `grunt.template.process` method) in the context of the Grunt config, as they are encountered. this method is called automatically by `grunt.config.get` but _not_ by `grunt.config.getRaw`. 53 | 54 | ```js 55 | grunt.config.process(value) 56 | ``` 57 | 58 | If any retrieved value is entirely a single `'<%= foo %>'` or `'<%= foo.bar %>'` template string, and the specified `foo` or `foo.bar` property is a non-string (and not `null` or `undefined`) value, it will be expanded to the _actual_ value. That, combined with grunt's task system automatically flattening arrays, can be extremely useful. 59 | 60 | ### grunt.config.getRaw 61 | Get a raw value from the project's Grunt configuration, without processing `<% %>` template strings. If `prop` is specified, that property's value is returned, or `null` if that property is not defined. If `prop` isn't specified, a copy of the entire config object is returned. 62 | 63 | ```js 64 | grunt.config.getRaw([prop]) 65 | ``` 66 | 67 | ### grunt.config.set 68 | Set a value into the project's Grunt configuration. 69 | 70 | ```js 71 | grunt.config.set(prop, value) 72 | ``` 73 | 74 | Note that any specified `<% %>` template strings will only be processed when config data is retrieved. 75 | 76 | ### grunt.config.escape 77 | Escape `.` dots in the given `propString`. This should be used for property names that contain dots. 78 | 79 | ```js 80 | grunt.config.escape(propString) 81 | ``` 82 | 83 | ### grunt.config.merge 84 | *Added in 0.4.5* 85 | 86 | Recursively merges properties of the specified `configObject` into the current project configuration. Array and plain object properties are merged recursively while other value types are overridden. 87 | 88 | ```js 89 | grunt.config.merge(configObject) 90 | ``` 91 | 92 | You can use this method to append configuration options, targets, etc., to already defined tasks, for example: 93 | 94 | ```js 95 | grunt.config.merge({ 96 | watch: { 97 | files: ["path/to/files"], 98 | tasks: ["task"] 99 | } 100 | }); 101 | ``` 102 | 103 | Array values are merged based on their index. Consider the following code: 104 | 105 | ```js 106 | grunt.initConfig({ 107 | jshint: { 108 | files: ['Gruntfile.js', 'src/**/*.js'], 109 | } 110 | ); 111 | 112 | var config = { 113 | jshint: { 114 | files: ['hello.js'], 115 | } 116 | }; 117 | 118 | grunt.config.merge(config); 119 | ``` 120 | 121 | It'll result in the configuration shown below: 122 | 123 | ```js 124 | jshint: { 125 | files: ['hello.js', 'src/**/*.js'], 126 | } 127 | ``` 128 | 129 | In conclusion, the first value of the `files` array defined in the `config` variable (`hello.js`) overrides the first value specified in the `initConfig` configuration call (`Gruntfile.js`). 130 | 131 | ## Requiring Config Data 132 | _Note that the method listed below is also available inside tasks on the `this` object as `this.requiresConfig`._ 133 | 134 | ### grunt.config.requires ☆ 135 | Fail the current task if one or more required config properties is missing, `null` or `undefined`. One or more string or array config properties may be specified. 136 | 137 | ```js 138 | grunt.config.requires(prop [, prop [, ...]]) 139 | ``` 140 | 141 | _This method is also available inside tasks as `this.requiresConfig`._ 142 | -------------------------------------------------------------------------------- /grunt.event.md: -------------------------------------------------------------------------------- 1 | Even though only the most relevant methods are listed on this page, the full [EventEmitter2 API][ee2] is available on the `grunt.event` object. Event namespaces may be specified with the `.` (dot) separator, and namespace wildcards have been enabled. 2 | 3 | *Note that Grunt doesn't yet emit any events, but can still be useful in your own tasks.* 4 | 5 | [ee2]: https://github.com/hij1nx/EventEmitter2 6 | 7 | ### grunt.event.on 8 | Adds a listener to the end of the listeners array for the specified event. 9 | 10 | ```js 11 | grunt.event.on(event, listener) 12 | ``` 13 | 14 | ### grunt.event.once 15 | Adds a **one time** listener for the event. The listener is invoked only the first time the event is fired, after which it is removed. 16 | 17 | ```js 18 | grunt.event.once(event, listener) 19 | ``` 20 | 21 | ### grunt.event.many 22 | Adds a listener that will execute **n times** for the event before being removed. 23 | 24 | ```js 25 | grunt.event.many(event, timesToListen, listener) 26 | ``` 27 | 28 | ### grunt.event.off 29 | Remove a listener from the listener array for the specified event. 30 | 31 | ```js 32 | grunt.event.off(event, listener) 33 | ``` 34 | 35 | ### grunt.event.removeAllListeners 36 | Removes all listeners, or those of the specified event. 37 | 38 | ```js 39 | grunt.event.removeAllListeners([event]) 40 | ``` 41 | 42 | ### grunt.event.emit 43 | Execute each of the listeners that may be listening for the specified event name in order with the list of arguments. 44 | 45 | ```js 46 | grunt.event.emit(event, [arg1], [arg2], [...]) 47 | ``` 48 | -------------------------------------------------------------------------------- /grunt.fail.md: -------------------------------------------------------------------------------- 1 | For when something goes horribly wrong. 2 | 3 | See the [fail lib source](https://github.com/gruntjs/grunt/blob/master/lib/grunt/fail.js) for more information. 4 | 5 | ## The fail API 6 | 7 | If something explodes (or is about to explode) inside a task, it can force Grunt to abort. See the [exit codes documentation](Exit-Codes) for a list of all built-in Grunt exit codes. 8 | 9 | Note that any method marked with a ☃ (unicode snowman) is also available directly on the `grunt` object. Just so you know. See the [API main page](grunt) for more usage information. 10 | 11 | ### grunt.fail.warn ☃ 12 | Display a warning and abort Grunt immediately. Grunt will continue processing tasks if the `--force` command-line option was specified. The `error` argument can be a string message or an error object. 13 | 14 | ```js 15 | grunt.fail.warn(error [, errorcode]) 16 | ``` 17 | 18 | If `--stack` is specified on the command-line and an error object was specified, a stack trace will be logged. 19 | 20 | _This method is also available as `grunt.warn`._ 21 | 22 | ### grunt.fail.fatal ☃ 23 | Display a warning and abort Grunt immediately. The `error` argument can be a string message or an error object. 24 | 25 | ```js 26 | grunt.fail.fatal(error [, errorcode]) 27 | ``` 28 | 29 | If `--stack` is specified on the command-line and an error object was specified, a stack trace will be logged. 30 | 31 | A beep is emitted on fatal unless the `--no-color` option is specified. 32 | 33 | _This method is also available as `grunt.fatal`._ 34 | -------------------------------------------------------------------------------- /grunt.file.md: -------------------------------------------------------------------------------- 1 | There are many provided methods for reading and writing files, traversing the filesystem and finding files by matching globbing patterns. Many of these methods are wrappers around built-in Node.js file functionality, but with additional error handling, logging and character encoding normalization. 2 | 3 | _Note: all file paths are relative to the `Gruntfile` unless the current working directory is changed with `grunt.file.setBase` or the `--base` command-line option._ 4 | 5 | ## Character encoding 6 | 7 | ### grunt.file.defaultEncoding 8 | Set this property to change the default encoding used by all `grunt.file` methods. Defaults to `'utf8'`. If you do have to change this value, it's recommended that you change it as early as possible inside your Gruntfile. 9 | 10 | ```js 11 | grunt.file.defaultEncoding = 'utf8'; 12 | ``` 13 | 14 | 15 | ### grunt.file.preserveBOM 16 | *Added in 0.4.2* 17 | 18 | Whether to preserve the Byte Order Mark (BOM) on `file.read` rather than strip it. 19 | 20 | ```js 21 | grunt.file.preserveBOM = false; 22 | ``` 23 | 24 | ## Reading and writing 25 | 26 | ### grunt.file.read 27 | Read and return a file's contents. Returns a string, unless `options.encoding` is `null` in which case it returns a [Buffer](https://nodejs.org/docs/latest/api/buffer.html). 28 | 29 | ```js 30 | grunt.file.read(filepath [, options]) 31 | ``` 32 | 33 | The `options` object has these possible properties: 34 | 35 | ```js 36 | var options = { 37 | // If an encoding is not specified, default to grunt.file.defaultEncoding. 38 | // If specified as null, returns a non-decoded Buffer instead of a string. 39 | encoding: encodingName 40 | }; 41 | ``` 42 | 43 | ### grunt.file.readJSON 44 | Read a file's contents, parsing the data as JSON and returning the result. See `grunt.file.read` for a list of supported options. 45 | 46 | ```js 47 | grunt.file.readJSON(filepath [, options]) 48 | ``` 49 | 50 | ### grunt.file.readYAML 51 | Read a file's contents, parsing the data as YAML and returning the result. See `grunt.file.read` for a list of supported options. 52 | 53 | ```js 54 | grunt.file.readYAML(filepath [, options]) 55 | ``` 56 | 57 | ### grunt.file.write 58 | Write the specified contents to a file, creating intermediate directories if necessary. Strings will be encoded using the specified character encoding, [Buffers](https://nodejs.org/docs/latest/api/buffer.html) will be written to disk as-specified. 59 | 60 | _If the `--no-write` command-line option is specified, the file won't actually be written._ 61 | 62 | ```js 63 | grunt.file.write(filepath, contents [, options]) 64 | ``` 65 | 66 | The `options` object has these possible properties: 67 | 68 | ```js 69 | var options = { 70 | // If an encoding is not specified, default to grunt.file.defaultEncoding. 71 | // If `contents` is a Buffer, encoding is ignored. 72 | encoding: encodingName 73 | }; 74 | ``` 75 | 76 | ### grunt.file.copy 77 | Copy a source file to a destination path, creating intermediate directories if necessary. 78 | 79 | _If the `--no-write` command-line option is specified, the file won't actually be written._ 80 | 81 | ```js 82 | grunt.file.copy(srcpath, destpath [, options]) 83 | ``` 84 | 85 | The `options` object has these possible properties: 86 | 87 | ```js 88 | var options = { 89 | // If an encoding is not specified, default to grunt.file.defaultEncoding. 90 | // If null, the `process` function will receive a Buffer instead of String. 91 | encoding: encodingName, 92 | // The source file contents, source file path, and destination file path 93 | // are passed into this function, whose return value will be used as the 94 | // destination file's contents. If this function returns `false`, the file 95 | // copy will be aborted. 96 | process: processFunction, 97 | // These optional globbing patterns will be matched against the filepath 98 | // (not the filename) using grunt.file.isMatch. If any specified globbing 99 | // pattern matches, the file won't be processed via the `process` function. 100 | // If `true` is specified, processing will be prevented. 101 | noProcess: globbingPatterns 102 | }; 103 | ``` 104 | 105 | ### grunt.file.delete 106 | Delete the specified filepath. Will delete files and folders recursively. 107 | 108 | _Will not delete the current working directory or files outside the current working directory unless the `--force` command-line option is specified._ 109 | 110 | _If the `--no-write` command-line option is specified, the filepath won't actually be deleted._ 111 | 112 | ```js 113 | grunt.file.delete(filepath [, options]) 114 | ``` 115 | 116 | The `options` object has one possible property: 117 | 118 | ```js 119 | var options = { 120 | // Enable deleting outside the current working directory. This option may 121 | // be overridden by the --force command-line option. 122 | force: true 123 | }; 124 | ``` 125 | 126 | ## Directories 127 | 128 | ### grunt.file.mkdir 129 | Works like `mkdir -p`. Create a directory along with any intermediate directories. If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. 130 | 131 | _If the `--no-write` command-line option is specified, directories won't actually be created._ 132 | 133 | ```js 134 | grunt.file.mkdir(dirpath [, mode]) 135 | ``` 136 | 137 | ### grunt.file.recurse 138 | Recurse into a directory, executing `callback` for each file. 139 | 140 | ```js 141 | grunt.file.recurse(rootdir, callback) 142 | ``` 143 | 144 | The callback function receives the following arguments: 145 | 146 | ```js 147 | function callback(abspath, rootdir, subdir, filename) { 148 | // The full path to the current file, which is nothing more than 149 | // the rootdir + subdir + filename arguments, joined. 150 | abspath 151 | // The root director, as originally specified. 152 | rootdir 153 | // The current file's directory, relative to rootdir. 154 | subdir 155 | // The filename of the current file, without any directory parts. 156 | filename 157 | } 158 | ``` 159 | 160 | ## Globbing patterns 161 | It is often impractical to specify all source filepaths individually, so Grunt supports filename expansion (also know as globbing) via the built-in [node-glob](https://github.com/isaacs/node-glob) library. 162 | 163 | See the "Globbing patterns" section of the [[Configuring tasks]] guide for globbing pattern examples. 164 | 165 | 166 | ### grunt.file.expand 167 | Return a unique array of all file or directory paths that match the given globbing pattern(s). This method accepts either comma separated globbing patterns or an array of globbing patterns. Paths matching patterns that begin with `!` will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant. 168 | 169 | ```js 170 | grunt.file.expand([options, ] patterns) 171 | ``` 172 | 173 | File paths are relative to the `Gruntfile` unless the current working directory is changed with `grunt.file.setBase` or the `--base` command-line option. 174 | 175 | The `options` object supports all [minimatch library](https://github.com/isaacs/minimatch) options, and a few others. For example: 176 | 177 | * `filter` Either a valid [fs.Stats method name](https://nodejs.org/docs/latest/api/fs.html#fs_class_fs_stats) or a function that is passed the matched `src` filepath and returns `true` or `false`. 178 | * `nonull` Retain `src` patterns even if they fail to match files. Combined with grunt's `--verbose` flag, this option can help debug file path issues. 179 | * `matchBase` Patterns without slashes will match just the basename part. Eg. this makes `*.js` work like `**/*.js`. 180 | * `cwd` Patterns will be matched relative to this path, and all returned filepaths will also be relative to this path. 181 | 182 | ### grunt.file.expandMapping 183 | Returns an array of src-dest file mapping objects. For each source file matched by a specified pattern, join that file path to the specified `dest`. This file path may be flattened or renamed, depending on the options specified. See the `grunt.file.expand` method documentation for an explanation of how the `patterns` and `options` arguments may be specified. 184 | 185 | ```js 186 | grunt.file.expandMapping(patterns, dest [, options]) 187 | ``` 188 | 189 | _Note that while this method may be used to programmatically generate a `files` array for a multi task, the declarative syntax for doing this described in the "Building the files object dynamically" section of the [[Configuring tasks]] guide is preferred._ 190 | 191 | In addition to those the `grunt.file.expand` method supports, the `options` object also supports these properties: 192 | 193 | ```js 194 | var options = { 195 | // The directory from which patterns are matched. Any string specified as 196 | // cwd is effectively stripped from the beginning of all matched paths. 197 | cwd: String, 198 | // Remove the path component from all matched src files. The src file path 199 | // is still joined to the specified dest. 200 | flatten: Boolean, 201 | // Remove anything after (and including) either the first or last "." in the 202 | // destination path (indicated by options.extDot), then append this value. 203 | ext: String, 204 | // *Added in 0.4.3* 205 | // Indicates where the period demarcating the extension is located. Can take: 206 | // - 'first' (extension begins after the first period in the file name) 207 | // - 'last' (extension begins after the last period) 208 | // Default: 'first' 209 | extDot: String, 210 | // If specified, this function will be responsible for returning the final 211 | // dest filepath. By default, it joins dest and matchedSrcPath like so: 212 | rename: function(dest, matchedSrcPath, options) { 213 | return path.join(dest, matchedSrcPath); 214 | } 215 | }; 216 | ``` 217 | 218 | ### grunt.file.match 219 | Match one or more globbing patterns against one or more file paths. Returns a uniqued array of all file paths that match any of the specified globbing patterns. Both the `patterns` and `filepaths` argument can be a single string or array of strings. Paths matching patterns that begin with `!` will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant. 220 | 221 | ```js 222 | grunt.file.match([options, ] patterns, filepaths) 223 | ``` 224 | 225 | The `options` object supports all [minimatch library](https://github.com/isaacs/minimatch) options. For example, if `options.matchBase` is true, patterns without slashes will match against the basename of the path even if it contains slashes, eg. pattern `*.js` will match filepath `path/to/file.js`. 226 | 227 | ### grunt.file.isMatch 228 | This method contains the same signature and logic as the `grunt.file.match` method, but simply returns `true` if any files were matched, otherwise `false`. 229 | 230 | ## File types 231 | 232 | ### grunt.file.exists 233 | Does the given path exist? Returns a boolean. 234 | 235 | Like the Node.js [path.join](https://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path. 236 | 237 | ```js 238 | grunt.file.exists(path1 [, path2 [, ...]]) 239 | ``` 240 | 241 | ### grunt.file.isLink 242 | Is the given path a symbolic link? Returns a boolean. 243 | 244 | Like the Node.js [path.join](https://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path. 245 | 246 | ```js 247 | grunt.file.isLink(path1 [, path2 [, ...]]) 248 | ``` 249 | 250 | Returns false if the path doesn't exist. 251 | 252 | ### grunt.file.isDir 253 | Is the given path a directory? Returns a boolean. 254 | 255 | Like the Node.js [path.join](https://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path. 256 | 257 | ```js 258 | grunt.file.isDir(path1 [, path2 [, ...]]) 259 | ``` 260 | 261 | Returns false if the path doesn't exist. 262 | 263 | ### grunt.file.isFile 264 | Is the given path a file? Returns a boolean. 265 | 266 | Like the Node.js [path.join](https://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path. 267 | 268 | ```js 269 | grunt.file.isFile(path1 [, path2 [, ...]]) 270 | ``` 271 | 272 | Returns false if the path doesn't exist. 273 | 274 | ## Paths 275 | 276 | ### grunt.file.isPathAbsolute 277 | Is a given file path absolute? Returns a boolean. 278 | 279 | Like the Node.js [path.join](https://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path. 280 | 281 | ```js 282 | grunt.file.isPathAbsolute(path1 [, path2 [, ...]]) 283 | ``` 284 | 285 | ### grunt.file.arePathsEquivalent 286 | Do all the specified paths refer to the same path? Returns a boolean. 287 | 288 | ```js 289 | grunt.file.arePathsEquivalent(path1 [, path2 [, ...]]) 290 | ``` 291 | 292 | ### grunt.file.doesPathContain 293 | Are all descendant path(s) contained within the specified ancestor path? Returns a boolean. 294 | 295 | _Note: does not check to see if paths actually exist._ 296 | 297 | ```js 298 | grunt.file.doesPathContain(ancestorPath, descendantPath1 [, descendantPath2 [, ...]]) 299 | ``` 300 | 301 | ### grunt.file.isPathCwd 302 | Is a given file path the CWD? Returns a boolean. 303 | 304 | Like the Node.js [path.join](https://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path. 305 | 306 | ```js 307 | grunt.file.isPathCwd(path1 [, path2 [, ...]]) 308 | ``` 309 | 310 | ### grunt.file.isPathInCwd 311 | Is a given file path inside the CWD? Note: CWD is not _inside_ CWD. Returns a boolean. 312 | 313 | Like the Node.js [path.join](https://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path. 314 | 315 | ```js 316 | grunt.file.isPathInCwd(path1 [, path2 [, ...]]) 317 | ``` 318 | 319 | ### grunt.file.setBase 320 | Change grunt's current working directory (CWD). By default, all file paths are relative to the `Gruntfile`. This works just like the `--base` command-line option. 321 | 322 | ```js 323 | grunt.file.setBase(path1 [, path2 [, ...]]) 324 | ``` 325 | 326 | Like the Node.js [path.join](https://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path. 327 | 328 | ## External libraries 329 | *Deprecated* 330 | 331 | __All external libraries that are listed below are now deprecated.__ 332 | 333 | Please use __npm__ to manage these external libraries in your project's dependencies. 334 | 335 | For example if you want use [Lo-Dash](https://www.npmjs.org/package/lodash), install it first `npm install lodash`, then 336 | use it in your `Gruntfile`: `var _ = require('lodash');` 337 | 338 | ### grunt.file.glob 339 | *Deprecated* 340 | 341 | [glob](https://github.com/isaacs/node-glob) - File globbing utility. 342 | 343 | ### grunt.file.minimatch 344 | *Deprecated* 345 | 346 | [minimatch](https://github.com/isaacs/minimatch) - File pattern matching utility. 347 | 348 | ### grunt.file.findup 349 | *Deprecated* 350 | 351 | [findup-sync](https://github.com/cowboy/node-findup-sync) - Search upwards for matching file patterns. 352 | -------------------------------------------------------------------------------- /grunt.log.md: -------------------------------------------------------------------------------- 1 | Output messages to the console. 2 | 3 | See the [log lib source](https://github.com/gruntjs/grunt-legacy-log/blob/master/index.js) for more information. 4 | 5 | ## The log API 6 | Grunt output should look consistent, and maybe even pretty. As such, there is a plethora of logging methods, and a few useful patterns. All of the methods that actually log something are chainable. 7 | 8 | _Note: all methods available under `grunt.verbose` work exactly like `grunt.log` methods, but only log if the `--verbose` command-line option was specified._ 9 | 10 | ### grunt.log.write / grunt.verbose.write 11 | Log the specified `msg` string, with no trailing newline. 12 | 13 | ```js 14 | grunt.log.write(msg) 15 | ``` 16 | 17 | ### grunt.log.writeln / grunt.verbose.writeln 18 | Log the specified `msg` string, with trailing newline. 19 | 20 | ```js 21 | grunt.log.writeln([msg]) 22 | ``` 23 | 24 | ### grunt.log.error / grunt.verbose.error 25 | If `msg` string is omitted, logs `ERROR` in red, otherwise logs `>> msg`, with trailing newline. 26 | 27 | ```js 28 | grunt.log.error([msg]) 29 | ``` 30 | 31 | ### grunt.log.errorlns / grunt.verbose.errorlns 32 | Log an error with `grunt.log.error`, wrapping text to 80 columns using `grunt.log.wraptext`. 33 | 34 | ```js 35 | grunt.log.errorlns(msg) 36 | ``` 37 | 38 | ### grunt.log.ok / grunt.verbose.ok 39 | If `msg` string is omitted, logs `OK` in green, otherwise logs `>> msg`, with trailing newline. 40 | 41 | ```js 42 | grunt.log.ok([msg]) 43 | ``` 44 | 45 | ### grunt.log.oklns / grunt.verbose.oklns 46 | Log an ok message with `grunt.log.ok`, wrapping text to 80 columns using `grunt.log.wraptext`. 47 | 48 | ```js 49 | grunt.log.oklns(msg) 50 | ``` 51 | 52 | ### grunt.log.subhead / grunt.verbose.subhead 53 | Log the specified `msg` string in **bold**, with trailing newline. 54 | 55 | ```js 56 | grunt.log.subhead(msg) 57 | ``` 58 | 59 | ### grunt.log.writeflags / grunt.verbose.writeflags 60 | Log a list of `obj` properties (good for debugging flags). 61 | 62 | ```js 63 | grunt.log.writeflags(obj, prefix) 64 | ``` 65 | 66 | ### grunt.log.debug / grunt.verbose.debug 67 | Logs a debugging message, but only if the `--debug` command-line option was specified. 68 | 69 | ```js 70 | grunt.log.debug(msg) 71 | ``` 72 | 73 | ## Verbose and Notverbose 74 | All logging methods available under `grunt.verbose` work exactly like their `grunt.log` counterparts, but only log if the `--verbose` command-line option was specified. There is also a "notverbose" counterpart available at both `grunt.log.notverbose` and `grunt.log.verbose.or`. In fact, the `.or` property can be used on both `verbose` and `notverbose` to effectively toggle between the two. 75 | 76 | ### grunt.verbose / grunt.log.verbose 77 | This object contains all methods of `grunt.log` but only logs if the `--verbose` command-line option was specified. 78 | 79 | ```js 80 | grunt.verbose 81 | ``` 82 | 83 | ### grunt.verbose.or / grunt.log.notverbose 84 | This object contains all methods of `grunt.log` but only logs if the `--verbose` command-line option was _not_ specified. 85 | 86 | ```js 87 | grunt.verbose.or 88 | ``` 89 | 90 | ## Utility Methods 91 | These methods don't actually log, they just return strings that can be used in other methods. 92 | 93 | ### grunt.log.wordlist 94 | Returns a comma-separated list of `arr` array items. 95 | 96 | ```js 97 | grunt.log.wordlist(arr [, options]) 98 | ``` 99 | 100 | The `options` object has these possible properties, and default values: 101 | 102 | ```js 103 | var options = { 104 | // The separator string (can be colored). 105 | separator: ', ', 106 | // The array item color (specify false to not colorize). 107 | color: 'cyan', 108 | }; 109 | ``` 110 | 111 | ### grunt.log.uncolor 112 | Removes all color information from a string, making it suitable for testing `.length` or perhaps logging to a file. 113 | 114 | ```js 115 | grunt.log.uncolor(str) 116 | ``` 117 | 118 | ### grunt.log.wraptext 119 | Wrap `text` string to `width` characters with `\n`, ensuring that words are not split in the middle unless absolutely necessary. 120 | 121 | ```js 122 | grunt.log.wraptext(width, text) 123 | ``` 124 | 125 | ### grunt.log.table 126 | Wrap `texts` array of strings to columns `widths` characters wide. A wrapper for the `grunt.log.wraptext` method that can be used to generate output in columns. 127 | 128 | ```js 129 | grunt.log.table(widths, texts) 130 | ``` 131 | 132 | ## An Example 133 | 134 | A common pattern is to only log when in `--verbose` mode OR if an error occurs, like so: 135 | 136 | ```js 137 | grunt.registerTask('something', 'Do something interesting.', function(arg) { 138 | var msg = 'Doing something...'; 139 | grunt.verbose.write(msg); 140 | try { 141 | doSomethingThatThrowsAnExceptionOnError(arg); 142 | // Success! 143 | grunt.verbose.ok(); 144 | } catch(e) { 145 | // Something went wrong. 146 | grunt.verbose.or.write(msg).error().error(e.message); 147 | grunt.fail.warn('Something went wrong.'); 148 | } 149 | }); 150 | ``` 151 | 152 | An explanation of the above code: 153 | 154 | 1. `grunt.verbose.write(msg);` logs the message (no newline), but only in `--verbose` mode. 155 | 2. `grunt.verbose.ok();` logs OK in green, with a newline. 156 | 3. `grunt.verbose.or.write(msg).error().error(e.message);` does a few things: 157 | 1. `grunt.verbose.or.write(msg)` logs the message (no newline) if not in `--verbose` mode, and returns the `notverbose` object. 158 | 2. `.error()` logs ERROR in red, with a newline, and returns the `notverbose` object. 159 | 3. `.error(e.message);` logs the actual error message (and returns the `notverbose` object). 160 | 4. `grunt.fail.warn('Something went wrong.');` logs a warning in bright yellow, exiting Grunt with exit code 1, unless `--force` was specified. 161 | 162 | Take a look at the [grunt-contrib-* tasks source code](https://github.com/gruntjs) for more examples. 163 | -------------------------------------------------------------------------------- /grunt.md: -------------------------------------------------------------------------------- 1 | Grunt exposes all of its methods and properties on the `grunt` object that gets passed into the `module.exports` function exported in your [Gruntfile](Getting-started), Grunt plugin or in a [tasks file](Creating-tasks). 2 | 3 | Nearly all of the following methods are defined elsewhere, but are provided directly on the `grunt` object for convenience. See the individual api section docs for detailed explanations and examples. 4 | 5 | ## Config 6 | 7 | ### grunt.initConfig 8 | _This method is an alias for the [grunt.config.init](grunt.config#grunt.config.init) method._ 9 | 10 | 11 | ## Creating Tasks 12 | 13 | ### grunt.registerTask 14 | _This method is an alias for the [grunt.task.registerTask](grunt.task#grunt.task.registerTask) method._ 15 | 16 | ### grunt.registerMultiTask 17 | _This method is an alias for the [grunt.task.registerMultiTask](grunt.task#grunt.task.registerMultiTask) method._ 18 | 19 | ### grunt.renameTask 20 | _This method is an alias for the [grunt.task.renameTask](grunt.task#grunt.task.renameTask) method._ 21 | 22 | ## Loading Externally-Defined Tasks 23 | 24 | ### grunt.loadTasks 25 | _This method is an alias for the [grunt.task.loadTasks](grunt.task#grunt.task.loadTasks) method._ 26 | 27 | ### grunt.loadNpmTasks 28 | _This method is an alias for the [grunt.task.loadNpmTasks](grunt.task#grunt.task.loadNpmTasks) method._ 29 | 30 | 31 | ## Warnings and Fatal Errors 32 | 33 | ### grunt.warn 34 | _This method is an alias for the [grunt.fail.warn](grunt.fail#grunt.fail.warn) method._ 35 | 36 | ### grunt.fatal 37 | _This method is an alias for the [grunt.fail.fatal](grunt.fail#grunt.fail.fatal) method._ 38 | 39 | 40 | ## Command-line Options 41 | 42 | ### grunt.option 43 | Retrieve the value of a command-line option, eg. `debug`. Note that for each command-line option, the inverse can be tested, eg. `no-debug`. 44 | 45 | ```js 46 | grunt.option(optionName) 47 | ``` 48 | 49 | ## Miscellaneous 50 | 51 | ### grunt.package 52 | The current Grunt `package.json` metadata, as an object. 53 | 54 | ```js 55 | grunt.package 56 | ``` 57 | 58 | ### grunt.version 59 | The current Grunt version, as a string. This is just a shortcut to the `grunt.package.version` property. 60 | 61 | ```js 62 | grunt.version 63 | ``` 64 | -------------------------------------------------------------------------------- /grunt.option.md: -------------------------------------------------------------------------------- 1 | The Grunt option API is for sharing parameters across multiple tasks and accessing parameters set on the command line. 2 | 3 | An example would be a flag to target whether your build is for development or staging. On the command line: `grunt deploy --target=staging` would cause `grunt.option('target')` to return `"staging"`. 4 | 5 | An example `Gruntfile` to utilize the `target` option could be: 6 | 7 | ```js 8 | grunt.initConfig({ 9 | compass: { 10 | dev: { 11 | options: { 12 | /* ... */ 13 | outputStyle: 'expanded' 14 | }, 15 | }, 16 | staging: { 17 | options: { 18 | /* ... */ 19 | outputStyle: 'compressed' 20 | }, 21 | }, 22 | }, 23 | }); 24 | var target = grunt.option('target') || 'dev'; 25 | grunt.registerTask('deploy', ['compass:' + target]); 26 | ``` 27 | 28 | As you run `grunt deploy` your stylesheets would default to the `dev` target and output the CSS in the expanded format. If you ran `grunt deploy --target=staging` the `staging` target would instead be ran and your CSS would be in the compressed format. 29 | 30 | `grunt.option` can be used within tasks as well, for example: 31 | 32 | ```js 33 | grunt.registerTask('upload', 'Upload code to specified target.', function(n) { 34 | var target = grunt.option('target'); 35 | // do something useful with target here 36 | }); 37 | grunt.registerTask('deploy', ['validate', 'upload']); 38 | ``` 39 | 40 | _Note that boolean options can be specified using just a key without a value. For example, running `grunt deploy --staging` on the command line would cause `grunt.option('staging')` to return `true`._ 41 | 42 | 43 | ### grunt.option ☃ 44 | Gets or sets an option. 45 | 46 | ```js 47 | grunt.option(key[, val]) 48 | ``` 49 | 50 | Boolean options can be negated by prepending `no-` onto the `key`. For example: 51 | 52 | ```js 53 | grunt.option('staging', false); 54 | var isDev = grunt.option('no-staging'); 55 | // isDev === true 56 | ``` 57 | 58 | ### grunt.option.init 59 | Initialize `grunt.option`. If `initObject` is omitted option will be initialized to an empty object otherwise will be set to `initObject`. 60 | 61 | ```js 62 | grunt.option.init([initObject]) 63 | ``` 64 | 65 | ### grunt.option.flags 66 | Returns the options as an array of command line parameters. 67 | 68 | ```js 69 | grunt.option.flags() 70 | ``` 71 | 72 | ### grunt.option.keys 73 | @since 1.2.0+ 74 | 75 | Returns all option keys. 76 | 77 | ```js 78 | grunt.option.keys() 79 | ``` 80 | -------------------------------------------------------------------------------- /grunt.task.md: -------------------------------------------------------------------------------- 1 | Register, run and load external tasks. 2 | 3 | See the [task lib source](https://github.com/gruntjs/grunt/blob/master/lib/grunt/task.js) and [task util lib source](https://github.com/gruntjs/grunt/blob/master/lib/util/task.js) for more information. 4 | 5 | ## The task API 6 | While a task is running, Grunt exposes many task-specific utility properties and methods inside the task function via the `this` object. See the [[Inside tasks]] guide for a list of these properties and methods. 7 | 8 | Many utility properties and methods are available inside of tasks via the `this` object. 9 | 10 | Note that any method marked with a ☃ (unicode snowman) is also available directly on the `grunt` object. Just so you know. See the [API main page](grunt) for more usage information. 11 | 12 | ## Creating Tasks 13 | 14 | ### grunt.task.registerTask ☃ 15 | Register an "alias task" or a task function. This method supports the following two signatures: 16 | 17 | **Alias task** 18 | 19 | If a task list is specified, the new task will be an alias for one or more other tasks. Whenever this "alias task" is run, every specified task in `taskList` will be run, in the order specified. The `taskList` argument must be an array of tasks. 20 | 21 | ```js 22 | grunt.task.registerTask(taskName, taskList) 23 | ``` 24 | 25 | When the optional `description` string is passed it will be displayed when `grunt --help` is run: 26 | 27 | ```js 28 | grunt.task.registerTask(taskName, description, taskList) 29 | ``` 30 | 31 | This example alias task defines a "default" task whereby the "jshint", "qunit", "concat" and "uglify" tasks are run automatically if Grunt is executed without any tasks specified: 32 | 33 | ```js 34 | task.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']); 35 | ``` 36 | 37 | Task arguments can be specified as well. In this example, the alias "dist" runs both the "concat" and "uglify" tasks, each with the "dist" argument: 38 | 39 | ```js 40 | task.registerTask('dist', ['concat:dist', 'uglify:dist']); 41 | ``` 42 | 43 | **Function task** 44 | 45 | If a `description` and `taskFunction` are passed, the specified function will be executed whenever the task is run. In addition, the specified description will be shown when `grunt --help` is run. Task-specific properties and methods are available inside the task function as properties of the `this` object. The task function can return `false` to indicate that the task has failed. 46 | 47 | Note that the `grunt.task.registerMultiTask` method, explained below, can be used to define a special type of task known as a "multi task." 48 | 49 | ```js 50 | grunt.task.registerTask(taskName, description, taskFunction) 51 | ``` 52 | 53 | This example task logs `foo, testing 123` if Grunt is run via `grunt foo:testing:123`. If the task is run without arguments as `grunt foo` the task logs `foo, no args`. 54 | 55 | ```js 56 | grunt.task.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) { 57 | if (arguments.length === 0) { 58 | grunt.log.writeln(this.name + ", no args"); 59 | } else { 60 | grunt.log.writeln(this.name + ", " + arg1 + " " + arg2); 61 | } 62 | }); 63 | ``` 64 | 65 | See the [creating tasks](Creating-tasks) documentation for more examples of tasks and alias tasks. 66 | 67 | _This method is also available as [grunt.registerTask](grunt)._ 68 | 69 | ### grunt.task.registerMultiTask ☃ 70 | Register a "multi task." A multi task is a task that implicitly iterates over all of its named sub-properties (AKA targets) if no target was specified. In addition to the default properties and methods, extra multi task-specific properties are available inside the task function as properties of the `this` object. 71 | 72 | Many of the contrib tasks, including the [jshint task](https://github.com/gruntjs/grunt-contrib-jshint), [concat task](https://github.com/gruntjs/grunt-contrib-concat) and [uglify task](https://github.com/gruntjs/grunt-contrib-uglify) are multi tasks. 73 | 74 | ```js 75 | grunt.task.registerMultiTask(taskName, description, taskFunction) 76 | ``` 77 | 78 | Given the specified configuration, this example multi task would log `foo: 1,2,3` if Grunt was run via `grunt log:foo`, or it would log `bar: hello world` if Grunt was run via `grunt log:bar`. If Grunt was run as `grunt log` however, it would log `foo: 1,2,3` then `bar: hello world` then `baz: false`. 79 | 80 | ```js 81 | grunt.initConfig({ 82 | log: { 83 | foo: [1, 2, 3], 84 | bar: 'hello world', 85 | baz: false 86 | } 87 | }); 88 | 89 | grunt.task.registerMultiTask('log', 'Log stuff.', function() { 90 | grunt.log.writeln(this.target + ': ' + this.data); 91 | }); 92 | ``` 93 | 94 | See the [creating tasks](Creating-tasks) documentation for more examples of multi tasks. 95 | 96 | _This method is also available as [grunt.registerMultiTask](grunt)._ 97 | 98 | ### grunt.task.requires 99 | 100 | Fail the task if some other task failed or never ran. 101 | 102 | ```js 103 | grunt.task.requires(taskName); 104 | ``` 105 | 106 | ### grunt.task.exists 107 | *Added in 0.4.5* 108 | 109 | Check with the name, if a task exists in the registered tasks. Return a boolean. 110 | 111 | ```js 112 | grunt.task.exists(name) 113 | ``` 114 | 115 | ### grunt.task.renameTask ☃ 116 | Rename a task. This might be useful if you want to override the default behavior of a task, while retaining the old name. 117 | 118 | _Note that if a task has been renamed, the [this.name](inside-tasks#this.name) and [this.nameArgs](inside-tasks#this.nameArgs) properties will change accordingly._ 119 | 120 | ```js 121 | grunt.task.renameTask(oldname, newname) 122 | ``` 123 | 124 | _This method is also available as [grunt.renameTask](grunt)._ 125 | 126 | ## Loading Externally-Defined Tasks 127 | For most projects, tasks will be defined in the [Gruntfile](Getting-started). For larger projects, or in cases where tasks need to be shared across projects, tasks can be loaded from one or more external directories or Npm-installed Grunt plugins. 128 | 129 | ### grunt.task.loadTasks ☃ 130 | Load task-related files from the specified directory, relative to the [Gruntfile](Getting-started). This method can be used to load task-related files from a local Grunt plugin by specifying the path to that plugin's "tasks" subdirectory. 131 | 132 | ```js 133 | grunt.task.loadTasks(tasksPath) 134 | ``` 135 | 136 | _This method is also available as [grunt.loadTasks](grunt)._ 137 | 138 | ### grunt.task.loadNpmTasks ☃ 139 | Load tasks from the specified Grunt plugin. This plugin must be installed locally via npm, and must be relative to the [Gruntfile](Getting-started). Grunt plugins can be created by using the [grunt-init gruntplugin template](https://github.com/gruntjs/grunt-init): `grunt init:gruntplugin`. 140 | 141 | ```js 142 | grunt.task.loadNpmTasks(pluginName) 143 | ``` 144 | 145 | _This method is also available as [grunt.loadNpmTasks](grunt)._ 146 | 147 | 148 | ## Queueing Tasks 149 | Grunt automatically enqueues and runs all tasks specified on the command line, but individual tasks can enqueue additional tasks to be run. 150 | 151 | ### grunt.task.run 152 | Enqueue one or more tasks. Every specified task in `taskList` will be run immediately after the current task completes, in the order specified. The task list can be an array of tasks or individual task arguments. 153 | 154 | ```js 155 | grunt.task.run(taskList) 156 | ``` 157 | 158 | ### grunt.task.clearQueue 159 | Empty the task queue completely. Unless additional tasks are enqueued, no more tasks will be run. 160 | 161 | ```js 162 | grunt.task.clearQueue() 163 | ``` 164 | 165 | ### grunt.task.normalizeMultiTaskFiles 166 | Normalizes a task target configuration object into an array of src-dest file mappings. This method is used internally by the multi task system [this.files / grunt.task.current.files](grunt.task#wiki-this-files) property. 167 | 168 | ```js 169 | grunt.task.normalizeMultiTaskFiles(data [, targetname]) 170 | ``` 171 | -------------------------------------------------------------------------------- /grunt.template.md: -------------------------------------------------------------------------------- 1 | Template strings can be processed manually using the provided template functions. In addition, the `config.get` method (used by many tasks) automatically expands `<% %>` style template strings specified as config data inside the `Gruntfile`. 2 | 3 | ### grunt.template.process 4 | Process a [Lo-Dash template](http://lodash.com/docs/#template) string. The `template` argument will be processed recursively until there are no more templates to process. 5 | 6 | The default data object is the entire config object, but if `options.data` is set, that object will be used instead. The default template delimiters are `<% %>` but if `options.delimiters` is set to a custom delimiter name (set with [`grunt.template.addDelimiters`](/api/grunt.template#grunt.template.adddelimiters)), those template delimiters will be used instead. 7 | 8 | ```js 9 | grunt.template.process(template [, options]) 10 | ``` 11 | 12 | Inside templates, the `grunt` object is exposed so that you can do things like `<%= grunt.template.today('yyyy') %>`. _Note that if the data object already has a `grunt` property, the `grunt` API will not be accessible in templates._ 13 | 14 | In this example, the `baz` property is processed recursively until there are no more `<% %>` templates to process. 15 | 16 | ```js 17 | var obj = { 18 | foo: 'c', 19 | bar: 'b<%= foo %>d', 20 | baz: 'a<%= bar %>e' 21 | }; 22 | grunt.template.process('<%= baz %>', {data: obj}) // 'abcde' 23 | ``` 24 | 25 | ### grunt.template.setDelimiters 26 | Set the [Lo-Dash template](http://lodash.com/docs/#template) delimiters to a predefined set in case `grunt.util._.template` needs to be called manually. The `config` delimiters `<% %>` are included by default. 27 | 28 | _You probably won't need to use this method, because you'll be using `grunt.template.process` which uses this method internally._ 29 | 30 | ```js 31 | grunt.template.setDelimiters(name) 32 | ``` 33 | 34 | ### grunt.template.addDelimiters 35 | Add a named set of [Lo-Dash template](http://lodash.com/docs/#template) delimiters. You probably won't need to use this method, because the built-in delimiters should be sufficient, but you could always add `{% %}` or `[% %]` style delimiters. 36 | 37 | The `name` argument should be unique since it is how we access the delimiters from `grunt.template.setDelimiters` and as an option for `grunt.template.process`. 38 | 39 | ```js 40 | grunt.template.addDelimiters(name, opener, closer) 41 | ``` 42 | 43 | In this example, if we were to use the `{% %}` style mentioned above we would use the following: 44 | 45 | ```js 46 | grunt.template.addDelimiters('myDelimiters', '{%', '%}') 47 | ``` 48 | 49 | ## Helpers 50 | 51 | ### grunt.template.date 52 | Format a date using the [dateformat library](https://github.com/felixge/node-dateformat). 53 | 54 | ```js 55 | grunt.template.date(date, format) 56 | ``` 57 | 58 | In this example, a specific date is formatted as month/day/year. 59 | 60 | ```js 61 | grunt.template.date(847602000000, 'yyyy-mm-dd') // '1996-11-10' 62 | ``` 63 | 64 | ### grunt.template.today 65 | Format today's date using the [dateformat library](https://github.com/felixge/node-dateformat). 66 | 67 | ```js 68 | grunt.template.today(format) 69 | ``` 70 | 71 | In this example, today's date is formatted as a 4-digit year. 72 | 73 | ```js 74 | grunt.template.today('yyyy') // This returns a year in format such as '2020' 75 | ``` 76 | -------------------------------------------------------------------------------- /grunt.util.md: -------------------------------------------------------------------------------- 1 | Miscellaneous utilities for your Gruntfile and tasks. 2 | 3 | ### grunt.util.kindOf 4 | Return the "kind" of a value. Like `typeof` but returns the internal `[[Class]]` value. Possible results are `"number"`, `"string"`, `"boolean"`, `"function"`, `"regexp"`, `"array"`, `"date"`, `"error"`, `"null"`, `"undefined"` and the catch-all `"object"`. 5 | 6 | ```js 7 | grunt.util.kindOf(value) 8 | ``` 9 | 10 | ### grunt.util.error 11 | Return a new Error instance (that can be thrown) with the appropriate message. If an Error object is specified instead of `message` that object will be returned. 12 | Also, if an Error object is specified for `origError` and Grunt was run with the `--stack` option, the original Error stack will be dumped. 13 | 14 | ```js 15 | grunt.util.error(message [, origError]) 16 | ``` 17 | 18 | ### grunt.util.linefeed 19 | The linefeed character, normalized for the current operating system. (`\r\n` on Windows, `\n` otherwise) 20 | 21 | ### grunt.util.normalizelf 22 | Given a string, return a new string with all the linefeeds normalized for the current operating system. (`\r\n` on Windows, `\n` otherwise) 23 | 24 | ```js 25 | grunt.util.normalizelf(string) 26 | ``` 27 | 28 | ### grunt.util.recurse 29 | Recurse through nested objects and arrays, executing `callbackFunction` for each non-object value. If `continueFunction` returns `false`, a given object or value will be skipped. 30 | 31 | ```js 32 | grunt.util.recurse(object, callbackFunction, continueFunction) 33 | ``` 34 | 35 | ### grunt.util.repeat 36 | Return string `str` repeated `n` times. 37 | 38 | ```js 39 | grunt.util.repeat(n, str) 40 | ``` 41 | 42 | ### grunt.util.pluralize 43 | Given `str` of `"a/b"`, If `n` is `1`, return `"a"` otherwise `"b"`. You can specify a custom separator if '/' doesn't work for you. 44 | 45 | ```js 46 | grunt.util.pluralize(n, str, separator) 47 | ``` 48 | 49 | ### grunt.util.spawn 50 | Spawn a child process, keeping track of its stdout, stderr and exit code. The method returns a reference to the spawned child. When the child exits, the `doneFunction` is called. 51 | 52 | ```js 53 | grunt.util.spawn(options, doneFunction) 54 | ``` 55 | 56 | The `options` object has these possible properties: 57 | 58 | ```js 59 | var options = { 60 | // The command to execute. It should be in the system path. 61 | cmd: commandToExecute, 62 | // If specified, the same grunt bin that is currently running will be 63 | // spawned as the child command, instead of the "cmd" option. Defaults 64 | // to false. 65 | grunt: boolean, 66 | // An array of arguments to pass to the command. 67 | args: arrayOfArguments, 68 | // Additional options for the Node.js child_process spawn method. 69 | opts: nodeSpawnOptions, 70 | // If this value is set and an error occurs, it will be used as the value 71 | // and null will be passed as the error value. 72 | fallback: fallbackValue 73 | }; 74 | ``` 75 | 76 | The `doneFunction` accepts these arguments: 77 | 78 | ```js 79 | function doneFunction(error, result, code) { 80 | // If the exit code was non-zero and a fallback wasn't specified, an Error 81 | // object, otherwise null. 82 | error 83 | // The result object is an object with the properties .stdout, .stderr, and 84 | // .code (exit code). 85 | result 86 | // When result is coerced to a string, the value is stdout if the exit code 87 | // was zero, the fallback if the exit code was non-zero and a fallback was 88 | // specified, or stderr if the exit code was non-zero and a fallback was 89 | // not specified. 90 | String(result) 91 | // The numeric exit code. 92 | code 93 | } 94 | ``` 95 | 96 | ### grunt.util.toArray 97 | Given an array or array-like object, return an array. Great for converting `arguments` objects into arrays. 98 | 99 | ```js 100 | grunt.util.toArray(arrayLikeObject) 101 | ``` 102 | 103 | ### grunt.util.callbackify 104 | Normalizes both "returns a value" and "passes result to a callback" functions to always pass a result to the specified callback. If the original function returns a value, that value will now be passed to the callback, which is specified as the last argument, after all other predefined arguments. If the original function passed a value to a callback, it will continue to do so. 105 | 106 | ```js 107 | grunt.util.callbackify(syncOrAsyncFunction) 108 | ``` 109 | 110 | This example might better illustrate: 111 | 112 | ```js 113 | function add1(a, b) { 114 | return a + b; 115 | } 116 | function add2(a, b, callback) { 117 | callback(a + b); 118 | } 119 | 120 | var fn1 = grunt.util.callbackify(add1); 121 | var fn2 = grunt.util.callbackify(add2); 122 | 123 | fn1(1, 2, function(result) { 124 | console.log('1 plus 2 equals ' + result); 125 | }); 126 | fn2(1, 2, function(result) { 127 | console.log('1 plus 2 equals ' + result); 128 | }); 129 | ``` 130 | 131 | ## Internal libraries 132 | 133 | ### grunt.util.namespace 134 | An internal library for resolving deeply-nested properties in objects. 135 | 136 | ### grunt.util.task 137 | An internal library for task running. 138 | 139 | ## External libraries 140 | *Deprecated* 141 | 142 | __All external libraries that are listed below are now deprecated.__ 143 | 144 | Please use __npm__ to manage these external libraries in your project's dependencies. 145 | 146 | For example if you want to use [Lo-Dash](https://www.npmjs.org/package/lodash), install it first: `npm install lodash`, then 147 | use it in your `Gruntfile`: `var _ = require('lodash');`. 148 | 149 | #### grunt.util._ 150 | *Deprecated* 151 | 152 | [Lo-Dash](http://lodash.com/) and [Underscore.string](https://github.com/epeli/underscore.string) 153 | 154 | `grunt.util._.str` is available for methods that conflict with existing Lo-Dash methods. 155 | 156 | #### grunt.util.async 157 | *Deprecated* 158 | 159 | [Async](https://github.com/caolan/async) - Async utilities for node and the browser. 160 | 161 | #### grunt.util.hooker 162 | *Deprecated* 163 | 164 | [JavaScript Hooker](https://github.com/cowboy/javascript-hooker) - Monkey-patch (hook) functions for debugging and stuff. 165 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grunt-docs", 3 | "version": "0.2.0", 4 | "description": "This repository contains the wiki files for the official grunt documentation. Grunt documentation is based on the [Gollum Wiki](https://github.com/gollum/gollum/wiki)", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/gruntjs/grunt-docs.git" 8 | }, 9 | "author": "GruntJS Team", 10 | "license": "MIT", 11 | "bugs": { 12 | "url": "https://github.com/gruntjs/grunt-docs/issues" 13 | }, 14 | "homepage": "https://github.com/gruntjs/grunt-docs" 15 | } 16 | --------------------------------------------------------------------------------