From 81fc26ddbc47ab10fa14ae4373850b30c92754e0 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Fri, 10 Nov 2017 21:39:13 -0600 Subject: [PATCH 001/225] Docs: Change jade references to pug (#2037) --- docs/API.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/API.md b/docs/API.md index d06906f1..d9239cce 100644 --- a/docs/API.md +++ b/docs/API.md @@ -14,8 +14,8 @@ that can be [piped](http://nodejs.org/api/stream.html#stream_readable_pipe_desti to plugins. ```javascript -gulp.src('client/templates/*.jade') - .pipe(jade()) +gulp.src('client/templates/*.pug') + .pipe(pug()) .pipe(minify()) .pipe(gulp.dest('build/minified_templates')); ``` @@ -77,8 +77,8 @@ gulp.src('client/js/**/*.js', { base: 'client' }) Can be piped to and it will write files. Re-emits all data passed to it so you can pipe to multiple folders. Folders that don't exist will be created. ```javascript -gulp.src('./client/templates/*.jade') - .pipe(jade()) +gulp.src('./client/templates/*.pug') + .pipe(pug()) .pipe(gulp.dest('./build/templates')) .pipe(minify()) .pipe(gulp.dest('./build/minified_templates')); From 4f9465a420f39832d5ade015c06972378502f8af Mon Sep 17 00:00:00 2001 From: Gregg Christofferson <25208248+GREGG-CHRISTOFFERSON@users.noreply.github.com> Date: Tue, 5 Dec 2017 12:28:17 -0800 Subject: [PATCH 002/225] Docs: Specify where to create package.json (#2053) --- docs/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 4ebaa5ab..057dca3b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -18,7 +18,7 @@ npm --version npm install --global gulp-cli ``` -#### Create a `package.json` +#### Create a `package.json` in your project directory If you don't have a package.json, create one. If you need help, run an `npm init` which will walk you through giving it a name, version, description, etc. From 4b118b9eff679ec76725db632a060e7b5ee5c8a9 Mon Sep 17 00:00:00 2001 From: Gabriel Aumala Date: Fri, 21 Jul 2017 17:25:47 -0500 Subject: [PATCH 003/225] Docs: Fix and improve Transform example in writing-a-plugin docs --- docs/writing-a-plugin/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/writing-a-plugin/README.md b/docs/writing-a-plugin/README.md index c301b695..0e058669 100644 --- a/docs/writing-a-plugin/README.md +++ b/docs/writing-a-plugin/README.md @@ -22,7 +22,7 @@ Transform streams are streams that are readable and writable; they manipulate ob All gulp plugins essentially boil down to this: ```js -var Transform = require('transform'); +var Transform = require('stream').Transform; module.exports = function() { // Monkey patch Transform or create your own subclass, @@ -44,7 +44,7 @@ module.exports = function() { }; ``` -Many plugins use the [through2](https://github.com/rvagg/through2/) module to simplify their code: +Alternatively you could pass your transform and flush functions to the `Transform` constructor or even extend `Transform` with ES6 classes, as described by the [Node.js docs](https://nodejs.org/docs/latest/api/stream.html#stream_implementing_a_transform_stream). However, many plugins prefer to use the [through2](https://github.com/rvagg/through2/) module to simplify their code: ```js var through = require('through2'); // npm install --save through2 From ff4e7197a67cecf6191006e6096c9ebe085cac45 Mon Sep 17 00:00:00 2001 From: Ronald Eddy Jr Date: Mon, 25 Dec 2017 09:36:54 -0800 Subject: [PATCH 004/225] Docs: Update urls to https (#2067) --- README.md | 2 +- docs/API.md | 4 ++-- docs/CLI.md | 2 +- docs/FAQ.md | 6 +++--- docs/README.md | 10 +++++----- docs/getting-started.md | 2 +- docs/recipes/browserify-transforms.md | 2 +- docs/recipes/browserify-uglify-sourcemap.md | 2 +- docs/recipes/fast-browserify-builds-with-watchify.md | 6 +++--- docs/recipes/rollup-with-rollup-stream.md | 2 +- .../server-with-livereload-and-css-injection.md | 4 ++-- docs/writing-a-plugin/README.md | 10 +++++----- 12 files changed, 26 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 8a5ddeba..ca49c3c2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- +

The streaming build system

diff --git a/docs/API.md b/docs/API.md index d9239cce..b5fac15b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -9,8 +9,8 @@ Jump to: ### gulp.src(globs[, options]) Emits files matching provided glob or an array of globs. -Returns a [stream](http://nodejs.org/api/stream.html) of [Vinyl files](https://github.com/gulpjs/vinyl-fs) -that can be [piped](http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options) +Returns a [stream](https://nodejs.org/api/stream.html) of [Vinyl files](https://github.com/gulpjs/vinyl-fs) +that can be [piped](https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options) to plugins. ```javascript diff --git a/docs/CLI.md b/docs/CLI.md index a536c913..eab0b6b7 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -18,7 +18,7 @@ The CLI adds process.env.INIT_CWD which is the original cwd it was launched from #### Task specific flags -Refer to this [StackOverflow](http://stackoverflow.com/questions/23023650/is-it-possible-to-pass-a-flag-to-gulp-to-have-it-run-tasks-in-different-ways) link for how to add task specific flags +Refer to this [StackOverflow](https://stackoverflow.com/questions/23023650/is-it-possible-to-pass-a-flag-to-gulp-to-have-it-run-tasks-in-different-ways) link for how to add task specific flags ### Tasks diff --git a/docs/FAQ.md b/docs/FAQ.md index aa8886ab..31e11df7 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -43,7 +43,7 @@ gulp updates can be found on the following twitters: Yes, come chat with us in #gulpjs on [Freenode]. [Writing a gulp plugin]: writing-a-plugin/README.md -[gulp introduction slideshow]: http://slid.es/contra/gulp -[Freenode]: http://freenode.net/ -[search-gulp-plugins]: http://gulpjs.com/plugins/ +[gulp introduction slideshow]: https://slid.es/contra/gulp +[Freenode]: https://freenode.net/ +[search-gulp-plugins]: https://gulpjs.com/plugins/ [npm plugin search]: https://npmjs.org/browse/keyword/gulpplugin diff --git a/docs/README.md b/docs/README.md index 39dc8469..d72ff7d2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -21,7 +21,7 @@ The community has written [recipes](recipes#recipes) for common gulp use-cases. ## Still got questions? -Post on [StackOverflow with a #gulp tag](http://stackoverflow.com/questions/tagged/gulp) or come chat with us in [#gulpjs](http://webchat.freenode.net/?channels=gulpjs) on [Freenode](http://freenode.net/). +Post on [StackOverflow with a #gulp tag](https://stackoverflow.com/questions/tagged/gulp) or come chat with us in [#gulpjs](https://webchat.freenode.net/?channels=gulpjs) on [Freenode](https://freenode.net/). ## Books @@ -32,14 +32,14 @@ Post on [StackOverflow with a #gulp tag](http://stackoverflow.com/questions/tagg ## Articles * [Tagtree intro to gulp video](http://tagtree.io/gulp) * [Introduction to node.js streams](https://github.com/substack/stream-handbook) -* [Video introduction to node.js streams](http://www.youtube.com/watch?v=QgEuZ52OZtU) -* [Getting started with gulp (by @markgdyr)](http://markgoodyear.com/2014/01/getting-started-with-gulp/) +* [Video introduction to node.js streams](https://www.youtube.com/watch?v=QgEuZ52OZtU) +* [Getting started with gulp (by @markgdyr)](https://markgoodyear.com/2014/01/getting-started-with-gulp/) * [A cheatsheet for gulp](https://github.com/osscafe/gulp-cheatsheet) * [Why you shouldn’t create a gulp plugin (or, how to stop worrying and learn to love existing node packages)](http://blog.overzealous.com/post/74121048393/why-you-shouldnt-create-a-gulp-plugin-or-how-to-stop) * [Inspiration (slides) about why gulp was made](http://slid.es/contra/gulp) * [Building With Gulp](http://www.smashingmagazine.com/2014/06/11/building-with-gulp/) * [Gulp - The Basics (screencast)](https://www.youtube.com/watch?v=dwSLFai8ovQ) -* [Get started with gulp (video series)](http://www.youtube.com/playlist?list=PLRk95HPmOM6PN-G1xyKj9q6ap_dc9Yckm) +* [Get started with gulp (video series)](https://www.youtube.com/playlist?list=PLRk95HPmOM6PN-G1xyKj9q6ap_dc9Yckm) * [Optimize your web code with gulp](http://www.linuxuser.co.uk/tutorials/optimise-your-web-code-with-gulp-js) * [Automate Your Tasks Easily with Gulp.js ](https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js) @@ -53,7 +53,7 @@ Post on [StackOverflow with a #gulp tag](http://stackoverflow.com/questions/tagg All the documentation is covered by the CC0 license *(do whatever you want with it - public domain)*. -[![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/) +[![CC0](https://i.creativecommons.org/p/zero/1.0/88x31.png)](https://creativecommons.org/publicdomain/zero/1.0/) To the extent possible under law, [Fractal](http://wearefractal.com) has waived all copyright and related or neighboring rights to this work. diff --git a/docs/getting-started.md b/docs/getting-started.md index 057dca3b..d859dc3b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -67,4 +67,4 @@ Using gulpfile ~/my-project/gulpfile.js - [API Documentation](API.md) - The programming interface, defined - [Recipes](recipes) - Specific examples from the community - [In Depth Help](https://travismaynard.com/writing/getting-started-with-gulp) - A tutorial from the the guy who wrote the book -- [Plugins](http://gulpjs.com/plugins/) - Building blocks for your gulp file +- [Plugins](https://gulpjs.com/plugins/) - Building blocks for your gulp file diff --git a/docs/recipes/browserify-transforms.md b/docs/recipes/browserify-transforms.md index e1f11dbc..6f343a47 100644 --- a/docs/recipes/browserify-transforms.md +++ b/docs/recipes/browserify-transforms.md @@ -1,6 +1,6 @@ # Browserify + Transforms -[Browserify](http://github.com/substack/node-browserify) has become an important and indispensable +[Browserify](https://github.com/substack/node-browserify) has become an important and indispensable tool but requires being wrapped before working well with gulp. Below is a simple recipe for using Browserify with transforms. diff --git a/docs/recipes/browserify-uglify-sourcemap.md b/docs/recipes/browserify-uglify-sourcemap.md index 756b89ac..6b822f28 100644 --- a/docs/recipes/browserify-uglify-sourcemap.md +++ b/docs/recipes/browserify-uglify-sourcemap.md @@ -1,6 +1,6 @@ # Browserify + Uglify2 with sourcemaps -[Browserify](http://github.com/substack/node-browserify) has become an important and indispensable +[Browserify](https://github.com/substack/node-browserify) has become an important and indispensable tool but requires being wrapped before working well with gulp. Below is a simple recipe for using Browserify with full sourcemaps that resolve to the original individual files. diff --git a/docs/recipes/fast-browserify-builds-with-watchify.md b/docs/recipes/fast-browserify-builds-with-watchify.md index ef65e768..0ac89db3 100644 --- a/docs/recipes/fast-browserify-builds-with-watchify.md +++ b/docs/recipes/fast-browserify-builds-with-watchify.md @@ -1,10 +1,10 @@ # Fast browserify builds with watchify -As a [browserify](http://github.com/substack/node-browserify) project begins to expand, the time to bundle it slowly gets longer and longer. While it might start at 1 second, it's possible to be waiting 30 seconds for your project to build on particularly large projects. +As a [browserify](https://github.com/substack/node-browserify) project begins to expand, the time to bundle it slowly gets longer and longer. While it might start at 1 second, it's possible to be waiting 30 seconds for your project to build on particularly large projects. -That's why [substack](http://github.com/substack) wrote [watchify](http://github.com/substack/watchify), a persistent browserify bundler that watches files for changes and *only rebuilds what it needs to*. This way, that first build might still take 30 seconds, but subsequent builds can still run in under 100ms – which is a huge improvement. +That's why [substack](https://github.com/substack) wrote [watchify](https://github.com/substack/watchify), a persistent browserify bundler that watches files for changes and *only rebuilds what it needs to*. This way, that first build might still take 30 seconds, but subsequent builds can still run in under 100ms – which is a huge improvement. -Watchify doesn't have a gulp plugin, and it doesn't need one: you can use [vinyl-source-stream](http://github.com/hughsk/vinyl-source-stream) to pipe the bundle stream into your gulp pipeline. +Watchify doesn't have a gulp plugin, and it doesn't need one: you can use [vinyl-source-stream](https://github.com/hughsk/vinyl-source-stream) to pipe the bundle stream into your gulp pipeline. ``` javascript 'use strict'; diff --git a/docs/recipes/rollup-with-rollup-stream.md b/docs/recipes/rollup-with-rollup-stream.md index abee2dd3..5311fd51 100644 --- a/docs/recipes/rollup-with-rollup-stream.md +++ b/docs/recipes/rollup-with-rollup-stream.md @@ -1,6 +1,6 @@ # Rollup with rollup-stream -Like Browserify, [Rollup](http://rollupjs.org/) is a bundler and thus only fits naturally into gulp if it's at the start of the pipeline. Unlike Browserify, Rollup doesn't natively produce a stream as output and needs to be wrapped before it can take this position. [rollup-stream](https://github.com/Permutatrix/rollup-stream) does this for you, producing output just like that of Browserify's `bundle()` method—as a result, most of the Browserify recipes here will also work with rollup-stream. +Like Browserify, [Rollup](https://rollupjs.org/) is a bundler and thus only fits naturally into gulp if it's at the start of the pipeline. Unlike Browserify, Rollup doesn't natively produce a stream as output and needs to be wrapped before it can take this position. [rollup-stream](https://github.com/Permutatrix/rollup-stream) does this for you, producing output just like that of Browserify's `bundle()` method—as a result, most of the Browserify recipes here will also work with rollup-stream. ## Basic usage ```js diff --git a/docs/recipes/server-with-livereload-and-css-injection.md b/docs/recipes/server-with-livereload-and-css-injection.md index 78a9b38f..7a14a667 100644 --- a/docs/recipes/server-with-livereload-and-css-injection.md +++ b/docs/recipes/server-with-livereload-and-css-injection.md @@ -1,6 +1,6 @@ # Server with live-reloading and CSS injection -With [BrowserSync](http://browsersync.io) and gulp, you can easily create a development server that is accessible to any device on the same WiFi network. BrowserSync also has live-reload built in, so there's nothing else to configure. +With [BrowserSync](https://browsersync.io) and gulp, you can easily create a development server that is accessible to any device on the same WiFi network. BrowserSync also has live-reload built in, so there's nothing else to configure. First install the module: @@ -118,5 +118,5 @@ gulp serve ## Extras -- Live reload, CSS injection and scroll/form syncing works seamlessly inside of [BrowserStack](http://www.browserstack.com/) virtual machines. +- Live reload, CSS injection and scroll/form syncing works seamlessly inside of [BrowserStack](https://www.browserstack.com/) virtual machines. - Set `tunnel: true` to view your local site at a public URL (complete with all BrowserSync features). diff --git a/docs/writing-a-plugin/README.md b/docs/writing-a-plugin/README.md index 0e058669..b5042a60 100644 --- a/docs/writing-a-plugin/README.md +++ b/docs/writing-a-plugin/README.md @@ -11,12 +11,12 @@ If you plan to create your own Gulp plugin, you will save time by reading the fu ### Streaming file objects -A gulp plugin always returns a stream in [object mode](http://nodejs.org/api/stream.html#stream_object_mode) that does the following: +A gulp plugin always returns a stream in [object mode](https://nodejs.org/api/stream.html#stream_object_mode) that does the following: -1. Takes in [vinyl File objects](http://github.com/gulpjs/vinyl) -2. Outputs [vinyl File objects](http://github.com/gulpjs/vinyl) (via `transform.push()` and/or the plugin's callback function) +1. Takes in [vinyl File objects](https://github.com/gulpjs/vinyl) +2. Outputs [vinyl File objects](https://github.com/gulpjs/vinyl) (via `transform.push()` and/or the plugin's callback function) -These are known as [transform streams](http://nodejs.org/api/stream.html#stream_class_stream_transform_1) +These are known as [transform streams](https://nodejs.org/api/stream.html#stream_class_stream_transform_1) (also sometimes called through streams). Transform streams are streams that are readable and writable; they manipulate objects as they're being passed through. @@ -195,6 +195,6 @@ if (someCondition) { If you're unfamiliar with streams, you will need to read up on them: * https://github.com/substack/stream-handbook (a MUST read) -* http://nodejs.org/api/stream.html +* https://nodejs.org/api/stream.html Other libraries that are not file manipulating through streams but are made for use with gulp are tagged with the [gulpfriendly](https://npmjs.org/browse/keyword/gulpfriendly) keyword on npm. From 260d5c41e6d74f2d11e48ca1e9a3be0b3918fe49 Mon Sep 17 00:00:00 2001 From: Ronald Eddy Jr Date: Tue, 26 Dec 2017 17:22:56 -0800 Subject: [PATCH 005/225] Docs: Update browserify links (#2072) --- docs/recipes/browserify-transforms.md | 2 +- docs/recipes/browserify-uglify-sourcemap.md | 2 +- docs/recipes/fast-browserify-builds-with-watchify.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/recipes/browserify-transforms.md b/docs/recipes/browserify-transforms.md index 6f343a47..0137c6ed 100644 --- a/docs/recipes/browserify-transforms.md +++ b/docs/recipes/browserify-transforms.md @@ -1,6 +1,6 @@ # Browserify + Transforms -[Browserify](https://github.com/substack/node-browserify) has become an important and indispensable +[Browserify](https://github.com/browserify/browserify) has become an important and indispensable tool but requires being wrapped before working well with gulp. Below is a simple recipe for using Browserify with transforms. diff --git a/docs/recipes/browserify-uglify-sourcemap.md b/docs/recipes/browserify-uglify-sourcemap.md index 6b822f28..08287edb 100644 --- a/docs/recipes/browserify-uglify-sourcemap.md +++ b/docs/recipes/browserify-uglify-sourcemap.md @@ -1,6 +1,6 @@ # Browserify + Uglify2 with sourcemaps -[Browserify](https://github.com/substack/node-browserify) has become an important and indispensable +[Browserify](https://github.com/browserify/browserify) has become an important and indispensable tool but requires being wrapped before working well with gulp. Below is a simple recipe for using Browserify with full sourcemaps that resolve to the original individual files. diff --git a/docs/recipes/fast-browserify-builds-with-watchify.md b/docs/recipes/fast-browserify-builds-with-watchify.md index 0ac89db3..32847d7c 100644 --- a/docs/recipes/fast-browserify-builds-with-watchify.md +++ b/docs/recipes/fast-browserify-builds-with-watchify.md @@ -1,8 +1,8 @@ # Fast browserify builds with watchify -As a [browserify](https://github.com/substack/node-browserify) project begins to expand, the time to bundle it slowly gets longer and longer. While it might start at 1 second, it's possible to be waiting 30 seconds for your project to build on particularly large projects. +As a [browserify](https://github.com/browserify/browserify) project begins to expand, the time to bundle it slowly gets longer and longer. While it might start at 1 second, it's possible to be waiting 30 seconds for your project to build on particularly large projects. -That's why [substack](https://github.com/substack) wrote [watchify](https://github.com/substack/watchify), a persistent browserify bundler that watches files for changes and *only rebuilds what it needs to*. This way, that first build might still take 30 seconds, but subsequent builds can still run in under 100ms – which is a huge improvement. +That's why [substack](https://github.com/substack) wrote [watchify](https://github.com/browserify/watchify), a persistent browserify bundler that watches files for changes and *only rebuilds what it needs to*. This way, that first build might still take 30 seconds, but subsequent builds can still run in under 100ms – which is a huge improvement. Watchify doesn't have a gulp plugin, and it doesn't need one: you can use [vinyl-source-stream](https://github.com/hughsk/vinyl-source-stream) to pipe the bundle stream into your gulp pipeline. From 5368d2c00cf186e25aa0b0f6e4d762f6e795e0fb Mon Sep 17 00:00:00 2001 From: Andreas Schlapbach Date: Wed, 27 Dec 2017 02:23:21 +0100 Subject: [PATCH 006/225] Docs: Remove duplicate "the" typo (#2071) --- docs/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index d859dc3b..980c2218 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -66,5 +66,5 @@ Using gulpfile ~/my-project/gulpfile.js - [API Documentation](API.md) - The programming interface, defined - [Recipes](recipes) - Specific examples from the community -- [In Depth Help](https://travismaynard.com/writing/getting-started-with-gulp) - A tutorial from the the guy who wrote the book +- [In Depth Help](https://travismaynard.com/writing/getting-started-with-gulp) - A tutorial from the guy who wrote the book - [Plugins](https://gulpjs.com/plugins/) - Building blocks for your gulp file From abd73b7fb0ab6eb2ccdc4407e367c169a0e1a887 Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Sat, 6 Sep 2014 19:37:12 +0200 Subject: [PATCH 007/225] New: Add the --verify flag (closes #535) --- docs/CLI.md | 1 + lib/blackList.js | 37 +++++++++++++++++++++++++++++++++++++ lib/verifyDependencies.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 lib/blackList.js create mode 100644 lib/verifyDependencies.js diff --git a/docs/CLI.md b/docs/CLI.md index eab0b6b7..20fb0325 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -10,6 +10,7 @@ gulp has very few flags to know about. All other flags are for tasks to use if n - `--cwd ` will manually set the CWD. The search for the gulpfile, as well as the relativity of all requires will be from here - `-T` or `--tasks` will display the task dependency tree for the loaded gulpfile - `--tasks-simple` will display a plaintext list of tasks for the loaded gulpfile +- `--verify` will verify plugins referenced in project's package.json against the plugins black list - `--color` will force gulp and gulp plugins to display colors even when no color support is detected - `--no-color` will force gulp and gulp plugins to not display colors even when color support is detected - `--silent` will disable all gulp logging diff --git a/lib/blackList.js b/lib/blackList.js new file mode 100644 index 00000000..b9f381ea --- /dev/null +++ b/lib/blackList.js @@ -0,0 +1,37 @@ +'use strict'; + +var http = require('http'); + +/** + * Given a collection of plugin names verifies this collection against + * the black-list. Invokes callback with an object: + * [plugin name]=>[black-listing reason] + * or undefined if none of the plugins to check is black-listed. + * + * @param pluginsToVerify - an array of plugin names to verify + * @param cb + */ +module.exports = function (pluginsToVerify, cb) { + http.get('http://gulpjs.com/plugins/blackList.json', function (res) { + var blackListJSONStr = ''; + + res.on('data', function (chunk) { + blackListJSONStr += chunk; + }); + + res.on('end', function () { + var blackList = JSON.parse(blackListJSONStr); + var result = pluginsToVerify.reduce(function(blackListed, pluginName) { + if (blackList[pluginName]) { + blackListed = blackListed || {}; + blackListed[pluginName] = blackList[pluginName]; + return blackListed; + } + }); + cb(null, result); + }); + + }).on('error', function (e) { + cb(e); + }); +}; diff --git a/lib/verifyDependencies.js b/lib/verifyDependencies.js new file mode 100644 index 00000000..25345847 --- /dev/null +++ b/lib/verifyDependencies.js @@ -0,0 +1,30 @@ +'use strict'; + +var chalk = require('chalk'); +var gutil = require('gulp-util'); +var blackList = require('./blackList'); +var formatError = require('./formatError'); + +module.exports = function verifyDependencies(depNames) { + + blackList(Object.keys(depNames), function(err, blackListed) { + if (err) { + gutil.log(chalk.red('Error: failed to retrieve plugins black-list')); + gutil.log(formatError(err)); + process.exit(1); + } + + if (blackListed) { + gutil.log(chalk.red('Black-listed plugins found in this project:')); + for (var blDependency in blackListed) { + gutil.log(blDependency + ': ' + blackListed[blDependency]); + } + process.exit(1); + } else { + gutil.log( + chalk.green('There are no black-listed plugins in this project') + ); + process.exit(0); + } + }); +}; From f0942aaf9dbdeda83a33273791686a20ae6d4d4a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 27 Dec 2014 23:22:00 -0700 Subject: [PATCH 008/225] Update: Replace inline CLI code with gulp-cli dependency --- bin/gulp.js | 211 +------------------------------------- completion/README.md | 20 ---- completion/bash | 27 ----- completion/fish | 10 -- completion/powershell | 61 ----------- completion/zsh | 25 ----- docs/CLI.md | 2 +- lib/blackList.js | 37 ------- lib/completion.js | 22 ---- lib/taskTree.js | 14 --- lib/verifyDependencies.js | 30 ------ package.json | 17 +-- test/taskTree.js | 42 -------- 13 files changed, 4 insertions(+), 514 deletions(-) delete mode 100644 completion/README.md delete mode 100644 completion/bash delete mode 100644 completion/fish delete mode 100644 completion/powershell delete mode 100644 completion/zsh delete mode 100644 lib/blackList.js delete mode 100644 lib/completion.js delete mode 100644 lib/taskTree.js delete mode 100644 lib/verifyDependencies.js delete mode 100644 test/taskTree.js diff --git a/bin/gulp.js b/bin/gulp.js index a5374c11..f4b80cc4 100755 --- a/bin/gulp.js +++ b/bin/gulp.js @@ -1,212 +1,3 @@ #!/usr/bin/env node -'use strict'; -var gutil = require('gulp-util'); -var prettyTime = require('pretty-hrtime'); -var chalk = require('chalk'); -var semver = require('semver'); -var archy = require('archy'); -var Liftoff = require('liftoff'); -var tildify = require('tildify'); -var interpret = require('interpret'); -var v8flags = require('v8flags'); -var completion = require('../lib/completion'); -var argv = require('minimist')(process.argv.slice(2)); -var taskTree = require('../lib/taskTree'); - -// Set env var for ORIGINAL cwd -// before anything touches it -process.env.INIT_CWD = process.cwd(); - -var cli = new Liftoff({ - name: 'gulp', - completions: completion, - extensions: interpret.jsVariants, - v8flags: v8flags, -}); - -// Exit with 0 or 1 -var failed = false; -process.once('exit', function(code) { - if (code === 0 && failed) { - process.exit(1); - } -}); - -// Parse those args m8 -var cliPackage = require('../package'); -var versionFlag = argv.v || argv.version; -var tasksFlag = argv.T || argv.tasks; -var tasks = argv._; -var toRun = tasks.length ? tasks : ['default']; - -// This is a hold-over until we have a better logging system -// with log levels -var simpleTasksFlag = argv['tasks-simple']; -var shouldLog = !argv.silent && !simpleTasksFlag; - -if (!shouldLog) { - gutil.log = function() {}; -} - -cli.on('require', function(name) { - gutil.log('Requiring external module', chalk.magenta(name)); -}); - -cli.on('requireFail', function(name) { - gutil.log(chalk.red('Failed to load external module'), chalk.magenta(name)); -}); - -cli.on('respawn', function(flags, child) { - var nodeFlags = chalk.magenta(flags.join(', ')); - var pid = chalk.magenta(child.pid); - gutil.log('Node flags detected:', nodeFlags); - gutil.log('Respawned to PID:', pid); -}); - -cli.launch({ - cwd: argv.cwd, - configPath: argv.gulpfile, - require: argv.require, - completion: argv.completion, -}, handleArguments); - -// The actual logic -function handleArguments(env) { - if (versionFlag && tasks.length === 0) { - gutil.log('CLI version', cliPackage.version); - if (env.modulePackage && typeof env.modulePackage.version !== 'undefined') { - gutil.log('Local version', env.modulePackage.version); - } - process.exit(0); - } - - if (!env.modulePath) { - gutil.log( - chalk.red('Local gulp not found in'), - chalk.magenta(tildify(env.cwd)) - ); - gutil.log(chalk.red('Try running: npm install gulp')); - process.exit(1); - } - - if (!env.configPath) { - gutil.log(chalk.red('No gulpfile found')); - process.exit(1); - } - - // Check for semver difference between cli and local installation - if (semver.gt(cliPackage.version, env.modulePackage.version)) { - gutil.log(chalk.red('Warning: gulp version mismatch:')); - gutil.log(chalk.red('Global gulp is', cliPackage.version)); - gutil.log(chalk.red('Local gulp is', env.modulePackage.version)); - } - - // Chdir before requiring gulpfile to make sure - // we let them chdir as needed - if (process.cwd() !== env.cwd) { - process.chdir(env.cwd); - gutil.log( - 'Working directory changed to', - chalk.magenta(tildify(env.cwd)) - ); - } - - // This is what actually loads up the gulpfile - require(env.configPath); - gutil.log('Using gulpfile', chalk.magenta(tildify(env.configPath))); - - var gulpInst = require(env.modulePath); - logEvents(gulpInst); - - process.nextTick(function() { - if (simpleTasksFlag) { - return logTasksSimple(env, gulpInst); - } - if (tasksFlag) { - return logTasks(env, gulpInst); - } - gulpInst.start.apply(gulpInst, toRun); - }); -} - -function logTasks(env, localGulp) { - var tree = taskTree(localGulp.tasks); - tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); - archy(tree) - .split('\n') - .forEach(function(v) { - if (v.trim().length === 0) { - return; - } - gutil.log(v); - }); -} - -function logTasksSimple(env, localGulp) { - console.log(Object.keys(localGulp.tasks) - .join('\n') - .trim()); -} - -// Format orchestrator errors -function formatError(e) { - if (!e.err) { - return e.message; - } - - // PluginError - if (typeof e.err.showStack === 'boolean') { - return e.err.toString(); - } - - // Normal error - if (e.err.stack) { - return e.err.stack; - } - - // Unknown (string, number, etc.) - return new Error(String(e.err)).stack; -} - -// Wire up logging events -function logEvents(gulpInst) { - - // Total hack due to poor error management in orchestrator - gulpInst.on('err', function() { - failed = true; - }); - - gulpInst.on('task_start', function(e) { - // TODO: batch these - // so when 5 tasks start at once it only logs one time with all 5 - gutil.log('Starting', '\'' + chalk.cyan(e.task) + '\'...'); - }); - - gulpInst.on('task_stop', function(e) { - var time = prettyTime(e.hrDuration); - gutil.log( - 'Finished', '\'' + chalk.cyan(e.task) + '\'', - 'after', chalk.magenta(time) - ); - }); - - gulpInst.on('task_err', function(e) { - var msg = formatError(e); - var time = prettyTime(e.hrDuration); - gutil.log( - '\'' + chalk.cyan(e.task) + '\'', - chalk.red('errored after'), - chalk.magenta(time) - ); - gutil.log(msg); - }); - - gulpInst.on('task_not_found', function(err) { - gutil.log( - chalk.red('Task \'' + err.task + '\' is not in your gulpfile') - ); - gutil.log('Please check the documentation for proper gulpfile formatting'); - process.exit(1); - }); -} +require('gulp-cli')(); diff --git a/completion/README.md b/completion/README.md deleted file mode 100644 index c0e8c913..00000000 --- a/completion/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Completion for gulp -> Thanks to grunt team and Tyler Kellen - -To enable tasks auto-completion in shell you should add `eval "$(gulp --completion=shell)"` in your `.shellrc` file. - -## Bash - -Add `eval "$(gulp --completion=bash)"` to `~/.bashrc`. - -## Zsh - -Add `eval "$(gulp --completion=zsh)"` to `~/.zshrc`. - -## Powershell - -Add `Invoke-Expression ((gulp --completion=powershell) -join [System.Environment]::NewLine)` to `$PROFILE`. - -## Fish - -Add `gulp --completion=fish | source` to `~/.config/fish/config.fish`. diff --git a/completion/bash b/completion/bash deleted file mode 100644 index 704c27c1..00000000 --- a/completion/bash +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# Borrowed from grunt-cli -# http://gruntjs.com/ -# -# Copyright (c) 2012 Tyler Kellen, contributors -# Licensed under the MIT license. -# https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT - -# Usage: -# -# To enable bash completion for gulp, add the following line (minus the -# leading #, which is the bash comment character) to your ~/.bashrc file: -# -# eval "$(gulp --completion=bash)" - -# Enable bash autocompletion. -function _gulp_completions() { - # The currently-being-completed word. - local cur="${COMP_WORDS[COMP_CWORD]}" - #Grab tasks - local compls=$(gulp --tasks-simple) - # Tell complete what stuff to show. - COMPREPLY=($(compgen -W "$compls" -- "$cur")) -} - -complete -o default -F _gulp_completions gulp diff --git a/completion/fish b/completion/fish deleted file mode 100644 index f27f2248..00000000 --- a/completion/fish +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env fish - -# Usage: -# -# To enable fish completion for gulp, add the following line to -# your ~/.config/fish/config.fish file: -# -# gulp --completion=fish | source - -complete -c gulp -a "(gulp --tasks-simple)" -f diff --git a/completion/powershell b/completion/powershell deleted file mode 100644 index 08ec4382..00000000 --- a/completion/powershell +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (c) 2014 Jason Jarrett -# -# Tab completion for the `gulp` -# -# Usage: -# -# To enable powershell completion for gulp you need to be running -# at least PowerShell v3 or greater and add the below to your $PROFILE -# -# Invoke-Expression ((gulp --completion=powershell) -join [System.Environment]::NewLine) -# -# - -$gulp_completion_Process = { - param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) - - - # Load up an assembly to read the gulpfile's sha1 - if(-not $global:GulpSHA1Managed) { - [Reflection.Assembly]::LoadWithPartialName("System.Security") | out-null - $global:GulpSHA1Managed = new-Object System.Security.Cryptography.SHA1Managed - } - - # setup a global (in-memory) cache - if(-not $global:GulpfileShaCache) { - $global:GulpfileShaCache = @{}; - } - - $cache = $global:GulpfileShaCache; - - # Get the gulpfile's sha1 - $sha1gulpFile = (resolve-path gulpfile.js -ErrorAction Ignore | %{ - $file = [System.IO.File]::Open($_.Path, "open", "read") - [string]::join('', ($global:GulpSHA1Managed.ComputeHash($file) | %{ $_.ToString("x2") })) - $file.Dispose() - }) - - # lookup the sha1 for previously cached task lists. - if($cache.ContainsKey($sha1gulpFile)){ - $tasks = $cache[$sha1gulpFile]; - } else { - $tasks = (gulp --tasks-simple).split("`n"); - $cache[$sha1gulpFile] = $tasks; - } - - - $tasks | - where { $_.startswith($commandName) } - Sort-Object | - foreach { New-Object System.Management.Automation.CompletionResult $_, $_, 'ParameterValue', ('{0}' -f $_) } -} - -if (-not $global:options) { - $global:options = @{ - CustomArgumentCompleters = @{}; - NativeArgumentCompleters = @{} - } -} - -$global:options['NativeArgumentCompleters']['gulp'] = $gulp_completion_Process -$function:tabexpansion2 = $function:tabexpansion2 -replace 'End\r\n{','End { if ($null -ne $options) { $options += $global:options} else {$options = $global:options}' diff --git a/completion/zsh b/completion/zsh deleted file mode 100644 index 8169b22d..00000000 --- a/completion/zsh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/zsh - -# Borrowed from grunt-cli -# http://gruntjs.com/ -# -# Copyright (c) 2012 Tyler Kellen, contributors -# Licensed under the MIT license. -# https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT - -# Usage: -# -# To enable zsh completion for gulp, add the following line (minus the -# leading #, which is the zsh comment character) to your ~/.zshrc file: -# -# eval "$(gulp --completion=zsh)" - -# Enable zsh autocompletion. -function _gulp_completion() { - # Grab tasks - compls=$(gulp --tasks-simple) - completions=(${=compls}) - compadd -- $completions -} - -compdef _gulp_completion gulp diff --git a/docs/CLI.md b/docs/CLI.md index 20fb0325..5bfd6792 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -10,7 +10,7 @@ gulp has very few flags to know about. All other flags are for tasks to use if n - `--cwd ` will manually set the CWD. The search for the gulpfile, as well as the relativity of all requires will be from here - `-T` or `--tasks` will display the task dependency tree for the loaded gulpfile - `--tasks-simple` will display a plaintext list of tasks for the loaded gulpfile -- `--verify` will verify plugins referenced in project's package.json against the plugins black list +- `--verify` will verify plugins referenced in project's package.json against the plugins blacklist - `--color` will force gulp and gulp plugins to display colors even when no color support is detected - `--no-color` will force gulp and gulp plugins to not display colors even when color support is detected - `--silent` will disable all gulp logging diff --git a/lib/blackList.js b/lib/blackList.js deleted file mode 100644 index b9f381ea..00000000 --- a/lib/blackList.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; - -var http = require('http'); - -/** - * Given a collection of plugin names verifies this collection against - * the black-list. Invokes callback with an object: - * [plugin name]=>[black-listing reason] - * or undefined if none of the plugins to check is black-listed. - * - * @param pluginsToVerify - an array of plugin names to verify - * @param cb - */ -module.exports = function (pluginsToVerify, cb) { - http.get('http://gulpjs.com/plugins/blackList.json', function (res) { - var blackListJSONStr = ''; - - res.on('data', function (chunk) { - blackListJSONStr += chunk; - }); - - res.on('end', function () { - var blackList = JSON.parse(blackListJSONStr); - var result = pluginsToVerify.reduce(function(blackListed, pluginName) { - if (blackList[pluginName]) { - blackListed = blackListed || {}; - blackListed[pluginName] = blackList[pluginName]; - return blackListed; - } - }); - cb(null, result); - }); - - }).on('error', function (e) { - cb(e); - }); -}; diff --git a/lib/completion.js b/lib/completion.js deleted file mode 100644 index 7000250b..00000000 --- a/lib/completion.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -var fs = require('fs'); -var path = require('path'); - -module.exports = function(name) { - if (typeof name !== 'string') { - throw new Error('Missing completion type'); - } - var file = path.join(__dirname, '../completion', name); - try { - console.log(fs.readFileSync(file, 'utf8')); - process.exit(0); - } catch (err) { - console.log( - 'echo "gulp autocompletion rules for', - '\'' + name + '\'', - 'not found"' - ); - process.exit(5); - } -}; diff --git a/lib/taskTree.js b/lib/taskTree.js deleted file mode 100644 index accb1a77..00000000 --- a/lib/taskTree.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -module.exports = function(tasks) { - return Object.keys(tasks) - .reduce(function(prev, task) { - prev.nodes.push({ - label: task, - nodes: tasks[task].dep, - }); - return prev; - }, { - nodes: [], - }); -}; diff --git a/lib/verifyDependencies.js b/lib/verifyDependencies.js deleted file mode 100644 index 25345847..00000000 --- a/lib/verifyDependencies.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; - -var chalk = require('chalk'); -var gutil = require('gulp-util'); -var blackList = require('./blackList'); -var formatError = require('./formatError'); - -module.exports = function verifyDependencies(depNames) { - - blackList(Object.keys(depNames), function(err, blackListed) { - if (err) { - gutil.log(chalk.red('Error: failed to retrieve plugins black-list')); - gutil.log(formatError(err)); - process.exit(1); - } - - if (blackListed) { - gutil.log(chalk.red('Black-listed plugins found in this project:')); - for (var blDependency in blackListed) { - gutil.log(blDependency + ': ' + blackListed[blDependency]); - } - process.exit(1); - } else { - gutil.log( - chalk.green('There are no black-listed plugins in this project') - ); - process.exit(0); - } - }); -}; diff --git a/package.json b/package.json index edf2e2e8..ba9d7eff 100644 --- a/package.json +++ b/package.json @@ -16,28 +16,17 @@ ], "files": [ "index.js", - "lib", - "bin", - "completion", - "gulp.1" + "bin" ], "bin": { "gulp": "./bin/gulp.js" }, "man": "gulp.1", "dependencies": { - "archy": "^1.0.0", - "chalk": "^1.0.0", "deprecated": "^0.0.1", + "gulp-cli": "^0.1.3", "gulp-util": "^3.0.0", - "interpret": "^1.0.0", - "liftoff": "^2.1.0", - "minimist": "^1.1.0", "orchestrator": "^0.3.0", - "pretty-hrtime": "^1.0.0", - "semver": "^4.1.0", - "tildify": "^1.0.0", - "v8flags": "^2.0.2", "vinyl-fs": "^0.3.0" }, "devDependencies": { @@ -48,7 +37,6 @@ "istanbul": "^0.3.0", "jscs": "^2.3.5", "jscs-preset-gulp": "^1.0.0", - "marked-man": "^0.1.3", "mkdirp": "^0.5.0", "mocha": "^2.0.1", "mocha-lcov-reporter": "^0.0.1", @@ -57,7 +45,6 @@ "should": "^5.0.1" }, "scripts": { - "prepublish": "marked-man --name gulp docs/CLI.md > gulp.1", "lint": "eslint . && jscs *.js bin/ lib/ test/", "pretest": "npm run lint", "test": "mocha --reporter spec", diff --git a/test/taskTree.js b/test/taskTree.js deleted file mode 100644 index 199eb1f2..00000000 --- a/test/taskTree.js +++ /dev/null @@ -1,42 +0,0 @@ -'use strict'; - -var taskTree = require('../lib/taskTree'); -var should = require('should'); - -require('mocha'); - -describe('taskTree()', function() { - it('should form a tree properly', function(done) { - should.exist(taskTree); // Lol shutup jshint - - var tasks = { - test: { - dep: ['abc', 'def'], - }, - abc: { - dep: ['def'], - }, - def: { - dep: [], - }, - }; - - var expectTree = { - nodes: [ - { - label: 'test', - nodes: ['abc', 'def'], - }, { - label: 'abc', - nodes: ['def'], - }, { - label: 'def', - nodes: [], - }, - ], - }; - - taskTree(tasks).should.eql(expectTree); - done(); - }); -}); From 9fda7b405e15aea6798277bd134b882251784fb4 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 24 Aug 2014 18:40:18 -0700 Subject: [PATCH 009/225] Breaking: Replace Orchestrator with Undertaker --- index.js | 44 ++------------ package.json | 3 +- test/tasks.js | 157 -------------------------------------------------- 3 files changed, 5 insertions(+), 199 deletions(-) delete mode 100644 test/tasks.js diff --git a/index.js b/index.js index 42bc69b3..a27af337 100644 --- a/index.js +++ b/index.js @@ -1,26 +1,13 @@ 'use strict'; var util = require('util'); -var Orchestrator = require('orchestrator'); -var gutil = require('gulp-util'); -var deprecated = require('deprecated'); +var Undertaker = require('undertaker'); var vfs = require('vinyl-fs'); function Gulp() { - Orchestrator.call(this); + Undertaker.call(this); } -util.inherits(Gulp, Orchestrator); - -Gulp.prototype.task = Gulp.prototype.add; -Gulp.prototype.run = function() { - // `run()` is deprecated as of 3.5 and will be removed in 4.0 - // Use task dependencies instead - - // Impose our opinion of "default" tasks onto orchestrator - var tasks = arguments.length ? arguments : ['default']; - - this.start.apply(this, tasks); -}; +util.inherits(Gulp, Undertaker); Gulp.prototype.src = vfs.src; Gulp.prototype.dest = vfs.dest; @@ -30,34 +17,11 @@ Gulp.prototype.watch = function(glob, opt, fn) { opt = null; } - // Array of tasks given - if (Array.isArray(fn)) { - return vfs.watch(glob, opt, function() { - this.start.apply(this, fn); - }.bind(this)); - } - - return vfs.watch(glob, opt, fn); + return vfs.watch(glob, opt, this.parallel(fn)); }; // Let people use this class from our instance Gulp.prototype.Gulp = Gulp; -// Deprecations -deprecated.field('gulp.env has been deprecated. ' + - 'Use your own CLI parser instead. ' + - 'We recommend using yargs or minimist.', - console.warn, - Gulp.prototype, - 'env', - gutil.env -); - -Gulp.prototype.run = deprecated.method('gulp.run() has been deprecated. ' + - 'Use task dependencies or gulp.watch task triggering instead.', - console.warn, - Gulp.prototype.run -); - var inst = new Gulp(); module.exports = inst; diff --git a/package.json b/package.json index ba9d7eff..666f8f27 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,9 @@ }, "man": "gulp.1", "dependencies": { - "deprecated": "^0.0.1", "gulp-cli": "^0.1.3", "gulp-util": "^3.0.0", - "orchestrator": "^0.3.0", + "undertaker": "^0.1.0", "vinyl-fs": "^0.3.0" }, "devDependencies": { diff --git a/test/tasks.js b/test/tasks.js deleted file mode 100644 index d5dcea19..00000000 --- a/test/tasks.js +++ /dev/null @@ -1,157 +0,0 @@ -'use strict'; - -var gulp = require('../'); -var Q = require('q'); -var should = require('should'); -require('mocha'); - -describe('gulp tasks', function() { - describe('task()', function() { - it('should define a task', function(done) { - var fn; - fn = function() {}; - gulp.task('test', fn); - should.exist(gulp.tasks.test); - gulp.tasks.test.fn.should.equal(fn); - gulp.reset(); - done(); - }); - }); - describe('run()', function() { - it('should run multiple tasks', function(done) { - var a, fn, fn2; - a = 0; - fn = function() { - this.should.equal(gulp); - ++a; - }; - fn2 = function() { - this.should.equal(gulp); - ++a; - }; - gulp.task('test', fn); - gulp.task('test2', fn2); - gulp.run('test', 'test2'); - a.should.equal(2); - gulp.reset(); - done(); - }); - it('should run all tasks when call run() multiple times', function(done) { - var a, fn, fn2; - a = 0; - fn = function() { - this.should.equal(gulp); - ++a; - }; - fn2 = function() { - this.should.equal(gulp); - ++a; - }; - gulp.task('test', fn); - gulp.task('test2', fn2); - gulp.run('test'); - gulp.run('test2'); - a.should.equal(2); - gulp.reset(); - done(); - }); - it('should run all async promise tasks', function(done) { - var a, fn, fn2; - a = 0; - fn = function() { - var deferred = Q.defer(); - setTimeout(function() { - ++a; - deferred.resolve(); - }, 1); - return deferred.promise; - }; - fn2 = function() { - var deferred = Q.defer(); - setTimeout(function() { - ++a; - deferred.resolve(); - }, 1); - return deferred.promise; - }; - gulp.task('test', fn); - gulp.task('test2', fn2); - gulp.run('test'); - gulp.run('test2', function() { - gulp.isRunning.should.equal(false); - a.should.equal(2); - gulp.reset(); - done(); - }); - gulp.isRunning.should.equal(true); - }); - it('should run all async callback tasks', function(done) { - var a, fn, fn2; - a = 0; - fn = function(cb) { - setTimeout(function() { - ++a; - cb(null); - }, 1); - }; - fn2 = function(cb) { - setTimeout(function() { - ++a; - cb(null); - }, 1); - }; - gulp.task('test', fn); - gulp.task('test2', fn2); - gulp.run('test'); - gulp.run('test2', function() { - gulp.isRunning.should.equal(false); - a.should.equal(2); - gulp.reset(); - done(); - }); - gulp.isRunning.should.equal(true); - }); - it('should emit task_not_found and throw an error when task is not defined', function(done) { - gulp.on('task_not_found', function(err) { - should.exist(err); - should.exist(err.task); - err.task.should.equal('test'); - gulp.reset(); - done(); - }); - try { - gulp.run('test'); - } catch (err) { - should.exist(err); - } - }); - it('should run task scoped to gulp', function(done) { - var a, fn; - a = 0; - fn = function() { - this.should.equal(gulp); - ++a; - }; - gulp.task('test', fn); - gulp.run('test'); - a.should.equal(1); - gulp.isRunning.should.equal(false); - gulp.reset(); - done(); - }); - it('should run default task scoped to gulp', function(done) { - var a, fn; - a = 0; - fn = function() { - this.should.equal(gulp); - ++a; - }; - gulp.task('default', fn); - gulp.run(); - a.should.equal(1); - gulp.isRunning.should.equal(false); - gulp.reset(); - done(); - }); - }); -}); From f787ba51569cc61439f731db9bfe0f0e2452a989 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 24 Aug 2014 20:21:25 -0700 Subject: [PATCH 010/225] Docs: Update syntax in readme example --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ca49c3c2..8e894f46 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ gulp.task('clean', function() { return del(['build']); }); -gulp.task('scripts', ['clean'], function() { +gulp.task('scripts', function() { // Minify and copy all JavaScript (except vendor scripts) // with sourcemaps all the way down return gulp.src(paths.scripts) @@ -60,7 +60,7 @@ gulp.task('scripts', ['clean'], function() { }); // Copy all static images -gulp.task('images', ['clean'], function() { +gulp.task('images', function() { return gulp.src(paths.images) // Pass in options to the task .pipe(imagemin({optimizationLevel: 5})) @@ -69,12 +69,13 @@ gulp.task('images', ['clean'], function() { // Rerun the task when a file changes gulp.task('watch', function() { - gulp.watch(paths.scripts, ['scripts']); - gulp.watch(paths.images, ['images']); + gulp.watch(paths.scripts, 'scripts'); + gulp.watch(paths.images, 'images'); }); +gulp.task('all', gulp.parallel('watch', 'scripts', 'images')); // The default task (called when you run `gulp` from cli) -gulp.task('default', ['watch', 'scripts', 'images']); +gulp.task('default', gulp.series('clean', 'all')); ``` ## Incremental Builds From 9abb0a4f96cc3d0989494e91b51c312ca1d5a589 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 24 Aug 2014 18:56:00 -0700 Subject: [PATCH 011/225] Update: Improve gulp.watch implementation & tests --- index.js | 16 +++-- package.json | 2 +- test/watch.js | 189 +++++++++++++++++++------------------------------- 3 files changed, 83 insertions(+), 124 deletions(-) diff --git a/index.js b/index.js index a27af337..13bc263c 100644 --- a/index.js +++ b/index.js @@ -11,13 +11,21 @@ util.inherits(Gulp, Undertaker); Gulp.prototype.src = vfs.src; Gulp.prototype.dest = vfs.dest; -Gulp.prototype.watch = function(glob, opt, fn) { - if (typeof opt === 'function' || Array.isArray(opt)) { - fn = opt; +Gulp.prototype.watch = function(glob, opt, task) { + var isFunction = (typeof opt === 'function'); + var isString = (typeof opt === 'string'); + var isArray = Array.isArray(opt); + if (isFunction || isString || isArray) { + task = opt; opt = null; } - return vfs.watch(glob, opt, this.parallel(fn)); + var fn; + if (task) { + fn = this.parallel(task); + } + + return vfs.watch(glob, opt, fn); }; // Let people use this class from our instance diff --git a/package.json b/package.json index 666f8f27..12cb3f37 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "should": "^5.0.1" }, "scripts": { - "lint": "eslint . && jscs *.js bin/ lib/ test/", + "lint": "eslint . && jscs *.js bin/ test/", "pretest": "npm run lint", "test": "mocha --reporter spec", "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" diff --git a/test/watch.js b/test/watch.js index e299cf90..335ca771 100644 --- a/test/watch.js +++ b/test/watch.js @@ -11,168 +11,119 @@ require('mocha'); var outpath = path.join(__dirname, './out-fixtures'); +var tempFileContent = 'A test generated this file and it is safe to delete'; + +function createTempFile(path) { + fs.writeFileSync(path, tempFileContent); +} + +function updateTempFile(path) { + var gazeTimeout = 125; + setTimeout(function() { + fs.appendFileSync(path, ' changed'); + }, gazeTimeout); +} + describe('gulp', function() { describe('watch()', function() { beforeEach(rimraf.bind(null, outpath)); beforeEach(mkdirp.bind(null, outpath)); afterEach(rimraf.bind(null, outpath)); - var tempFileContent = 'A test generated this file and it is safe to delete'; - - var writeTimeout = 125; // Wait for it to get to the filesystem - var writeFileWait = function(name, content, cb) { - if (!cb) { - cb = function() {}; - } - setTimeout(function() { - fs.writeFile(name, content, cb); - }, writeTimeout); - }; - it('should call the function when file changes: no options', function(done) { - - // Arrange var tempFile = path.join(outpath, 'watch-func.txt'); - fs.writeFile(tempFile, tempFileContent, function() { - // Assert: it works if it calls done - var watcher = gulp.watch(tempFile, function(evt) { - should.exist(evt); - should.exist(evt.path); - should.exist(evt.type); - evt.type.should.equal('changed'); - evt.path.should.equal(path.resolve(tempFile)); - watcher.end(); - done(); - }); + createTempFile(tempFile); - // Act: change file - writeFileWait(tempFile, tempFileContent + ' changed'); + var watcher = gulp.watch(tempFile, function(cb) { + watcher.end(); + cb(); + done(); }); + + updateTempFile(tempFile); }); it('should call the function when file changes: w/ options', function(done) { - - // Arrange var tempFile = path.join(outpath, 'watch-func-options.txt'); - fs.writeFile(tempFile, tempFileContent, function() { - // Assert: it works if it calls done - var watcher = gulp.watch(tempFile, { debounceDelay: 5 }, function(evt) { - should.exist(evt); - should.exist(evt.path); - should.exist(evt.type); - evt.type.should.equal('changed'); - evt.path.should.equal(path.resolve(tempFile)); - watcher.end(); - done(); - }); + createTempFile(tempFile); - // Act: change file - writeFileWait(tempFile, tempFileContent + ' changed'); + var watcher = gulp.watch(tempFile, {debounceDelay: 5}, function(cb) { + watcher.end(); + cb(); + done(); }); + + updateTempFile(tempFile); }); it('should not drop options when no callback specified', function(done) { - // Arrange var tempFile = path.join(outpath, 'watch-func-nodrop-options.txt'); // By passing a cwd option, ensure options are not lost to gaze var relFile = '../watch-func-nodrop-options.txt'; var cwd = outpath + '/subdir'; - fs.writeFile(tempFile, tempFileContent, function() { - - // Assert: it works if it calls done - var watcher = gulp.watch(relFile, { debounceDelay: 5, cwd: cwd }) - .on('change', function(evt) { - should.exist(evt); - should.exist(evt.path); - should.exist(evt.type); - evt.type.should.equal('changed'); - evt.path.should.equal(path.resolve(tempFile)); - watcher.end(); - done(); - }); - - // Act: change file - writeFileWait(tempFile, tempFileContent + ' changed'); - }); + + createTempFile(tempFile); + + var watcher = gulp.watch(relFile, {debounceDelay: 5, cwd: cwd}) + .on('change', function(evt) { + should.exist(evt); + should.exist(evt.path); + should.exist(evt.type); + evt.type.should.equal('changed'); + evt.path.should.equal(path.resolve(tempFile)); + watcher.end(); + done(); + }); + + updateTempFile(tempFile); }); it('should run many tasks: w/ options', function(done) { - // Arrange var tempFile = path.join(outpath, 'watch-task-options.txt'); - var task1 = 'task1'; - var task2 = 'task2'; - var task3 = 'task3'; var a = 0; - var timeout = writeTimeout * 2.5; - fs.writeFile(tempFile, tempFileContent, function() { + createTempFile(tempFile); - gulp.task(task1, function() { - a++; - }); - gulp.task(task2, function() { - a += 10; - }); - gulp.task(task3, function() { - throw new Error('task3 called!'); - }); - - // It works if it calls the task - var config = { debounceDelay: timeout / 2 }; - var watcher = gulp.watch(tempFile, config, [task1, task2]); - - // Assert - setTimeout(function() { - a.should.equal(11); // Task1 and task2 + gulp.task('task1', function(cb) { + a++; + cb(); + }); + gulp.task('task2', function(cb) { + a += 10; + a.should.equal(11); + watcher.end(); + cb(); + done(); + }); - gulp.reset(); - watcher.end(); - done(); - }, timeout); + var watcher = gulp.watch(tempFile, {debounceDelay: 25}, gulp.series('task1', 'task2')); - // Act: change file - writeFileWait(tempFile, tempFileContent + ' changed'); - }); + updateTempFile(tempFile); }); it('should run many tasks: no options', function(done) { - // Arrange var tempFile = path.join(outpath, 'watch-many-tasks-no-options.txt'); - var task1 = 'task1'; - var task2 = 'task2'; - var task3 = 'task3'; var a = 0; - var timeout = writeTimeout * 2.5; - - fs.writeFile(tempFile, tempFileContent, function() { - - gulp.task(task1, function() { - a++; - }); - gulp.task(task2, function() { - a += 10; - }); - gulp.task(task3, function() { - throw new Error('task3 called!'); - }); - // It works if it calls the task - var watcher = gulp.watch(tempFile, [task1, task2]); + createTempFile(tempFile); - // Assert - setTimeout(function() { - a.should.equal(11); // Task1 and task2 + gulp.task('task1', function(cb) { + a++; + cb(); + }); + gulp.task('task2', function(cb) { + a += 10; + a.should.equal(11); + watcher.end(); + cb(); + done(); + }); - gulp.reset(); - watcher.end(); - done(); - }, timeout); + var watcher = gulp.watch(tempFile, gulp.series('task1', 'task2')); - // Act: change file - writeFileWait(tempFile, tempFileContent + ' changed'); - }); + updateTempFile(tempFile); }); }); From d331a4e73bf257f334e55ac722bfae64adb45d53 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 30 Aug 2014 15:23:13 -0700 Subject: [PATCH 012/225] Docs: Add 4.0 changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74e9767d..939c7acb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # gulp changelog +## 4.0.0 + +- removed task dependency graph, everything must be composed using `gulp.series` or `gulp.parallel` +- removed 3 argument syntax for `gulp.task` due to task dependency graph being removed. +- added `gulp.series` and `gulp.parallel` methods for composing tasks. +- added single argument syntax for `gulp.task` which allows a named function to be used as the name of the task and task function. +- added `gulp.tree` method for retrieving the task tree. Pass `{ deep: true }` for an `archy` compatible node list. +- added `--verify` flag to check the dependencies in package.json against the plugin blacklist. +- added `gulp.registry` for setting custom registries. + ## 3.9.1 - update interpret to 1.0.0 (support for babel-register) From 6830560bb5d2a4e446d9d2811a8a7d71d38a5868 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 16 Nov 2014 16:10:22 -0700 Subject: [PATCH 013/225] Upgrade: Update undertaker --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 12cb3f37..6d5e7db4 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dependencies": { "gulp-cli": "^0.1.3", "gulp-util": "^3.0.0", - "undertaker": "^0.1.0", + "undertaker": "^0.3.0", "vinyl-fs": "^0.3.0" }, "devDependencies": { From 2d0fa20a030c3111e6ec67be087d8b0c84364f49 Mon Sep 17 00:00:00 2001 From: Eric Schoffstall Date: Sat, 27 Dec 2014 16:47:18 -0800 Subject: [PATCH 014/225] Docs: Update changelog --- CHANGELOG.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 939c7acb..ade4772b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,21 @@ ## 4.0.0 -- removed task dependency graph, everything must be composed using `gulp.series` or `gulp.parallel` -- removed 3 argument syntax for `gulp.task` due to task dependency graph being removed. -- added `gulp.series` and `gulp.parallel` methods for composing tasks. -- added single argument syntax for `gulp.task` which allows a named function to be used as the name of the task and task function. -- added `gulp.tree` method for retrieving the task tree. Pass `{ deep: true }` for an `archy` compatible node list. +- replaced 3.x task system (orchestrator) with new task system (bach) + - removed gulp.reset + - removed 3 argument syntax for `gulp.task` + - using strings when registering with `gulp.task` should only be done when you will call the task with the CLI + - added `gulp.series` and `gulp.parallel` methods for composing tasks. Everything must use these now. + - added single argument syntax for `gulp.task` which allows a named function to be used as the name of the task and task function. + - added `gulp.tree` method for retrieving the task tree. Pass `{ deep: true }` for an `archy` compatible node list. + - added `gulp.registry` for setting custom registries. - added `--verify` flag to check the dependencies in package.json against the plugin blacklist. -- added `gulp.registry` for setting custom registries. +- added `gulp.symlink` which functions exactly like `gulp.dest`, but symlinks instead. +- added `dirMode` param to `gulp.dest` and `gulp.symlink` which allows better control over the mode of the destination folder that is created. +- globs passed to `gulp.src` will be evaluated in order, which means this is possible `gulp.src(['*.js', '!b*.js', 'bad.js'])` (exclude every JS file that starts with a b except bad.js) +- added `since` option to `gulp.src` which lets you only match files that have been modified since a certain date (for incremental builds) +- split CLI out into a module if you want to save bandwidth/disk space. you can install the gulp CLI using either `npm install gulp -g` or `npm install gulp-cli -g`, where gulp-cli is the smaller one (no module code included) +- add `--tasks-json` flag to CLI to dump the whole tree out for other tools to consume ## 3.9.1 From 6095f350486ea47fc2d8203a68980230b3573af1 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 10 Jan 2015 17:07:25 -0700 Subject: [PATCH 015/225] Update: Remove gulp-util & depend on unpublished gulp-cli --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 6d5e7db4..28e782d5 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,7 @@ }, "man": "gulp.1", "dependencies": { - "gulp-cli": "^0.1.3", - "gulp-util": "^3.0.0", + "gulp-cli": "gulpjs/gulp-cli#4.0", "undertaker": "^0.3.0", "vinyl-fs": "^0.3.0" }, From fa85999b3e12627370891332f7e281c5341aea1c Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 14:25:16 -0700 Subject: [PATCH 016/225] Release: 4.0.0-alpha.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 28e782d5..45dbe3b0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "gulp", "description": "The streaming build system", - "version": "3.9.1", + "version": "4.0.0-alpha.1", "homepage": "http://gulpjs.com", "repository": "gulpjs/gulp", "author": "Fractal (http://wearefractal.com/)", From cac9a8ad10f92ef3d3206cd5143700499281363c Mon Sep 17 00:00:00 2001 From: Contra Date: Mon, 26 Jan 2015 13:53:53 -0800 Subject: [PATCH 017/225] Update: Use unpublished vinyl-fs version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45dbe3b0..90f654e1 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dependencies": { "gulp-cli": "gulpjs/gulp-cli#4.0", "undertaker": "^0.3.0", - "vinyl-fs": "^0.3.0" + "vinyl-fs": "wearefractal/vinyl-fs" }, "devDependencies": { "coveralls": "^2.7.0", From 87e9cb687356b666cb6a67af44c62ed7bc42b68d Mon Sep 17 00:00:00 2001 From: Contra Date: Mon, 23 Feb 2015 15:17:11 -0800 Subject: [PATCH 018/225] Docs: Improve changelog --- CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ade4772b..32864677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 4.0.0 +### Task system changes + - replaced 3.x task system (orchestrator) with new task system (bach) - removed gulp.reset - removed 3 argument syntax for `gulp.task` @@ -10,13 +12,23 @@ - added single argument syntax for `gulp.task` which allows a named function to be used as the name of the task and task function. - added `gulp.tree` method for retrieving the task tree. Pass `{ deep: true }` for an `archy` compatible node list. - added `gulp.registry` for setting custom registries. + +### CLI changes + +- split CLI out into a module if you want to save bandwidth/disk space. you can install the gulp CLI using either `npm install gulp -g` or `npm install gulp-cli -g`, where gulp-cli is the smaller one (no module code included) +- add `--tasks-json` flag to CLI to dump the whole tree out for other tools to consume - added `--verify` flag to check the dependencies in package.json against the plugin blacklist. + +### vinyl/vinyl-fs changes + - added `gulp.symlink` which functions exactly like `gulp.dest`, but symlinks instead. - added `dirMode` param to `gulp.dest` and `gulp.symlink` which allows better control over the mode of the destination folder that is created. - globs passed to `gulp.src` will be evaluated in order, which means this is possible `gulp.src(['*.js', '!b*.js', 'bad.js'])` (exclude every JS file that starts with a b except bad.js) +- performance for gulp.src has improved massively + - `gulp.src(['**/*', '!b.js'])` will no longer eat CPU since negations happen during walking now - added `since` option to `gulp.src` which lets you only match files that have been modified since a certain date (for incremental builds) -- split CLI out into a module if you want to save bandwidth/disk space. you can install the gulp CLI using either `npm install gulp -g` or `npm install gulp-cli -g`, where gulp-cli is the smaller one (no module code included) -- add `--tasks-json` flag to CLI to dump the whole tree out for other tools to consume +- fixed `gulp.src` not following symlinks +- added `overwrite` option to `gulp.dest` which allows you to enable or disable overwriting of existing files ## 3.9.1 From 0ac0a0ec0c2fff79099a4c42d353069093287dab Mon Sep 17 00:00:00 2001 From: Damien Lebrun Date: Sun, 1 Mar 2015 00:14:03 +0000 Subject: [PATCH 019/225] Docs: Add gulp.series/gulp.parallel APIs, update gulp.task API & vinyl-fs options --- README.md | 2 +- docs/API.md | 370 ++++++++++++------ docs/getting-started.md | 3 +- .../combining-streams-to-handle-errors.md | 19 +- docs/recipes/delete-files-folder.md | 4 +- .../incremental-builds-with-concatenate.md | 2 +- ...tain-directory-structure-while-globbing.md | 2 +- docs/recipes/make-stream-from-buffer.md | 52 ++- docs/recipes/mocha-test-runner-with-gulp.md | 8 +- docs/recipes/running-tasks-in-series.md | 109 +++--- ...erver-with-livereload-and-css-injection.md | 4 +- docs/recipes/using-external-config-file.md | 11 +- 12 files changed, 377 insertions(+), 209 deletions(-) diff --git a/README.md b/README.md index 8e894f46..b492ea7d 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ var paths = { }; // Not all tasks need to use streams -// A gulpfile is just another node program and you can use any package available on npm +// A gulpfile is just another node program and you can use all packages available on npm gulp.task('clean', function() { // You can use multiple globbing patterns as you would with `gulp.src` return del(['build']); diff --git a/docs/API.md b/docs/API.md index b5fac15b..6c2443e7 100644 --- a/docs/API.md +++ b/docs/API.md @@ -8,10 +8,8 @@ Jump to: ### gulp.src(globs[, options]) -Emits files matching provided glob or an array of globs. -Returns a [stream](https://nodejs.org/api/stream.html) of [Vinyl files](https://github.com/gulpjs/vinyl-fs) -that can be [piped](https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options) -to plugins. +Emits files matching provided glob or array of globs. +Returns a [stream] of [Vinyl files] that can be [piped] to plugins. ```javascript gulp.src('client/templates/*.pug') @@ -20,6 +18,8 @@ gulp.src('client/templates/*.pug') .pipe(gulp.dest('build/minified_templates')); ``` +`glob` refers to [node-glob syntax][node-glob] or it can be a direct file path. + #### globs Type: `String` or `Array` @@ -37,33 +37,48 @@ The following expression matches `a.js` and `bad.js`: gulp.src(['client/*.js', '!client/b*.js', 'client/bad.js']) +Note that globs are evaluated in order, which means this is possible: +``` +// exclude every JS file that starts with a b except bad.js +gulp.src(['*.js', '!b*.js', 'bad.js']) +``` + #### options Type: `Object` Options to pass to [node-glob] through [glob-stream]. -gulp supports all [options supported by node-glob][node-glob documentation] and [glob-stream] except `ignore` and adds the following options. +gulp adds some additional options in addition to the +[options supported by node-glob][node-glob documentation] and [glob-stream]: ##### options.buffer Type: `Boolean` + Default: `true` -Setting this to `false` will return `file.contents` as a stream and not buffer files. This is useful when working with large files. **Note:** Plugins might not implement support for streams. +Setting this to `false` will return `file.contents` as a stream and not +buffer files. This is useful when working with large files. + +**Note:** Plugins might not implement support for streams. ##### options.read Type: `Boolean` + Default: `true` -Setting this to `false` will return `file.contents` as null and not read the file at all. +Setting this to `false` will return `file.contents` as null and not read +the file at all. ##### options.base Type: `String` -Default: everything before a glob starts (see [glob2base]) + +Default: everything before a glob starts (see [glob-parent]) E.g., consider `somefile.js` in `client/js/somedir`: ```js -gulp.src('client/js/**/*.js') // Matches 'client/js/somedir/somefile.js' and resolves `base` to `client/js/` +// Matches 'client/js/somedir/somefile.js' and resolves `base` to `client/js/` +gulp.src('client/js/**/*.js') .pipe(minify()) .pipe(gulp.dest('build')); // Writes 'build/somedir/somefile.js' @@ -72,9 +87,25 @@ gulp.src('client/js/**/*.js', { base: 'client' }) .pipe(gulp.dest('build')); // Writes 'build/js/somedir/somefile.js' ``` +##### options.since +Type: `Date` or `Number` + +Setting this to a Date or a time stamp will discard any file that have not been +modified since the time specified. + +##### options.passthrough +Type: `Boolean` + +Default: `false` + +If true, it will create a duplex stream which passes items through and +emits globbed files. + + ### gulp.dest(path[, options]) -Can be piped to and it will write files. Re-emits all data passed to it so you can pipe to multiple folders. Folders that don't exist will be created. +Can be piped to and it will write files. Re-emits all data passed to it so you +can pipe to multiple folders. Folders that don't exist will be created. ```javascript gulp.src('./client/templates/*.pug') @@ -85,32 +116,83 @@ gulp.src('./client/templates/*.pug') ``` The write path is calculated by appending the file relative path to the given -destination directory. In turn, relative paths are calculated against the file base. -See `gulp.src` above for more info. +destination directory. In turn, relative paths are calculated against +the file base. See `gulp.src` above for more info. #### path Type: `String` or `Function` -The path (output folder) to write files to. Or a function that returns it, the function will be provided a [vinyl File instance](https://github.com/gulpjs/vinyl). +The path (output folder) to write files to. Or a function that returns it, +the function will be provided a [vinyl File instance]. #### options Type: `Object` ##### options.cwd Type: `String` + Default: `process.cwd()` -`cwd` for the output folder, only has an effect if provided output folder is relative. +`cwd` for the output folder, only has an effect if provided output folder is +relative. ##### options.mode +Type: `String` or `Number` + +Default: the mode of the input file (file.stat.mode) or the process mode +if the input file has no mode property. + +Octal permission specifying the mode the files should be created with: e.g. +`"0744"`, `0744` or `484` (`0744` in base 10). + +##### options.dirMode +Type: `String` or `Number` + +Default: Default is the process mode. + +Octal permission specifying the mode the directory should be created with: e.g. +`"0755"`, `0755` or `493` (`0755` in base 10). + +##### options.overwrite +Type: `Boolean` + +Default: `true` + +Specify if existing files with the same path should be overwritten or not. + + +### gulp.symlink(folder[, options]) + +Functions exactly like `gulp.dest`, but will create symlinks instead of copying +a directory. + +#### folder +Type: `String` or `Function` + +A folder path or a function that receives in a file and returns a folder path. + +#### options +Type: `Object` + +##### options.cwd Type: `String` -Default: `0777` -Octal permission string specifying mode for any folders that need to be created for output folder. +Default: `process.cwd()` + +`cwd` for the output folder, only has an effect if provided output folder is +relative. + +##### options.dirMode +Type: `String` or `Number` + +Default: Default is the process mode. + +Octal permission specifying the mode the directory should be created with: e.g. +`"0755"`, `0755` or `493` (`0755` in base 10). -### gulp.task(name [, deps] [, fn]) +### gulp.task([name,] fn) -Define a task using [Orchestrator]. +Define a task using [Undertaker]. ```js gulp.task('somename', function() { @@ -121,20 +203,27 @@ gulp.task('somename', function() { #### name Type: `String` -The name of the task. Tasks that you want to run from the command line should not have spaces in them. +Optional, The name of the task. Tasks that you want to run from the command line +should not have spaces in them. -#### deps -Type: `Array` +If the name is not provided, the task will be named after the function +`name` attribute, set on any named function. -An array of tasks to be executed and completed before your task will run. +[Function.name] is not writable; it cannot be set or edited. +It will be empty for anonymous functions: ```js -gulp.task('mytask', ['array', 'of', 'task', 'names'], function() { - // Do stuff -}); +function foo() {}; +foo.name === 'foo' // true + +var bar = function() {}; +bar.name === '' // true + +bar.name = 'bar' +bar.name === '' // true ``` -**Note:** Are your tasks running before the dependencies are complete? Make sure your dependency tasks are correctly using the async run hints: take in a callback or return a promise or event stream. +You should either provide the task name or avoid anonymous functions. You can also omit the function if you only want to run a bundle of dependency tasks: @@ -147,35 +236,31 @@ gulp.task('build', ['array', 'of', 'task', 'names']); #### fn Type: `Function` -The function performs the task's main operations. Generally this takes the form of: - -```js -gulp.task('buildStuff', function() { - // Do something that "builds stuff" - var stream = gulp.src(/*some source path*/) - .pipe(somePlugin()) - .pipe(someOtherPlugin()) - .pipe(gulp.dest(/*some destination*/)); - - return stream; - }); +The function that performs the task's operations. Generally it takes this form: ``` +gulp.task('somename', function() { + return gulp.src(['some/glob/**/*.ext']).pipe(someplugin()); +}) +``` + +Gulp tasks are asynchronous and Gulp uses [async-done] to wait for the tasks' +completion. Tasks are called with a callback parameter to call to signal +completion. Alternatively, Task can return a stream, a promise, a child process +or a RxJS observable to signal the end of the task. -#### Async task support +**Warning:** Sync tasks are not supported and your function will never complete +if the one of the above strategies is not used to signal completion. However, +thrown errors will be caught by Gulp. -Tasks can be made asynchronous if its `fn` does one of the following: +#### Async support ##### Accept a callback -```javascript -// run a command in a shell -var exec = require('child_process').exec; -gulp.task('jekyll', function(cb) { - // build Jekyll - exec('jekyll build', function(err) { - if (err) return cb(err); // return error - cb(); // finished task - }); +```js +var del = require('del'); + +gulp.task('clean', function(done) { + del(['.build/'], done); }); // use an async result in a pipe @@ -190,96 +275,143 @@ gulp.task('somename', function(cb) { }); ``` +The callback accepts an optional `Error` object. If it receives an error, +the task will fail. + ##### Return a stream ```js gulp.task('somename', function() { - var stream = gulp.src('client/**/*.js') + return gulp.src('client/**/*.js') .pipe(minify()) .pipe(gulp.dest('build')); - return stream; }); ``` ##### Return a promise -```javascript -var Q = require('q'); +```js +var Promise = require('promise'); +var del = require('del'); + +gulp.task('clean', function() { + return new Promise(function (resolve, reject) { + del(['.build/'], function(err) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); +}); +``` -gulp.task('somename', function() { - var deferred = Q.defer(); +or: +```js +var promisedDel = require('promised-del'); - // do async stuff - setTimeout(function() { - deferred.resolve(); - }, 1); +gulp.task('clean', function() { + return promisedDel(['.build/']); +}); +``` - return deferred.promise; +##### Return a child process + +```js +gulp.task('clean', function() { + return spawn('rm', ['-rf', path.join(__dirname, 'build')]); }); + ``` -**Note:** By default, tasks run with maximum concurrency -- e.g. it launches all the tasks at once and waits for nothing. If you want to create a series where tasks run in a particular order, you need to do two things: +##### Return a [RxJS] observable -- give it a hint to tell it when the task is done, -- and give it a hint that a task depends on completion of another. +```js +var Observable = require('rx').Observable; -For these examples, let's presume you have two tasks, "one" and "two" that you specifically want to run in this order: +gulp.task('sometask', function() { + return Observable.return(42); +}); +``` -1. In task "one" you add a hint to tell it when the task is done. Either take in a callback and call it when you're -done or return a promise or stream that the engine should wait to resolve or end respectively. -2. In task "two" you add a hint telling the engine that it depends on completion of the first task. +### gulp.parallel(...tasks) -So this example would look like this: +Takes a number of task names or functions and returns a function of the composed +tasks or functions. -```js -var gulp = require('gulp'); +When using task names, the task should already be registered. -// takes in a callback so the engine knows when it'll be done -gulp.task('one', function(cb) { - // do stuff -- async or otherwise - cb(err); // if err is not null and not undefined, the run will stop, and note that it failed +When the returned function is executed, the tasks or functions will be executed +in parallel, all being executed at the same time. If an error occurs, +all execution will complete. + +```js +gulp.task('one', function(done) { + // do stuff + done(); }); -// identifies a dependent task must be complete before this one begins -gulp.task('two', ['one'], function() { - // task 'one' is done now +gulp.task('two', function(done) { + // do stuff + done(); }); -gulp.task('default', ['one', 'two']); +gulp.task('default', gulp.parallel('one', 'two', function(done) { + // do more stuff + done(); +})); ``` +#### tasks +Type: `Array`, `String` or `Function` -### gulp.watch(glob [, opts], tasks) or gulp.watch(glob [, opts, cb]) +A task name, a function or an array of either. -Watch files and do something when a file changes. This always returns an EventEmitter that emits `change` events. -### gulp.watch(glob[, opts], tasks) +### gulp.series(...tasks) -#### glob -Type: `String` or `Array` +Takes a number of task names or functions and returns a function of the composed +tasks or functions. -A single glob or array of globs that indicate which files to watch for changes. +When using task names, the task should already be registered. -#### opts -Type: `Object` +When the returned function is executed, the tasks or functions will be executed +in series, each waiting for the prior to finish. If an error occurs, +execution will stop. -Options, that are passed to [`gaze`](https://github.com/shama/gaze). +```js +gulp.task('one', function(done) { + // do stuff + done(); +}); + +gulp.task('two', function(done) { + // do stuff + done(); +}); + +gulp.task('default', gulp.series('one', 'two', function(done) { + // do more stuff + done(); +})); +``` #### tasks -Type: `Array` +Type: `Array`, `String` or `Function` + +A task name, a function or an array of either. -Names of task(s) to run when a file changes, added with `gulp.task()` + +### gulp.watch(glob[, opts], tasks) + +Watch files and do something when a file changes. ```js -var watcher = gulp.watch('js/**/*.js', ['uglify','reload']); -watcher.on('change', function(event) { - console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); -}); +gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); ``` -### gulp.watch(glob[, opts, cb]) - #### glob Type: `String` or `Array` @@ -288,36 +420,50 @@ A single glob or array of globs that indicate which files to watch for changes. #### opts Type: `Object` -Options, that are passed to [`gaze`](https://github.com/shama/gaze). +Options, that are passed to [`gaze`][gaze]. -#### cb(event) -Type: `Function` +#### tasks +Type: `Array`, `Function` or `String` + +A task name, a function or an array of either to run when a file changes. -Callback to be called on each change. +When `tasks` is an array, the tasks will be run in parallel: +``` +gulp.watch('*.js', [one, two]); +// is equivalent to +gulp.watch('*.js', gulp.parallel(one, two)); +``` +`gulp.watch` returns an `EventEmitter` object which emits `change` events with +the [gaze] `event`: ```js -gulp.watch('js/**/*.js', function(event) { - console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); +var watcher = gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); +watcher.on('change', function(event) { + console.log('File ' + event.path + ' was ' + event.type); }); ``` -The callback will be passed an object, `event`, that describes the change: - ##### event.type -Type: `String` +Type: String -The type of change that occurred, either `added`, `changed`, `deleted` or `renamed`. +The type of change that occurred, either "added", "changed" or "deleted". ##### event.path -Type: `String` +Type: String The path to the file that triggered the event. - -[node-glob]: https://github.com/isaacs/node-glob -[node-glob documentation]: https://github.com/isaacs/node-glob#options -[node-glob syntax]: https://github.com/isaacs/node-glob +[Function.name]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name +[gaze]: https://github.com/shama/gaze [glob-stream]: https://github.com/gulpjs/glob-stream +[glob-parent]: https://github.com/es128/glob-parent [gulp-if]: https://github.com/robrich/gulp-if -[Orchestrator]: https://github.com/robrich/orchestrator -[glob2base]: https://github.com/wearefractal/glob2base +[node-glob documentation]: https://github.com/isaacs/node-glob#options +[node-glob]: https://github.com/isaacs/node-glob +[piped]: http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options +[RxJS]: https://www.npmjs.com/package/rx +[stream]: http://nodejs.org/api/stream.html +[async-done]: https://www.npmjs.com/package/async-done +[Undertaker]: https://github.com/phated/undertaker +[vinyl File instance]: https://github.com/gulpjs/vinyl +[Vinyl files]: https://github.com/gulpjs/vinyl-fs diff --git a/docs/getting-started.md b/docs/getting-started.md index 980c2218..06e0c9b8 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -37,8 +37,9 @@ In your project directory, create a file named `gulpfile.js` in your project roo ```js var gulp = require('gulp'); -gulp.task('default', function() { +gulp.task('default', function(done) { // place code for your default task here + done(); }); ``` diff --git a/docs/recipes/combining-streams-to-handle-errors.md b/docs/recipes/combining-streams-to-handle-errors.md index e376f6db..7c38654a 100644 --- a/docs/recipes/combining-streams-to-handle-errors.md +++ b/docs/recipes/combining-streams-to-handle-errors.md @@ -12,16 +12,13 @@ var uglify = require('gulp-uglify'); var gulp = require('gulp'); gulp.task('test', function() { - var combined = combiner.obj([ - gulp.src('bootstrap/js/*.js'), - uglify(), - gulp.dest('public/bootstrap') - ]); - - // any errors in the above streams will get caught - // by this listener, instead of being thrown: - combined.on('error', console.error.bind(console)); - - return combined; + return combiner.obj([ + gulp.src('bootstrap/js/*.js'), + uglify(), + gulp.dest('public/bootstrap') + ]) + // any errors in the above streams will get caught + // by this listener, instead of being thrown: + .on('error', console.error.bind(console)); }); ``` diff --git a/docs/recipes/delete-files-folder.md b/docs/recipes/delete-files-folder.md index 05e37762..1373ce6a 100644 --- a/docs/recipes/delete-files-folder.md +++ b/docs/recipes/delete-files-folder.md @@ -39,7 +39,7 @@ gulp.task('clean:mobile', function () { ]); }); -gulp.task('default', ['clean:mobile']); +gulp.task('default', gulp.series('clean:mobile')); ``` @@ -76,7 +76,7 @@ gulp.task('clean:tmp', function () { .pipe(gulp.dest('dist')); }); -gulp.task('default', ['clean:tmp']); +gulp.task('default', gulp.series('clean:tmp')); ``` This will only delete the tmp dir. diff --git a/docs/recipes/incremental-builds-with-concatenate.md b/docs/recipes/incremental-builds-with-concatenate.md index a1435eb8..c9fdaa0d 100644 --- a/docs/recipes/incremental-builds-with-concatenate.md +++ b/docs/recipes/incremental-builds-with-concatenate.md @@ -27,7 +27,7 @@ gulp.task('scripts', function() { }); gulp.task('watch', function () { - var watcher = gulp.watch(scriptsGlob, ['scripts']); // watch the same files in our scripts task + var watcher = gulp.watch(scriptsGlob, gulp.series('scripts')); // watch the same files in our scripts task watcher.on('change', function (event) { if (event.type === 'deleted') { // if a file is deleted, forget about it delete cached.caches.scripts[event.path]; // gulp-cached remove api diff --git a/docs/recipes/maintain-directory-structure-while-globbing.md b/docs/recipes/maintain-directory-structure-while-globbing.md index 95d64469..aadd32ef 100644 --- a/docs/recipes/maintain-directory-structure-while-globbing.md +++ b/docs/recipes/maintain-directory-structure-while-globbing.md @@ -27,7 +27,7 @@ If you want to maintain the structure, you need to pass `{base: '.'}` to `gulp.s ```js gulp.task('task', function () { - gulp.src(['index.html', + return gulp.src(['index.html', 'css/**', 'js/**', 'lib/**', diff --git a/docs/recipes/make-stream-from-buffer.md b/docs/recipes/make-stream-from-buffer.md index 1125451f..f11c1161 100644 --- a/docs/recipes/make-stream-from-buffer.md +++ b/docs/recipes/make-stream-from-buffer.md @@ -35,7 +35,6 @@ A simple and modular way to do this would be the following: ```js var gulp = require('gulp'); -var runSequence = require('run-sequence'); var source = require('vinyl-source-stream'); var vinylBuffer = require('vinyl-buffer'); var tap = require('gulp-tap'); @@ -50,13 +49,13 @@ var memory = {}; // we'll keep our assets in memory gulp.task('load-lib-files', function() { // read the lib files from the disk return gulp.src('src/libs/*.js') - // concatenate all lib files into one - .pipe(concat('libs.concat.js')) - // tap into the stream to get each file's data - .pipe(tap(function(file) { - // save the file contents in memory - memory[path.basename(file.path)] = file.contents.toString(); - })); + // concatenate all lib files into one + .pipe(concat('libs.concat.js')) + // tap into the stream to get each file's data + .pipe(tap(function(file) { + // save the file contents in memory + memory[path.basename(file.path)] = file.contents.toString(); + })); }); gulp.task('load-versions', function() { @@ -111,30 +110,29 @@ gulp.task('write-versions', function() { }); //============================================ our main task -gulp.task('default', function(taskDone) { - runSequence( - ['load-lib-files', 'load-versions'], // load the files in parallel - 'write-versions', // ready to write once all resources are in memory - taskDone // done - ); -}); +gulp.task('default', gulp.series( + // load the files in parallel + gulp.parallel('load-lib-files', 'load-versions'), + // ready to write once all resources are in memory + 'write-versions' + ) +); //============================================ our watcher task // only watch after having run 'default' once so that all resources // are already in memory -gulp.task('watch', ['default'], function() { - gulp.watch('./src/libs/*.js', function() { - runSequence( - 'load-lib-files', // we only have to load the changed files +gulp.task('watch', gulp.series( + 'default', + function() { + gulp.watch('./src/libs/*.js', gulp.series( + 'load-lib-files', 'write-versions' - ); - }); + )); - gulp.watch('./src/versions/*.js', function() { - runSequence( - 'load-versions', // we only have to load the changed files + gulp.watch('./src/versions/*.js', gulp.series( + 'load-lib-files', 'write-versions' - ); - }); -}); + )); + } +)); ``` diff --git a/docs/recipes/mocha-test-runner-with-gulp.md b/docs/recipes/mocha-test-runner-with-gulp.md index 69788aad..775e3a72 100644 --- a/docs/recipes/mocha-test-runner-with-gulp.md +++ b/docs/recipes/mocha-test-runner-with-gulp.md @@ -28,13 +28,13 @@ var gulp = require('gulp'); var mocha = require('gulp-mocha'); var gutil = require('gulp-util'); -gulp.task('default', function() { - gulp.watch(['lib/**', 'test/**'], ['mocha']); -}); - gulp.task('mocha', function() { return gulp.src(['test/*.js'], { read: false }) .pipe(mocha({ reporter: 'list' })) .on('error', gutil.log); }); + +gulp.task('watch-mocha', function() { + gulp.watch(['lib/**', 'test/**'], gulp.series('mocha')); +}); ``` diff --git a/docs/recipes/running-tasks-in-series.md b/docs/recipes/running-tasks-in-series.md index 4ac2e6c4..5dfad24d 100644 --- a/docs/recipes/running-tasks-in-series.md +++ b/docs/recipes/running-tasks-in-series.md @@ -1,68 +1,89 @@ -# Running tasks in series, i.e. Task Dependency +# Running tasks in series -By default, tasks run with maximum concurrency -- e.g. it launches all the tasks at once and waits for nothing. If you want to create a series where tasks run in a particular order, you need to do two things: - -- give it a hint to tell it when the task is done, -- and give it a hint that a task depends on completion of another. - -For these examples, let's presume you have two tasks, "one" and "two" that you specifically want to run in this order: - -1. In task "one" you add a hint to tell it when the task is done. Either take in a callback and call it when you're done or return a promise or stream that the engine should wait to resolve or end respectively. - -2. In task "two" you add a hint telling the engine that it depends on completion of the first task. - -So this example would look like: +By default, gulp CLI run tasks with maximum concurrency - e.g. it launches +all the tasks at once and waits for nothing. If you want to create a series +where tasks run in a particular order, you should use `gulp.series`; ```js var gulp = require('gulp'); +var doAsyncStuff = require('./stuff'); -// takes in a callback so the engine knows when it'll be done -gulp.task('one', function (cb) { - // do stuff -- async or otherwise - fs.writeFile('filename', 'data', opts, function (err) { - cb(err); // if err is not null and not undefined, the orchestration will stop, and 'two' will not run - }); +gulp.task('one', function(done) { + doAsyncStuff(function(err){ + done(err); + }); }); -// identifies a dependent task must be complete before this one begins -gulp.task('two', ['one'], function() { - // task 'one' is done now +gulp.task('two', function(done) { + // do things + done(); }); -gulp.task('default', ['one', 'two']); -// alternatively: gulp.task('default', ['two']); +gulp.task('default', gulp.series('one', 'two')); ``` -Another example, which returns the stream instead of using a callback: - +Another example, using a dependency pattern. It uses +[`async-once`](https://www.npmjs.com/package/async-once) to run the `clean` +task operations only once: ```js var gulp = require('gulp'); var del = require('del'); // rm -rf - -gulp.task('clean', function() { - return del(['output']); +var once = require('async-once'); + +gulp.task('clean', once(function(done) { + // run only once. + // for the next call to the clean task, once will call done with + // the same arguments as the first call. + del(['output'], done); +})); + +gulp.task('templates', gulp.series('clean', function() { + return gulp.src(['src/templates/*.hbs']) + // do some concatenation, minification, etc. + .pipe(gulp.dest('output/templates/')); }); -gulp.task('templates', ['clean'], function() { - var stream = gulp.src(['src/templates/*.hbs']) - // do some concatenation, minification, etc. - .pipe(gulp.dest('output/templates/')); - return stream; // return the stream as the completion hint +gulp.task('styles', gulp.series('clean', function() { + return gulp.src(['src/styles/app.less']) + // do some hinting, minification, etc. + .pipe(gulp.dest('output/css/app.css')); +})); + +// templates and styles will be processed in parallel. +// `clean` will be guaranteed to complete before either start. +// `clean` operations will not be run twice, +// even though it is called as a dependency twice. +gulp.task('build', gulp.parallel('templates', 'styles')); + +// an alias. +gulp.task('default', gulp.parallel('build')); +``` + +Note that it's an anti-pattern in Gulp 4 and the logs will show the clean task +running twice. Instead, `templates` and `style` should use dedicated `clean:*` +tasks: +```js +var gulp = require('gulp'); +var del = require('del'); +gulp.task('clean:templates', function() { + return del(['output/templates/']); }); -gulp.task('styles', ['clean'], function() { - var stream = gulp.src(['src/styles/app.less']) - // do some hinting, minification, etc. - .pipe(gulp.dest('output/css/app.css')); - return stream; +gulp.task('templates', gulp.series('clean:templates', function() { + return gulp.src(['src/templates/*.hbs']) + .pipe(gulp.dest('output/templates/')); }); -gulp.task('build', ['templates', 'styles']); +gulp.task('clean:styles', function() { + return del(['output/css/']); +}); -// templates and styles will be processed in parallel. -// clean will be guaranteed to complete before either start. -// clean will not be run twice, even though it is called as a dependency twice. +gulp.task('styles', gulp.series('clean:styles', function() { + return gulp.src(['src/styles/app.less']) + .pipe(gulp.dest('output/css/app.css')); +})); -gulp.task('default', ['build']); +gulp.task('build', gulp.parallel('templates', 'styles')); +gulp.task('default', gulp.parallel('build')); ``` diff --git a/docs/recipes/server-with-livereload-and-css-injection.md b/docs/recipes/server-with-livereload-and-css-injection.md index 7a14a667..74280505 100644 --- a/docs/recipes/server-with-livereload-and-css-injection.md +++ b/docs/recipes/server-with-livereload-and-css-injection.md @@ -88,14 +88,14 @@ gulp.task('sass', function() { }); // watch Sass files for changes, run the Sass preprocessor with the 'sass' task and reload -gulp.task('serve', ['sass'], function() { +gulp.task('serve', gulp.series('sass', function() { browserSync({ server: { baseDir: 'app' } }); - gulp.watch('app/scss/*.scss', ['sass']); + gulp.watch('scss/*.scss', gulp.series('sass')); }); ``` diff --git a/docs/recipes/using-external-config-file.md b/docs/recipes/using-external-config-file.md index 5c83779d..6c740761 100644 --- a/docs/recipes/using-external-config-file.md +++ b/docs/recipes/using-external-config-file.md @@ -30,9 +30,11 @@ Beneficial because it's keeping tasks DRY and config.json can be used by another ###### `gulpfile.js` ```js -// npm install --save-dev gulp gulp-uglify +// npm install --save-dev gulp gulp-uglify merge-stream var gulp = require('gulp'); var uglify = require('gulp-uglify'); +var merge = require('merge-stream'); + var config = require('./config.json'); function doStuff(cfg) { @@ -42,7 +44,10 @@ function doStuff(cfg) { } gulp.task('dry', function() { - doStuff(config.desktop); - doStuff(config.mobile); + // return a stream to signal completion + return merge([ + doStuff(config.desktop), + doStuff(config.mobile) + ]) }); ``` From 96febce29ae10e4b4a4da001f49ddbe63bf8d0f9 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 13 Mar 2015 19:59:57 -0700 Subject: [PATCH 020/225] Upgrade: Update undertaker --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 90f654e1..73f3f04a 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "man": "gulp.1", "dependencies": { "gulp-cli": "gulpjs/gulp-cli#4.0", - "undertaker": "^0.3.0", + "undertaker": "^0.7.0", "vinyl-fs": "wearefractal/vinyl-fs" }, "devDependencies": { From 8806326a4f3823b6deb7e29b31bc0fd82057b653 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Tue, 17 Mar 2015 07:48:29 +0000 Subject: [PATCH 021/225] Docs: Added allowEmpty option for gulp.src --- docs/API.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/API.md b/docs/API.md index 6c2443e7..1d4a903d 100644 --- a/docs/API.md +++ b/docs/API.md @@ -101,6 +101,21 @@ Default: `false` If true, it will create a duplex stream which passes items through and emits globbed files. +### options.allowEmpty +Type: `Boolean` +Default: `false` + +When true, will allow singular globs to fail to match. Otherwise, globs which are only supposed to match one file (such as `./foo/bar.js`) will cause an error to be thrown if they don't match. + +```js +// Emits an error if app/scripts.js doesn't exist +gulp.src('app/scripts.js') + .pipe(...); + +// Won't emit an error +gulp.src('app/scripts.js', { allowEmpty: true }) + .pipe(...); +``` ### gulp.dest(path[, options]) From d942cf56f774ba47fb344510c8b10b7efe536239 Mon Sep 17 00:00:00 2001 From: Damien Lebrun Date: Fri, 20 Mar 2015 13:07:59 +0000 Subject: [PATCH 022/225] Docs: Improve incremental build example & add gulp.lastRun API --- README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++----- docs/API.md | 33 ++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b492ea7d..6fbc95b2 100644 --- a/README.md +++ b/README.md @@ -80,12 +80,56 @@ gulp.task('default', gulp.series('clean', 'all')); ## Incremental Builds -We recommend these plugins: +You can filter out unchanged files between runs of a task using +the `gulp.src` function's `since` option and `gulp.lastRun`: +```js +gulp.task('images', function() { + return gulp.src(paths.images, {since: gulp.lastRun('images')}) + .pipe(imagemin({optimizationLevel: 5})) + .pipe(gulp.dest('build/img')); +}); + +gulp.task('watch', function() { + gulp.watch(paths.images, 'images'); +}); +``` +Task run times are saved in memory and are lost when gulp exits. It will only +save time during the `watch` task when running the `images` task +for a second time. -- [gulp-changed](https://github.com/sindresorhus/gulp-changed) - only pass through changed files -- [gulp-cached](https://github.com/contra/gulp-cached) - in-memory file cache, not for operation on sets of files -- [gulp-remember](https://github.com/ahaurw01/gulp-remember) - pairs nicely with gulp-cached -- [gulp-newer](https://github.com/tschaub/gulp-newer) - pass through newer source files only, supports many:1 source:dest +If you want to compare modification time between files instead, we recommend these plugins: +- [gulp-changed]; +- or [gulp-newer] - supports many:1 source:dest. + +[gulp-newer] example: +```js +gulp.task('images', function() { + var dest = 'build/img'; + return gulp.src(paths.images) + .pipe(newer(dest)) // pass through newer images only + .pipe(imagemin({optimizationLevel: 5})) + .pipe(gulp.dest(dest)); +}); +``` + +If you can't simply filter out unchanged files, but need them in a later phase +of the stream, we recommend these plugins: +- [gulp-cached] - in-memory file cache, not for operation on sets of files +- [gulp-remember] - pairs nicely with gulp-cached + +[gulp-remember] example: +```js +gulp.task('scripts', function () { + return gulp.src(scriptsGlob) + .pipe(cache('scripts')) // only pass through changed files + .pipe(header('(function () {')) // do special things to the changed files... + .pipe(footer('})();')) // for example, + // add a simple module wrap to each file + .pipe(remember('scripts')) // add back all files to the stream + .pipe(concat('app.js')) // do things that require all files + .pipe(gulp.dest('public/')) +}); +``` ## Want to test the latest and greatest? @@ -135,3 +179,8 @@ Become a sponsor to get your logo on our README on Github. [backers-image]: https://opencollective.com/gulpjs/backers.svg [sponsors-image]: https://opencollective.com/gulpjs/sponsors.svg + +[gulp-cached]: https://github.com/contra/gulp-cached +[gulp-remember]: https://github.com/ahaurw01/gulp-remember +[gulp-changed]: https://github.com/sindresorhus/gulp-changed +[gulp-newer]: https://github.com/tschaub/gulp-newer diff --git a/docs/API.md b/docs/API.md index 1d4a903d..a885bbcd 100644 --- a/docs/API.md +++ b/docs/API.md @@ -350,6 +350,38 @@ gulp.task('sometask', function() { }); ``` +### lastRun(taskName, [timeResolution]) + +Returns the timestamp of the last time the task ran successfully. The time +will be the time the task started. Returns `undefined` if the task has +not run yet. + +#### taskName + +Type: `String` + +The name of the registered task or of a function. + +#### timeResolution + +Type: `Number`. + +Default: `1000` on node v0.10, `0` on node v0.12 (and iojs v1.5). + +Set the time resolution of the returned timestamps. Assuming +the task named "someTask" ran at `1426000004321`: +- `gulp.lastRun('someTask', 1000)` would return `1426000004000`. +- `gulp.lastRun('someTask', 100)` would return `1426000004300`. + +`timeResolution` allows you to compare a run time to a file [mtime stat][fs stats] +attribute. This attribute time resolution may vary depending of the node version +and the file system used: +- on node v0.10, a file [mtime stat][fs stats] time resolution of any files will be 1s at best; +- on node v0.12 and iojs v1.5, 1ms at best; +- for files on FAT32, the mtime time resolution is 2s; +- on HFS+ and Ext3, 1s; +- on NTFS, 1s on node v0.10, 100ms on node 0.12; +- on Ext4, 1s on node v0.10, 1ms on node 0.12. ### gulp.parallel(...tasks) @@ -482,3 +514,4 @@ The path to the file that triggered the event. [Undertaker]: https://github.com/phated/undertaker [vinyl File instance]: https://github.com/gulpjs/vinyl [Vinyl files]: https://github.com/gulpjs/vinyl-fs +[fs stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats From 1abb5eda814a42acf1495de6f73842a14365b4db Mon Sep 17 00:00:00 2001 From: Damien Lebrun Date: Sun, 22 Mar 2015 10:51:07 +0000 Subject: [PATCH 023/225] Docs: Outline using named functions and when to use gulp.task --- CHANGELOG.md | 2 +- README.md | 72 ++++++++++++++++++++++++++++++---------------------- docs/API.md | 35 ++++++++++++------------- 3 files changed, 60 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32864677..860674c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - replaced 3.x task system (orchestrator) with new task system (bach) - removed gulp.reset - removed 3 argument syntax for `gulp.task` - - using strings when registering with `gulp.task` should only be done when you will call the task with the CLI + - `gulp.task` should only be used when you will call the task with the CLI - added `gulp.series` and `gulp.parallel` methods for composing tasks. Everything must use these now. - added single argument syntax for `gulp.task` which allows a named function to be used as the name of the task and task function. - added `gulp.tree` method for retrieving the task tree. Pass `{ deep: true }` for an `archy` compatible node list. diff --git a/README.md b/README.md index 6fbc95b2..e8cf13d4 100644 --- a/README.md +++ b/README.md @@ -40,16 +40,38 @@ var paths = { images: 'client/img/**/*' }; +/* Register some tasks to expose to the cli */ +gulp.task('build', gulp.series( + clean, + gulp.parallel(scripts, images) +)); +gulp.task(clean); +gulp.task(watch); + +// The default task (called when you run `gulp` from cli) +gulp.task('default', gulp.series('build')); + + +/* Define our tasks using plain functions */ + // Not all tasks need to use streams // A gulpfile is just another node program and you can use all packages available on npm -gulp.task('clean', function() { +function clean() { // You can use multiple globbing patterns as you would with `gulp.src` return del(['build']); -}); +} -gulp.task('scripts', function() { - // Minify and copy all JavaScript (except vendor scripts) - // with sourcemaps all the way down +// Copy all static images +function images() { + return gulp.src(paths.images) + // Pass in options to the task + .pipe(imagemin({optimizationLevel: 5})) + .pipe(gulp.dest('build/img')); +} + +// Minify and copy all JavaScript (except vendor scripts) +// with sourcemaps all the way down +function scripts() { return gulp.src(paths.scripts) .pipe(sourcemaps.init()) .pipe(coffee()) @@ -57,25 +79,13 @@ gulp.task('scripts', function() { .pipe(concat('all.min.js')) .pipe(sourcemaps.write()) .pipe(gulp.dest('build/js')); -}); - -// Copy all static images -gulp.task('images', function() { - return gulp.src(paths.images) - // Pass in options to the task - .pipe(imagemin({optimizationLevel: 5})) - .pipe(gulp.dest('build/img')); -}); +} // Rerun the task when a file changes -gulp.task('watch', function() { - gulp.watch(paths.scripts, 'scripts'); - gulp.watch(paths.images, 'images'); -}); - -gulp.task('all', gulp.parallel('watch', 'scripts', 'images')); -// The default task (called when you run `gulp` from cli) -gulp.task('default', gulp.series('clean', 'all')); +function watch() { + gulp.watch(paths.scripts, scripts); + gulp.watch(paths.images, images); +} ``` ## Incremental Builds @@ -83,15 +93,15 @@ gulp.task('default', gulp.series('clean', 'all')); You can filter out unchanged files between runs of a task using the `gulp.src` function's `since` option and `gulp.lastRun`: ```js -gulp.task('images', function() { +function images() { return gulp.src(paths.images, {since: gulp.lastRun('images')}) .pipe(imagemin({optimizationLevel: 5})) .pipe(gulp.dest('build/img')); -}); +} -gulp.task('watch', function() { - gulp.watch(paths.images, 'images'); -}); +function watch() { + gulp.watch(paths.images, images); +} ``` Task run times are saved in memory and are lost when gulp exits. It will only save time during the `watch` task when running the `images` task @@ -103,13 +113,13 @@ If you want to compare modification time between files instead, we recommend the [gulp-newer] example: ```js -gulp.task('images', function() { +function images() { var dest = 'build/img'; return gulp.src(paths.images) .pipe(newer(dest)) // pass through newer images only .pipe(imagemin({optimizationLevel: 5})) .pipe(gulp.dest(dest)); -}); +} ``` If you can't simply filter out unchanged files, but need them in a later phase @@ -119,7 +129,7 @@ of the stream, we recommend these plugins: [gulp-remember] example: ```js -gulp.task('scripts', function () { +function scripts() { return gulp.src(scriptsGlob) .pipe(cache('scripts')) // only pass through changed files .pipe(header('(function () {')) // do special things to the changed files... @@ -128,7 +138,7 @@ gulp.task('scripts', function () { .pipe(remember('scripts')) // add back all files to the stream .pipe(concat('app.js')) // do things that require all files .pipe(gulp.dest('public/')) -}); +} ``` ## Want to test the latest and greatest? diff --git a/docs/API.md b/docs/API.md index a885bbcd..d9e3a077 100644 --- a/docs/API.md +++ b/docs/API.md @@ -207,7 +207,8 @@ Octal permission specifying the mode the directory should be created with: e.g. ### gulp.task([name,] fn) -Define a task using [Undertaker]. +Define a task exposed to gulp-cli, `gulp.series`, `gulp.parallel` and +`gulp.lastRun`; inherited from [undertaker]. ```js gulp.task('somename', function() { @@ -215,16 +216,26 @@ gulp.task('somename', function() { }); ``` +Or get a task that has been registered. + +```js +// somenameTask will be the registered task function +var somenameTask = gulp.task('somename'); +``` + #### name Type: `String` -Optional, The name of the task. Tasks that you want to run from the command line -should not have spaces in them. - If the name is not provided, the task will be named after the function -`name` attribute, set on any named function. +`name` or `displayName` property. The name argument is required if the +`name` and `displayName` properties of `fn` are empty. + +Since the task can be run from the command line, you should avoid using +spaces in task names. -[Function.name] is not writable; it cannot be set or edited. +**Note:** [Function.name] is not writable; it cannot be set or edited. If +you need to assign a function name or use characters that aren't allowed +in function names, use the `displayName` property. It will be empty for anonymous functions: ```js @@ -238,16 +249,6 @@ bar.name = 'bar' bar.name === '' // true ``` -You should either provide the task name or avoid anonymous functions. - -You can also omit the function if you only want to run a bundle of dependency tasks: - -```js -gulp.task('build', ['array', 'of', 'task', 'names']); -``` - -**Note:** The tasks will run in parallel (all at once), so don't assume that the tasks will start/finish in order. - #### fn Type: `Function` @@ -511,7 +512,7 @@ The path to the file that triggered the event. [RxJS]: https://www.npmjs.com/package/rx [stream]: http://nodejs.org/api/stream.html [async-done]: https://www.npmjs.com/package/async-done -[Undertaker]: https://github.com/phated/undertaker +[undertaker]: https://github.com/gulpjs/undertaker [vinyl File instance]: https://github.com/gulpjs/vinyl [Vinyl files]: https://github.com/gulpjs/vinyl-fs [fs stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats From ad627e6110e7a414085e8eaedec0d0131c3dce93 Mon Sep 17 00:00:00 2001 From: Damien Lebrun Date: Sun, 22 Mar 2015 21:52:29 +0000 Subject: [PATCH 024/225] Docs: Mention .description property & add usage examples --- docs/API.md | 71 +++++++++++++++++++++++++++++++++++++++-------------- docs/CLI.md | 2 +- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/docs/API.md b/docs/API.md index d9e3a077..a4bca45c 100644 --- a/docs/API.md +++ b/docs/API.md @@ -211,7 +211,7 @@ Define a task exposed to gulp-cli, `gulp.series`, `gulp.parallel` and `gulp.lastRun`; inherited from [undertaker]. ```js -gulp.task('somename', function() { +gulp.task(function someTask() { // Do stuff }); ``` @@ -219,8 +219,8 @@ gulp.task('somename', function() { Or get a task that has been registered. ```js -// somenameTask will be the registered task function -var somenameTask = gulp.task('somename'); +// someTask will be the registered task function +var someTask = gulp.task('someTask'); ``` #### name @@ -233,6 +233,35 @@ If the name is not provided, the task will be named after the function Since the task can be run from the command line, you should avoid using spaces in task names. +#### fn + +The function that performs the task's operations. Generally it takes this form: + +```js +function someTask() { + return gulp.src(['some/glob/**/*.ext']).pipe(someplugin()); +} +someTask.description = 'Does something'; + +gulp.task(someTask) +``` + +Gulp tasks are asynchronous and Gulp uses [async-done] to wait for the task's +completion. Tasks are called with a callback parameter to call to signal +completion. Alternatively, Task can return a stream, a promise, a child process +or a RxJS observable to signal the end of the task. + +**Warning:** Sync tasks are not supported and your function will never complete +if the one of the above strategies is not used to signal completion. However, +thrown errors will be caught by Gulp. + +#### fn properties + +##### fn.name + +`gulp.task` names the task after the function `name` property +if the optional `name` parameter of `gulp.task` is not provided. + **Note:** [Function.name] is not writable; it cannot be set or edited. If you need to assign a function name or use characters that aren't allowed in function names, use the `displayName` property. @@ -249,24 +278,30 @@ bar.name = 'bar' bar.name === '' // true ``` -#### fn -Type: `Function` +##### fn.displayName -The function that performs the task's operations. Generally it takes this form: -``` -gulp.task('somename', function() { - return gulp.src(['some/glob/**/*.ext']).pipe(someplugin()); -}) -``` +`gulp.task` names the task after the function `displayName` property +if function is anonymous and the optional `name` parameter of `gulp.task` +is not provided. -Gulp tasks are asynchronous and Gulp uses [async-done] to wait for the tasks' -completion. Tasks are called with a callback parameter to call to signal -completion. Alternatively, Task can return a stream, a promise, a child process -or a RxJS observable to signal the end of the task. +##### fn.description -**Warning:** Sync tasks are not supported and your function will never complete -if the one of the above strategies is not used to signal completion. However, -thrown errors will be caught by Gulp. +gulp-cli prints this description alongside the task name when listing tasks: +```js +var gulp = require('gulp'); + +function test(done){ + done(); +} +test.description = 'I do nothing'; + +gulp.task(test); +``` +```shell +$> gulp --tasks +[12:00:02] Tasks for ~/Documents/some-project/gulpfile.js +[12:00:02] └── test I do nothing +``` #### Async support diff --git a/docs/CLI.md b/docs/CLI.md index 5bfd6792..0666881d 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -8,7 +8,7 @@ gulp has very few flags to know about. All other flags are for tasks to use if n - `--require ` will require a module before running the gulpfile. This is useful for transpilers but also has other applications. You can use multiple `--require` flags - `--gulpfile ` will manually set path of gulpfile. Useful if you have multiple gulpfiles. This will set the CWD to the gulpfile directory as well - `--cwd ` will manually set the CWD. The search for the gulpfile, as well as the relativity of all requires will be from here -- `-T` or `--tasks` will display the task dependency tree for the loaded gulpfile +- `-T` or `--tasks` will display the task dependency tree for the loaded gulpfile. It will include the task names and their [description](./API.md#fndescription). - `--tasks-simple` will display a plaintext list of tasks for the loaded gulpfile - `--verify` will verify plugins referenced in project's package.json against the plugins blacklist - `--color` will force gulp and gulp plugins to display colors even when no color support is detected From b085e951ee4e0b5b0a4c9f4810444a08659301b1 Mon Sep 17 00:00:00 2001 From: Damien Lebrun Date: Wed, 25 Mar 2015 17:42:58 +0000 Subject: [PATCH 025/225] Breaking: Remove array & string task support from gulp.watch --- docs/API.md | 18 +++++++----------- index.js | 5 +---- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/docs/API.md b/docs/API.md index a4bca45c..3cc60467 100644 --- a/docs/API.md +++ b/docs/API.md @@ -487,7 +487,7 @@ Type: `Array`, `String` or `Function` A task name, a function or an array of either. -### gulp.watch(glob[, opts], tasks) +### gulp.watch(glob[, opts], fn) Watch files and do something when a file changes. @@ -495,6 +495,9 @@ Watch files and do something when a file changes. gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); ``` +In the example, `gulp.watch` runs the function returned by gulp.parallel each +time a file with the `js` extension in `js/` is updated. + #### glob Type: `String` or `Array` @@ -505,17 +508,10 @@ Type: `Object` Options, that are passed to [`gaze`][gaze]. -#### tasks -Type: `Array`, `Function` or `String` - -A task name, a function or an array of either to run when a file changes. +#### fn +Type: `Function` -When `tasks` is an array, the tasks will be run in parallel: -``` -gulp.watch('*.js', [one, two]); -// is equivalent to -gulp.watch('*.js', gulp.parallel(one, two)); -``` +An [async](#async-support) function to run when a file changes. `gulp.watch` returns an `EventEmitter` object which emits `change` events with the [gaze] `event`: diff --git a/index.js b/index.js index 13bc263c..3cb73538 100644 --- a/index.js +++ b/index.js @@ -12,10 +12,7 @@ util.inherits(Gulp, Undertaker); Gulp.prototype.src = vfs.src; Gulp.prototype.dest = vfs.dest; Gulp.prototype.watch = function(glob, opt, task) { - var isFunction = (typeof opt === 'function'); - var isString = (typeof opt === 'string'); - var isArray = Array.isArray(opt); - if (isFunction || isString || isArray) { + if (typeof opt === 'function') { task = opt; opt = null; } From c4b6922630dc15f9c7c57890d0d49375bdfeb961 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 1 Apr 2015 12:24:26 -0700 Subject: [PATCH 026/225] Docs: Add note about opt-in symlink following --- docs/API.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/API.md b/docs/API.md index 3cc60467..f9a2e328 100644 --- a/docs/API.md +++ b/docs/API.md @@ -43,6 +43,9 @@ Note that globs are evaluated in order, which means this is possible: gulp.src(['*.js', '!b*.js', 'bad.js']) ``` +**Note:** glob symlink following behavior is opt-in and you must specify +`follow: true` in the options object that is passed to [node-glob]. + #### options Type: `Object` From 1d70cfbf064d5c6ab1677a4389e29fe276b0657b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 1 Apr 2015 12:50:55 -0700 Subject: [PATCH 027/225] Breaking: Only support tasks that are functions in gulp.watch --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 3cb73538..d8a18111 100644 --- a/index.js +++ b/index.js @@ -18,7 +18,7 @@ Gulp.prototype.watch = function(glob, opt, task) { } var fn; - if (task) { + if (typeof task === 'function') { fn = this.parallel(task); } From 6c46116b2c9254d69b596b2fd1102e004430d786 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 1 Apr 2015 14:23:20 -0700 Subject: [PATCH 028/225] New: Expose vfs.symlink API on gulp --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index d8a18111..6969fa14 100644 --- a/index.js +++ b/index.js @@ -11,6 +11,7 @@ util.inherits(Gulp, Undertaker); Gulp.prototype.src = vfs.src; Gulp.prototype.dest = vfs.dest; +Gulp.prototype.symlink = vfs.symlink; Gulp.prototype.watch = function(glob, opt, task) { if (typeof opt === 'function') { task = opt; From f7e7d4c16e97d8f240ec2bad2377e9ef4bed1674 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 3 Apr 2015 14:54:08 -0700 Subject: [PATCH 029/225] Docs: Update "split tasks" recipe to use gulp-hub --- .../split-tasks-across-multiple-files.md | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/docs/recipes/split-tasks-across-multiple-files.md b/docs/recipes/split-tasks-across-multiple-files.md index fb820ad1..4f69bbde 100644 --- a/docs/recipes/split-tasks-across-multiple-files.md +++ b/docs/recipes/split-tasks-across-multiple-files.md @@ -1,22 +1,8 @@ # Split tasks across multiple files -If your `gulpfile.js` is starting to grow too large, you can split -the tasks into separate files using one of the methods below. - -> Be advised, that this approach is [considered deprecated][deprecated] -> and could lead to problems when migrating to the `gulp 4`. - - -## Using `gulp-require-tasks` - -You can use the [gulp-require-tasks][gulp-require-tasks] -module to automatically load all your tasks from the individual files. - -Please see the [module's README][gulp-require-tasks] for up-to-date instructions. - -## Using `require-dir` - -You can also use the [require-dir][require-dir] module to load your tasks manually. +If your `gulpfile.js` is starting to grow too large, you can split the tasks +into separate files by using the [gulp-hub](https://github.com/frankwallis/gulp-hub/tree/4.0) +module as a [custom registry](https://github.com/phated/undertaker#registryregistryinstance). Imagine the following file structure: @@ -28,20 +14,25 @@ tasks/ └── test.js ``` -Install the `require-dir` module: +Install the `gulp-hub` module: ```sh -npm install --save-dev require-dir +npm install --save-dev gulp-hub ``` Add the following lines to your `gulpfile.js` file: ```js -var requireDir = require('require-dir'); -var tasks = requireDir('./tasks'); -``` +'use strict'; + +var gulp = require('gulp'); +var HubRegistry = require('gulp-hub'); +/* load some files into the registry */ +var hub = new HubRegistry(['tasks/*.js']); + +/* tell gulp to use the tasks just loaded */ +gulp.registry(hub); +``` - [gulp-require-tasks]: https://github.com/betsol/gulp-require-tasks - [require-dir]: https://github.com/aseemk/requireDir - [deprecated]: https://github.com/gulpjs/gulp/pull/1554#issuecomment-202614391 +This recipe can also be found at https://github.com/frankwallis/gulp-hub/tree/4.0/examples/recipe From 98b95046d788a69746f8d6ce5789edf81149a103 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 4 Apr 2015 15:26:13 -0700 Subject: [PATCH 030/225] Docs: Add recipe for running shell commands with child_process or gulp-exec --- docs/recipes/README.md | 1 + docs/recipes/running-shell-commands.md | 31 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 docs/recipes/running-shell-commands.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 52c3bcd1..3e822432 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -27,3 +27,4 @@ * [Exports as tasks](exports-as-tasks.md) * [Rollup with rollup-stream](rollup-with-rollup-stream.md) * [Run gulp task via cron job](cron-task.md) +* [Running shell commands](running-shell-commands.md) diff --git a/docs/recipes/running-shell-commands.md b/docs/recipes/running-shell-commands.md new file mode 100644 index 00000000..5d344747 --- /dev/null +++ b/docs/recipes/running-shell-commands.md @@ -0,0 +1,31 @@ +# Running Shell Commands + +Sometimes it is helpful to be able to call existing command line tools from gulp. + +There are 2 ways to handle this: node's [`child_process`](https://nodejs.org/api/child_process.html) +built-in module or [`gulp-exec`](https://github.com/robrich/gulp-exec) if you need to integrate the +command with an existing pipeline. + +```js +'use strict'; + +var cp = require('child_process'); +var gulp = require('gulp'); + +gulp.task('reset', function() { + // In gulp 4, you can return a child process to signal task completion + return cp.execFile('git checkout -- .'); +}); +``` + +```js +'use strict'; + +var gulp = require('gulp'); +var exec = require('gulp-exec'); + +gulp.task('reset', function() { + return gulp.src('./**/**') + .pipe(exec('git checkout -- <%= file.path %>')); +}); +``` From 409f19aacb9489491c82013e9dee28f06f49e8d6 Mon Sep 17 00:00:00 2001 From: Stefan Baumgartner Date: Sun, 5 Apr 2015 22:18:25 +0200 Subject: [PATCH 031/225] Fix: Throw better error when watch parameters are invalid (fixes #1002) --- index.js | 7 +++++++ test/watch.js | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/index.js b/index.js index 6969fa14..1b584162 100644 --- a/index.js +++ b/index.js @@ -13,6 +13,13 @@ Gulp.prototype.src = vfs.src; Gulp.prototype.dest = vfs.dest; Gulp.prototype.symlink = vfs.symlink; Gulp.prototype.watch = function(glob, opt, task) { + if (typeof opt === 'string' || typeof task === 'string' || + Array.isArray(opt) || Array.isArray(task)) { + throw new Error('watching ' + glob + ': watch task has to be ' + + 'a function (optionally generated by using gulp.parallel ' + + 'or gulp.series)'); + } + if (typeof opt === 'function') { task = opt; opt = null; diff --git a/test/watch.js b/test/watch.js index 335ca771..1b1f9d6d 100644 --- a/test/watch.js +++ b/test/watch.js @@ -126,5 +126,29 @@ describe('gulp', function() { updateTempFile(tempFile); }); + it('should throw an error: passed parameter (string) is not a function', function(done) { + var tempFile = path.join(outpath, 'empty.txt'); + + createTempFile(tempFile); + try { + gulp.watch(tempFile, 'task1'); + } catch (err) { + err.message.should.equal('watching ' + tempFile + ': watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)'); + done(); + } + }); + + it('should throw an error: passed parameter (array) is not a function', function(done) { + var tempFile = path.join(outpath, 'empty.txt'); + + createTempFile(tempFile); + try { + gulp.watch(tempFile, ['task1']); + } catch (err) { + err.message.should.equal('watching ' + tempFile + ': watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)'); + done(); + } + }); + }); }); From 8aa1022f22c822db3a2cb62db01e377a88fdd934 Mon Sep 17 00:00:00 2001 From: Devyn Stott Date: Wed, 8 Apr 2015 20:48:20 -0700 Subject: [PATCH 032/225] Docs: Add gulp.tree API & examples --- docs/API.md | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/docs/API.md b/docs/API.md index f9a2e328..c4252457 100644 --- a/docs/API.md +++ b/docs/API.md @@ -535,6 +535,154 @@ Type: String The path to the file that triggered the event. +### gulp.tree(options) + +Returns the tree of tasks. Inherited from [undertaker]. See the [undertaker docs for this function](https://github.com/phated/undertaker#treeoptions--object). + +#### options +Type: Object + +Options to pass to [undertaker]. + +##### options.deep +Type: `Boolean` + +Default: `false` + +If set to true whole tree should be returned. + +#### Example gulpfile + +```js +gulp.task('one', function(done) { + // do stuff + done(); +}); + +gulp.task('two', function(done) { + // do stuff + done(); +}); + +gulp.task('three', function(done) { + // do stuff + done(); +}); + +gulp.task('four', gulp.series('one', 'two')); + +gulp.task('five', + gulp.series('four', + gulp.parallel('three', function(done) { + // do more stuff + done(); + }) + ) +); +``` + +#### Example tree output + +```js +gulp.tree() + +// output: [ 'one', 'two', 'three', 'four', 'five' ] + +gulp.tree({ deep: true }) + +/*output: [ + { + "label":"one", + "type":"task", + "nodes":[] + }, + { + "label":"two", + "type":"task", + "nodes":[] + }, + { + "label":"three", + "type":"task", + "nodes":[] + }, + { + "label":"four", + "type":"task", + "nodes":[ + { + "label":"", + "type":"function", + "nodes":[ + { + "label":"one", + "type":"task", + "nodes":[] + }, + { + "label":"two", + "type":"task", + "nodes":[] + } + ] + } + ] + }, + { + "label":"five", + "type":"task", + "nodes":[ + { + "label":"", + "type":"function", + "nodes":[ + { + "label":"four", + "type":"task", + "nodes":[ + { + "label":"", + "type":"function", + "nodes":[ + { + "label":"one", + "type":"task", + "nodes":[] + }, + { + "label":"two", + "type":"task", + "nodes":[] + } + ] + } + ] + }, + { + "label":"", + "type":"function", + "nodes":[ + { + "label":"three", + "type":"task", + "nodes":[] + }, + { + "label":"", + "type":"function", + "nodes":[] + } + ] + } + ] + } + ] + } +] +*/ +``` + + [Function.name]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name [gaze]: https://github.com/shama/gaze [glob-stream]: https://github.com/gulpjs/glob-stream From c1012cd5524d8265f00898bddab491a8f7fcf41e Mon Sep 17 00:00:00 2001 From: Devyn Stott Date: Wed, 8 Apr 2015 21:08:00 -0700 Subject: [PATCH 033/225] Docs: Add example of -T/--tasks and --tasks-simple --- docs/CLI.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/docs/CLI.md b/docs/CLI.md index 0666881d..c4af45f7 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -41,3 +41,75 @@ Just running `gulp` will execute the task `default`. If there is no ### Compilers You can find a list of supported languages at [interpret](https://github.com/tkellen/node-interpret#jsvariants). If you would like to add support for a new language send pull request/open issues there. + +### Examples + +#### Example gulpfile + +```js +gulp.task('one', function(done) { + // do stuff + done(); +}); + +gulp.task('two', function(done) { + // do stuff + done(); +}); + +gulp.task('three', three); + +function three(done) { + done(); +} +three.description = "This is the description of task three"; + +gulp.task('four', gulp.series('one', 'two')); + +gulp.task('five', + gulp.series('four', + gulp.parallel('three', function(done) { + // do more stuff + done(); + }) + ) +); +``` + +### `-T` or `--tasks` + +Command: `gulp -T` or `gulp --tasks` + +Output: +```shell +[20:58:55] Tasks for ~\exampleProject\gulpfile.js +[20:58:55] ├── one +[20:58:55] ├── two +[20:58:55] ├── three This is the description of task three +[20:58:55] ├─┬ four +[20:58:55] │ └─┬ +[20:58:55] │ ├── one +[20:58:55] │ └── two +[20:58:55] ├─┬ five +[20:58:55] │ └─┬ +[20:58:55] │ ├─┬ four +[20:58:55] │ │ └─┬ +[20:58:55] │ │ ├── one +[20:58:55] │ │ └── two +[20:58:55] │ └─┬ +[20:58:55] │ ├── three +[20:58:55] │ └── +``` + +### `--tasks-simple` + +Command: `gulp --tasks-simple` + +Output: +```shell +one +two +three +four +five +``` From be2df066378166d0cdf5f040291e333044dac074 Mon Sep 17 00:00:00 2001 From: Ivan Yan Date: Sun, 24 May 2015 08:18:48 +0800 Subject: [PATCH 034/225] Docs: Improve API references --- docs/API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/API.md b/docs/API.md index c4252457..f0227f2b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -104,7 +104,7 @@ Default: `false` If true, it will create a duplex stream which passes items through and emits globbed files. -### options.allowEmpty +##### options.allowEmpty Type: `Boolean` Default: `false` @@ -389,7 +389,7 @@ gulp.task('sometask', function() { }); ``` -### lastRun(taskName, [timeResolution]) +### gulp.lastRun(taskName, [timeResolution]) Returns the timestamp of the last time the task ran successfully. The time will be the time the task started. Returns `undefined` if the task has From 2e4809b08b7a955f1758241e3adc708270c2d603 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 1 Jun 2015 16:24:15 -0700 Subject: [PATCH 035/225] Upgrade: Update undertaker & vinyl-fs --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 73f3f04a..0f01025c 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ "man": "gulp.1", "dependencies": { "gulp-cli": "gulpjs/gulp-cli#4.0", - "undertaker": "^0.7.0", - "vinyl-fs": "wearefractal/vinyl-fs" + "undertaker": "^0.11.0", + "vinyl-fs": "^1.0.0" }, "devDependencies": { "coveralls": "^2.7.0", From 3f843b8585a05500588c741b5bd58c5c87f0b7f7 Mon Sep 17 00:00:00 2001 From: Devyn Stott Date: Thu, 16 Apr 2015 11:56:25 -0700 Subject: [PATCH 036/225] Docs: Add gulp.registry API & examples --- docs/API.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/docs/API.md b/docs/API.md index f0227f2b..75b727ca 100644 --- a/docs/API.md +++ b/docs/API.md @@ -682,6 +682,59 @@ gulp.tree({ deep: true }) */ ``` +### gulp.registry([registry]) + +Get or set the underlying task registry. Inherited from [undertaker]; see the undertaker documention on [registries](https://github.com/phated/undertaker#registryregistryinstance). Using this, you can change registries that enhance gulp in different ways. Utilizing a custom registry has at least three use cases: + +- [Sharing tasks](https://github.com/phated/undertaker#sharing-tasks) +- [Sharing functionality](https://github.com/phated/undertaker#sharing-functionalities). (e.g. you could override the task prototype to add some additional logging, bind task metadata or include some config settings.) +- Handling other behavior that hooks into the registry lifecycle (see [gulp-hub](https://github.com/frankwallis/gulp-hub) for an example) + +To build your own custom registry see the [undertaker documentation on custom registries](https://github.com/phated/undertaker#custom-registries). + +#### registry + +A registry instance or constructor. When passed in, the tasks from the current registry will be transferred to the new registry and then current registry will be replaced with the new registry. + +#### Example + +This example shows how to create and use a simple custom registry to add tasks. + +```js +//gulpfile.js +var gulp = require('gulp'); + +var companyTasks = require('./myCompanyTasksRegistry.js'); + +gulp.registry(companyTasks); + +gulp.task('one', gulp.parallel('someCompanyTask', function(done) { + console.log('in task one'); + done(); +})); +``` + +```js +//myCompanyTasksRegistry.js +var util = require('util'); + +var DefaultRegistry = require('undertaker-registry'); + +function MyCompanyTasksRegistry() { + DefaultRegistry.call(this); + + this.set('clean', function(done) { + done(); + }); + this.set('someCompanyTask', function(done) { + console.log('performing some company task.'); + done(); + }); +} +util.inherits(MyCompanyTasksRegistry, DefaultRegistry); + +module.exports = new MyCompanyTasksRegistry(); +``` [Function.name]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name [gaze]: https://github.com/shama/gaze From 646044b6f80bc45213cc42ef0f6a8065e7382442 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 21 Aug 2015 16:53:40 -0700 Subject: [PATCH 037/225] Upgrade: Update undertaker --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f01025c..9e1adcf7 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "man": "gulp.1", "dependencies": { "gulp-cli": "gulpjs/gulp-cli#4.0", - "undertaker": "^0.11.0", + "undertaker": "^0.12.0", "vinyl-fs": "^1.0.0" }, "devDependencies": { From 2cd0e1e91214e41265469df880815ffa82f20444 Mon Sep 17 00:00:00 2001 From: Stefan Baumgartner Date: Wed, 16 Sep 2015 10:21:13 +0200 Subject: [PATCH 038/225] Breaking: Replace vinyl-fs watch/gaze with chokidar --- docs/API.md | 33 ++++++++++----- .../handling-the-delete-event-on-watch.md | 22 ++++------ index.js | 11 ++++- package.json | 1 + test/watch.js | 42 ++++++++++++------- 5 files changed, 69 insertions(+), 40 deletions(-) diff --git a/docs/API.md b/docs/API.md index 75b727ca..17263fc3 100644 --- a/docs/API.md +++ b/docs/API.md @@ -509,31 +509,42 @@ A single glob or array of globs that indicate which files to watch for changes. #### opts Type: `Object` -Options, that are passed to [`gaze`][gaze]. +Options, that are passed to [`chokidar`][chokidar]. #### fn Type: `Function` An [async](#async-support) function to run when a file changes. -`gulp.watch` returns an `EventEmitter` object which emits `change` events with -the [gaze] `event`: +`gulp.watch` returns a wrapped [chokidar] FSWatcher object. If provided, +the callback will be triggered upon any `add`, `change`, or `unlink` event. +Listeners can also be set directly for any of [chokidar]'s events. + ```js var watcher = gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); -watcher.on('change', function(event) { - console.log('File ' + event.path + ' was ' + event.type); +watcher.on('change', function(path, stats) { + console.log('File ' + path + ' was changed'); + if (stats) { + console.log('changed size to ' + stats.size); + } +}); + +watcher.on('unlink', function(path) { + console.log('File ' + path + ' was removed'); }); ``` -##### event.type +##### path Type: String -The type of change that occurred, either "added", "changed" or "deleted". +The relative path of the document. -##### event.path -Type: String +##### stats +Type: Object -The path to the file that triggered the event. +[File stats](http://nodejs.org/api/fs.html#fs_class_fs_stats) object when available. +Setting the `alwaysStat` option to true will ensure that a file stat object will be +available. ### gulp.tree(options) @@ -737,7 +748,7 @@ module.exports = new MyCompanyTasksRegistry(); ``` [Function.name]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name -[gaze]: https://github.com/shama/gaze +[chokidar]: https://github.com/paulmillr/chokidar [glob-stream]: https://github.com/gulpjs/glob-stream [glob-parent]: https://github.com/es128/glob-parent [gulp-if]: https://github.com/robrich/gulp-if diff --git a/docs/recipes/handling-the-delete-event-on-watch.md b/docs/recipes/handling-the-delete-event-on-watch.md index 40cf115f..05bd683a 100644 --- a/docs/recipes/handling-the-delete-event-on-watch.md +++ b/docs/recipes/handling-the-delete-event-on-watch.md @@ -1,9 +1,8 @@ # Handling the Delete Event on Watch -You can listen for `'change'` events to fire on the watcher returned from `gulp.watch`. - -Each change event has a `type` property. If `type` is `'deleted'`, you can delete the file -from your destination directory, using something like: +You can listen for `'unlink'` events to fire on the watcher returned from `gulp.watch`. +This gets fired when files are removed, so you can delete the file from your destination +directory, using something like: ```js 'use strict'; @@ -24,16 +23,11 @@ gulp.task('scripts', function() { gulp.task('watch', function () { var watcher = gulp.watch('src/**/*.js', ['scripts']); - watcher.on('change', function (event) { - if (event.type === 'deleted') { - // Simulating the {base: 'src'} used with gulp.src in the scripts task - var filePathFromSrc = path.relative(path.resolve('src'), event.path); - - // Concatenating the 'build' absolute path used by gulp.dest in the scripts task - var destFilePath = path.resolve('build', filePathFromSrc); - - del.sync(destFilePath); - } + watcher.on('unlink', function (filepath) { + var filePathFromSrc = path.relative(path.resolve('src'), filepath); + // Concatenating the 'build' absolute path used by gulp.dest in the scripts task + var destFilePath = path.resolve('build', filePathFromSrc); + del.sync(destFilePath); }); }); ``` diff --git a/index.js b/index.js index 1b584162..46309dbc 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ var util = require('util'); var Undertaker = require('undertaker'); var vfs = require('vinyl-fs'); +var chokidar = require('chokidar'); function Gulp() { Undertaker.call(this); @@ -30,7 +31,15 @@ Gulp.prototype.watch = function(glob, opt, task) { fn = this.parallel(task); } - return vfs.watch(glob, opt, fn); + var watcher = chokidar.watch(glob, opt); + if (fn) { + watcher + .on('change', fn) + .on('unlink', fn) + .on('add', fn); + } + + return watcher; }; // Let people use this class from our instance diff --git a/package.json b/package.json index 9e1adcf7..8ab6637b 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ }, "man": "gulp.1", "dependencies": { + "chokidar": "^1.0.5", "gulp-cli": "gulpjs/gulp-cli#4.0", "undertaker": "^0.12.0", "vinyl-fs": "^1.0.0" diff --git a/test/watch.js b/test/watch.js index 1b1f9d6d..788df4b4 100644 --- a/test/watch.js +++ b/test/watch.js @@ -36,7 +36,7 @@ describe('gulp', function() { createTempFile(tempFile); var watcher = gulp.watch(tempFile, function(cb) { - watcher.end(); + watcher.close(); cb(); done(); }); @@ -44,13 +44,30 @@ describe('gulp', function() { updateTempFile(tempFile); }); + it('should execute the gulp.parallel tasks', function(done) { + var tempFile = path.join(outpath, 'watch-func.txt'); + + createTempFile(tempFile); + + gulp.task('test', function(cb) { + watcher.close(); + cb(); + done(); + }); + + var watcher = gulp.watch(tempFile, gulp.parallel('test')); + + updateTempFile(tempFile); + }); + + it('should call the function when file changes: w/ options', function(done) { var tempFile = path.join(outpath, 'watch-func-options.txt'); createTempFile(tempFile); - var watcher = gulp.watch(tempFile, {debounceDelay: 5}, function(cb) { - watcher.end(); + var watcher = gulp.watch(tempFile, function(cb) { + watcher.close(); cb(); done(); }); @@ -66,14 +83,11 @@ describe('gulp', function() { createTempFile(tempFile); - var watcher = gulp.watch(relFile, {debounceDelay: 5, cwd: cwd}) - .on('change', function(evt) { - should.exist(evt); - should.exist(evt.path); - should.exist(evt.type); - evt.type.should.equal('changed'); - evt.path.should.equal(path.resolve(tempFile)); - watcher.end(); + var watcher = gulp.watch(relFile, {cwd: cwd}) + .on('change', function(filepath) { + should.exist(filepath); + path.resolve(cwd, filepath).should.equal(path.resolve(tempFile)); + watcher.close(); done(); }); @@ -93,12 +107,12 @@ describe('gulp', function() { gulp.task('task2', function(cb) { a += 10; a.should.equal(11); - watcher.end(); + watcher.close(); cb(); done(); }); - var watcher = gulp.watch(tempFile, {debounceDelay: 25}, gulp.series('task1', 'task2')); + var watcher = gulp.watch(tempFile, gulp.series('task1', 'task2')); updateTempFile(tempFile); }); @@ -116,7 +130,7 @@ describe('gulp', function() { gulp.task('task2', function(cb) { a += 10; a.should.equal(11); - watcher.end(); + watcher.close(); cb(); done(); }); From 32abfe5c1479e6662150a692c59b4072d334869c Mon Sep 17 00:00:00 2001 From: Contra Date: Fri, 25 Sep 2015 16:06:20 -0700 Subject: [PATCH 039/225] Upgrade: Update vinyl-fs & mocha-lcov-reporter --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8ab6637b..3edf5830 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ }, "man": "gulp.1", "dependencies": { - "chokidar": "^1.0.5", + "chokidar": "^1.1.0", "gulp-cli": "gulpjs/gulp-cli#4.0", "undertaker": "^0.12.0", - "vinyl-fs": "^1.0.0" + "vinyl-fs": "^2.0.0" }, "devDependencies": { "coveralls": "^2.7.0", @@ -38,7 +38,7 @@ "jscs-preset-gulp": "^1.0.0", "mkdirp": "^0.5.0", "mocha": "^2.0.1", - "mocha-lcov-reporter": "^0.0.1", + "mocha-lcov-reporter": "^1.0.0", "q": "^1.0.0", "rimraf": "^2.2.5", "should": "^5.0.1" From 355fc4e14840fd26db07fe99183e430e8390ae17 Mon Sep 17 00:00:00 2001 From: Elan Shanker Date: Sat, 26 Sep 2015 02:59:13 -0400 Subject: [PATCH 040/225] Fix: Set chokidar option ignoreIntial: true by default --- index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 46309dbc..dda868a5 100644 --- a/index.js +++ b/index.js @@ -23,7 +23,7 @@ Gulp.prototype.watch = function(glob, opt, task) { if (typeof opt === 'function') { task = opt; - opt = null; + opt = {}; } var fn; @@ -31,6 +31,10 @@ Gulp.prototype.watch = function(glob, opt, task) { fn = this.parallel(task); } + if (opt.ignoreInitial == null) { + opt.ignoreInitial = true; + } + var watcher = chokidar.watch(glob, opt); if (fn) { watcher From 263eeeaad217d4bffb1fbaea1eb57a18a3af2967 Mon Sep 17 00:00:00 2001 From: Elan Shanker Date: Sat, 26 Sep 2015 03:26:30 -0400 Subject: [PATCH 041/225] Docs: Improve gulp.watch API with Chokidar specifics --- docs/API.md | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/docs/API.md b/docs/API.md index 17263fc3..cf3c2071 100644 --- a/docs/API.md +++ b/docs/API.md @@ -493,6 +493,9 @@ A task name, a function or an array of either. ### gulp.watch(glob[, opts], fn) Watch files and do something when a file changes. +File watching is provided by the [`chokidar`][chokidar] module. +Please report any file watching problems directly to its +[issue tracker](https://github.com/paulmillr/chokidar/issues). ```js gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); @@ -509,7 +512,23 @@ A single glob or array of globs that indicate which files to watch for changes. #### opts Type: `Object` -Options, that are passed to [`chokidar`][chokidar]. +Options that are passed to [`chokidar`][chokidar]. + +Commonly used options: +* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition) +Defines files/paths to be excluded from being watched. +* `usePolling` (boolean, default: `false`). When `true` uses a watch method backed +by stat polling. Usually necessary when watching files on a network mount or on a +VMs file system. +* `cwd` (path string). The base directory from which watch paths are to be +derived. Paths emitted with events will be relative to this. +* `alwaysStat` (boolean, default: `false`). If relying upon the +[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object +that may get passed as a second argument with `add`, `addDir`, and `change` events +when available, set this to `true` to ensure it is provided with every event. May +have a slight performance penalty. + +Read about the full set of options in [`chokidar`'s README][chokidar] #### fn Type: `Function` @@ -518,15 +537,13 @@ An [async](#async-support) function to run when a file changes. `gulp.watch` returns a wrapped [chokidar] FSWatcher object. If provided, the callback will be triggered upon any `add`, `change`, or `unlink` event. -Listeners can also be set directly for any of [chokidar]'s events. +Listeners can also be set directly for any of [chokidar]'s events, such as +`addDir`, `unlinkDir`, and `error`. ```js var watcher = gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); watcher.on('change', function(path, stats) { console.log('File ' + path + ' was changed'); - if (stats) { - console.log('changed size to ' + stats.size); - } }); watcher.on('unlink', function(path) { @@ -544,7 +561,22 @@ Type: Object [File stats](http://nodejs.org/api/fs.html#fs_class_fs_stats) object when available. Setting the `alwaysStat` option to true will ensure that a file stat object will be -available. +provided. + +#### watcher methods + +##### watcher.close() + +Shuts down the file watcher. + +##### watcher.add(glob) + +Watch additional glob (or array of globs) with an already-running watcher instance. + +##### watcher.unwatch(glob) + +Stop watching a glob (or array of globs) while leaving the watcher running and +emitting events for the remaining paths it is watching. ### gulp.tree(options) From 88b6c338649b78ff8be3a7131f72205713b9e741 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 1 Oct 2015 13:57:32 -0700 Subject: [PATCH 042/225] Upgrade: Update chokidar (ref #1287) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3edf5830..ebe6378f 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ }, "man": "gulp.1", "dependencies": { - "chokidar": "^1.1.0", + "chokidar": "^1.2.0", "gulp-cli": "gulpjs/gulp-cli#4.0", "undertaker": "^0.12.0", "vinyl-fs": "^2.0.0" From cacc173eef8bfd514d9be66368ae69276e72c932 Mon Sep 17 00:00:00 2001 From: Da CodeKid Date: Tue, 6 Oct 2015 11:11:43 -0400 Subject: [PATCH 043/225] Docs: Update "clean" task in example for "del" syntax change --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e8cf13d4..ea3cf1ad 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,10 @@ gulp.task('default', gulp.series('build')); /* Define our tasks using plain functions */ // Not all tasks need to use streams -// A gulpfile is just another node program and you can use all packages available on npm +// But it must return either a Promise or Stream or take a Callback and call it function clean() { // You can use multiple globbing patterns as you would with `gulp.src` + // If you are using del 2.0 or above, return its promise return del(['build']); } From bc352dd943c4bbd5961901da3798df398d9f0434 Mon Sep 17 00:00:00 2001 From: Nick McCready Date: Thu, 10 Sep 2015 23:37:37 -0400 Subject: [PATCH 044/225] Update: Add test to make sure no functions are kicked off when they should not --- test/watch.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/watch.js b/test/watch.js index 788df4b4..2dba7dab 100644 --- a/test/watch.js +++ b/test/watch.js @@ -61,6 +61,21 @@ describe('gulp', function() { }); + it('should not call the function when no file changes: no options', function(done) { + var tempFile = path.join(outpath, 'watch-func.txt'); + + createTempFile(tempFile); + + var watcher = gulp.watch(tempFile, function() { + should.fail('Watcher erroneously called'); + }); + + setTimeout(function() { + watcher.close(); + done(); + }, 10); + }); + it('should call the function when file changes: w/ options', function(done) { var tempFile = path.join(outpath, 'watch-func-options.txt'); From 0f3151edb6f4772aaa8a249a85a42183384c2e3a Mon Sep 17 00:00:00 2001 From: erikkemperman Date: Wed, 21 Oct 2015 16:49:35 +0200 Subject: [PATCH 045/225] Docs: Align API with undertaker docs --- docs/API.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/API.md b/docs/API.md index cf3c2071..7179223b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -737,7 +737,7 @@ To build your own custom registry see the [undertaker documentation on custom re #### registry -A registry instance or constructor. When passed in, the tasks from the current registry will be transferred to the new registry and then current registry will be replaced with the new registry. +A registry instance. When passed in, the tasks from the current registry will be transferred to the new registry and then current registry will be replaced with the new registry. #### Example @@ -765,16 +765,18 @@ var DefaultRegistry = require('undertaker-registry'); function MyCompanyTasksRegistry() { DefaultRegistry.call(this); +} +util.inherits(MyCompanyTasksRegistry, DefaultRegistry); - this.set('clean', function(done) { +MyCompanyTasksRegistry.prototype.init = function(gulp) { + gulp.task('clean', function(done) { done(); }); - this.set('someCompanyTask', function(done) { + gulp.task('someCompanyTask', function(done) { console.log('performing some company task.'); done(); }); -} -util.inherits(MyCompanyTasksRegistry, DefaultRegistry); +}; module.exports = new MyCompanyTasksRegistry(); ``` From 7e67502ca611979821ad1036afba5925f0efef64 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 18 Nov 2015 13:00:05 -0700 Subject: [PATCH 046/225] Upgrade: Update undertaker --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ebe6378f..0a9402f3 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dependencies": { "chokidar": "^1.2.0", "gulp-cli": "gulpjs/gulp-cli#4.0", - "undertaker": "^0.12.0", + "undertaker": "^0.13.0", "vinyl-fs": "^2.0.0" }, "devDependencies": { From 430df3667ee52d9c65b1dc719354e4ab6d37fcd7 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 14:45:47 -0700 Subject: [PATCH 047/225] Release: 4.0.0-alpha.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0a9402f3..c7e241b7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "gulp", "description": "The streaming build system", - "version": "4.0.0-alpha.1", + "version": "4.0.0-alpha.2", "homepage": "http://gulpjs.com", "repository": "gulpjs/gulp", "author": "Fractal (http://wearefractal.com/)", From d0ced7521dcc4a5ee8004d0daf6d8e0f488e28cc Mon Sep 17 00:00:00 2001 From: cssmagic Date: Tue, 10 Nov 2015 14:56:15 +0800 Subject: [PATCH 048/225] Docs: Improve format of API --- docs/API.md | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/docs/API.md b/docs/API.md index 7179223b..a420c040 100644 --- a/docs/API.md +++ b/docs/API.md @@ -38,7 +38,8 @@ The following expression matches `a.js` and `bad.js`: Note that globs are evaluated in order, which means this is possible: -``` + +```js // exclude every JS file that starts with a b except bad.js gulp.src(['*.js', '!b*.js', 'bad.js']) ``` @@ -106,6 +107,7 @@ emits globbed files. ##### options.allowEmpty Type: `Boolean` + Default: `false` When true, will allow singular globs to fail to match. Otherwise, globs which are only supposed to match one file (such as `./foo/bar.js`) will cause an error to be thrown if they don't match. @@ -120,6 +122,7 @@ gulp.src('app/scripts.js', { allowEmpty: true }) .pipe(...); ``` + ### gulp.dest(path[, options]) Can be piped to and it will write files. Re-emits all data passed to it so you @@ -290,6 +293,7 @@ is not provided. ##### fn.description gulp-cli prints this description alongside the task name when listing tasks: + ```js var gulp = require('gulp'); @@ -300,7 +304,8 @@ test.description = 'I do nothing'; gulp.task(test); ``` -```shell + +```sh $> gulp --tasks [12:00:02] Tasks for ~/Documents/some-project/gulpfile.js [12:00:02] └── test I do nothing @@ -389,6 +394,7 @@ gulp.task('sometask', function() { }); ``` + ### gulp.lastRun(taskName, [timeResolution]) Returns the timestamp of the last time the task ran successfully. The time @@ -409,12 +415,14 @@ Default: `1000` on node v0.10, `0` on node v0.12 (and iojs v1.5). Set the time resolution of the returned timestamps. Assuming the task named "someTask" ran at `1426000004321`: + - `gulp.lastRun('someTask', 1000)` would return `1426000004000`. - `gulp.lastRun('someTask', 100)` would return `1426000004300`. `timeResolution` allows you to compare a run time to a file [mtime stat][fs stats] attribute. This attribute time resolution may vary depending of the node version and the file system used: + - on node v0.10, a file [mtime stat][fs stats] time resolution of any files will be 1s at best; - on node v0.12 and iojs v1.5, 1ms at best; - for files on FAT32, the mtime time resolution is 2s; @@ -422,6 +430,7 @@ and the file system used: - on NTFS, 1s on node v0.10, 100ms on node 0.12; - on Ext4, 1s on node v0.10, 1ms on node 0.12. + ### gulp.parallel(...tasks) Takes a number of task names or functions and returns a function of the composed @@ -515,7 +524,8 @@ Type: `Object` Options that are passed to [`chokidar`][chokidar]. Commonly used options: -* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition) + +* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition). Defines files/paths to be excluded from being watched. * `usePolling` (boolean, default: `false`). When `true` uses a watch method backed by stat polling. Usually necessary when watching files on a network mount or on a @@ -523,12 +533,12 @@ VMs file system. * `cwd` (path string). The base directory from which watch paths are to be derived. Paths emitted with events will be relative to this. * `alwaysStat` (boolean, default: `false`). If relying upon the -[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object +[`fs.Stats`][fs stats] object that may get passed as a second argument with `add`, `addDir`, and `change` events when available, set this to `true` to ensure it is provided with every event. May have a slight performance penalty. -Read about the full set of options in [`chokidar`'s README][chokidar] +Read about the full set of options in [`chokidar`'s README][chokidar]. #### fn Type: `Function` @@ -552,15 +562,15 @@ watcher.on('unlink', function(path) { ``` ##### path -Type: String +Type: `String` The relative path of the document. ##### stats -Type: Object +Type: `Object` -[File stats](http://nodejs.org/api/fs.html#fs_class_fs_stats) object when available. -Setting the `alwaysStat` option to true will ensure that a file stat object will be +[File stats][fs stats] object when available. +Setting the `alwaysStat` option to `true` will ensure that a file stat object will be provided. #### watcher methods @@ -578,12 +588,13 @@ Watch additional glob (or array of globs) with an already-running watcher instan Stop watching a glob (or array of globs) while leaving the watcher running and emitting events for the remaining paths it is watching. + ### gulp.tree(options) Returns the tree of tasks. Inherited from [undertaker]. See the [undertaker docs for this function](https://github.com/phated/undertaker#treeoptions--object). #### options -Type: Object +Type: `Object` Options to pass to [undertaker]. @@ -592,7 +603,7 @@ Type: `Boolean` Default: `false` -If set to true whole tree should be returned. +If set to `true` whole tree should be returned. #### Example gulpfile @@ -725,12 +736,13 @@ gulp.tree({ deep: true }) */ ``` + ### gulp.registry([registry]) Get or set the underlying task registry. Inherited from [undertaker]; see the undertaker documention on [registries](https://github.com/phated/undertaker#registryregistryinstance). Using this, you can change registries that enhance gulp in different ways. Utilizing a custom registry has at least three use cases: - [Sharing tasks](https://github.com/phated/undertaker#sharing-tasks) -- [Sharing functionality](https://github.com/phated/undertaker#sharing-functionalities). (e.g. you could override the task prototype to add some additional logging, bind task metadata or include some config settings.) +- [Sharing functionality](https://github.com/phated/undertaker#sharing-functionalities) (e.g. you could override the task prototype to add some additional logging, bind task metadata or include some config settings.) - Handling other behavior that hooks into the registry lifecycle (see [gulp-hub](https://github.com/frankwallis/gulp-hub) for an example) To build your own custom registry see the [undertaker documentation on custom registries](https://github.com/phated/undertaker#custom-registries). From b764543fcc2b8a512a771ac104babaa2e4451c44 Mon Sep 17 00:00:00 2001 From: Shawn Erquhart Date: Mon, 9 Nov 2015 20:59:53 -0500 Subject: [PATCH 049/225] Docs: Update table of contents for API --- docs/API.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/API.md b/docs/API.md index a420c040..201114b6 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,10 +1,15 @@ ## gulp API docs -Jump to: - [gulp.src](#gulpsrcglobs-options) | - [gulp.dest](#gulpdestpath-options) | - [gulp.task](#gulptaskname--deps--fn) | - [gulp.watch](#gulpwatchglob--opts-tasks-or-gulpwatchglob--opts-cb) +* [gulp.src](#gulpsrcglobs-options) - Emit files matching one or more globs +* [gulp.dest](#gulpdestpath-options) - Write files to directories +* [gulp.symlink](#gulpsymlinkfolder-options) - Write files to symlinks +* [gulp.task](#gulptaskname-fn) - Define tasks +* [gulp.lastRun](#gulplastruntaskname-timeresolution) - Get timestamp of last successful run +* [gulp.parallel](#gulpparalleltasks) - Run tasks in parallel +* [gulp.series](#gulpseriestasks) - Run tasks in series +* [gulp.watch](#gulpwatchglob-opts-fn) - Do something when a file changes +* [gulp.tree](#gulptreeoptions) - Get the tree of tasks +* [gulp.registry](#gulpregistryregistry) - Get or set the task registry ### gulp.src(globs[, options]) From 468a703d01589429be8ac2922ca24e15b2df55a6 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 21 Dec 2015 16:57:19 -0700 Subject: [PATCH 050/225] Update: Use published gulp-cli --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c7e241b7..7d04e53b 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "man": "gulp.1", "dependencies": { "chokidar": "^1.2.0", - "gulp-cli": "gulpjs/gulp-cli#4.0", + "gulp-cli": "^1.0.0", "undertaker": "^0.13.0", "vinyl-fs": "^2.0.0" }, From c69157281f26b91c7e6581f2e1e0fba9d1c2b7c6 Mon Sep 17 00:00:00 2001 From: Contra Date: Thu, 24 Dec 2015 11:41:11 -0800 Subject: [PATCH 051/225] Update: Bind all undertaker functions on the gulp instance to allow destructuring --- index.js | 9 +++++++++ test/watch.js | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/index.js b/index.js index dda868a5..e3b5b4fe 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,15 @@ var chokidar = require('chokidar'); function Gulp() { Undertaker.call(this); + + // Bind the functions for destructuring + this.watch = this.watch.bind(this); + this.task = this.task.bind(this); + this.series = this.series.bind(this); + this.parallel = this.parallel.bind(this); + this.registry = this.registry.bind(this); + this.tree = this.tree.bind(this); + this.lastRun = this.lastRun.bind(this); } util.inherits(Gulp, Undertaker); diff --git a/test/watch.js b/test/watch.js index 2dba7dab..787b6543 100644 --- a/test/watch.js +++ b/test/watch.js @@ -60,6 +60,23 @@ describe('gulp', function() { updateTempFile(tempFile); }); + it('should work with destructuring', function(done) { + var tempFile = path.join(outpath, 'watch-func.txt'); + var watch = gulp.watch; + var parallel = gulp.parallel; + var task = gulp.task; + createTempFile(tempFile); + + task('test', function(cb) { + watcher.close(); + cb(); + done(); + }); + + var watcher = watch(tempFile, parallel('test')); + + updateTempFile(tempFile); + }); it('should not call the function when no file changes: no options', function(done) { var tempFile = path.join(outpath, 'watch-func.txt'); From 83f563295a22a04f2c4595671fab6b7baf840979 Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Thu, 21 Jan 2016 22:51:46 -0500 Subject: [PATCH 052/225] Docs: Replace irc with gitter channel --- docs/FAQ.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index 31e11df7..f8a649ea 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -38,9 +38,9 @@ gulp updates can be found on the following twitters: - [@eschoff](https://twitter.com/eschoff) - [@gulpjs](https://twitter.com/gulpjs) -## Does gulp have an IRC channel? +## Does gulp have an chat channel? -Yes, come chat with us in #gulpjs on [Freenode]. +Yes, come chat with us on [Gitter](https://gitter.im/gulpjs/gulp). [Writing a gulp plugin]: writing-a-plugin/README.md [gulp introduction slideshow]: https://slid.es/contra/gulp From 9fc412590747b5e20b4c5b52f59446aaf84632f9 Mon Sep 17 00:00:00 2001 From: Jesse McCarthy Date: Tue, 26 Jan 2016 14:04:10 -0500 Subject: [PATCH 053/225] Fix: Add support for gulp.watch usage w/o opts or callback --- docs/API.md | 12 +++++++----- index.js | 2 ++ test/watch.js | 4 ++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/API.md b/docs/API.md index 201114b6..e95cc52f 100644 --- a/docs/API.md +++ b/docs/API.md @@ -504,7 +504,7 @@ Type: `Array`, `String` or `Function` A task name, a function or an array of either. -### gulp.watch(glob[, opts], fn) +### gulp.watch(glob[, opts][, fn]) Watch files and do something when a file changes. File watching is provided by the [`chokidar`][chokidar] module. @@ -515,7 +515,7 @@ Please report any file watching problems directly to its gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); ``` -In the example, `gulp.watch` runs the function returned by gulp.parallel each +In the example, `gulp.watch` runs the function returned by `gulp.parallel` each time a file with the `js` extension in `js/` is updated. #### glob @@ -548,12 +548,14 @@ Read about the full set of options in [`chokidar`'s README][chokidar]. #### fn Type: `Function` -An [async](#async-support) function to run when a file changes. +An [async](#async-support) function to run when a file changes. Does not provide +access to the `path` parameter. `gulp.watch` returns a wrapped [chokidar] FSWatcher object. If provided, the callback will be triggered upon any `add`, `change`, or `unlink` event. Listeners can also be set directly for any of [chokidar]'s events, such as -`addDir`, `unlinkDir`, and `error`. +`addDir`, `unlinkDir`, and `error`. You must set listeners directly to get +access to chokidar's callback parameters, such as `path`. ```js var watcher = gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); @@ -569,7 +571,7 @@ watcher.on('unlink', function(path) { ##### path Type: `String` -The relative path of the document. +Path to the file. If `opts.cwd` is set, `path` is relative to it. ##### stats Type: `Object` diff --git a/index.js b/index.js index e3b5b4fe..2058ce0b 100644 --- a/index.js +++ b/index.js @@ -35,6 +35,8 @@ Gulp.prototype.watch = function(glob, opt, task) { opt = {}; } + opt = opt || {}; + var fn; if (typeof task === 'function') { fn = this.parallel(task); diff --git a/test/watch.js b/test/watch.js index 787b6543..d2d15b48 100644 --- a/test/watch.js +++ b/test/watch.js @@ -126,6 +126,10 @@ describe('gulp', function() { updateTempFile(tempFile); }); + it('should work without options or callback', function() { + gulp.watch('x'); + }); + it('should run many tasks: w/ options', function(done) { var tempFile = path.join(outpath, 'watch-task-options.txt'); var a = 0; From a379529aa5a101550f4b578205c622ad821ccdd1 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 14 Feb 2016 22:35:17 +0300 Subject: [PATCH 054/225] Upgrade: Update undertaker --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7d04e53b..af155392 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dependencies": { "chokidar": "^1.2.0", "gulp-cli": "^1.0.0", - "undertaker": "^0.13.0", + "undertaker": "^0.15.0", "vinyl-fs": "^2.0.0" }, "devDependencies": { From d90198c0f49305fc54baffa7acc0d731bd7ba781 Mon Sep 17 00:00:00 2001 From: Mehdy Dara Date: Fri, 18 Mar 2016 00:46:51 +0100 Subject: [PATCH 055/225] Docs: Add link to "Intro to Gulp 4" video --- docs/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/README.md b/docs/README.md index d72ff7d2..db9b6cdd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,6 +23,8 @@ The community has written [recipes](recipes#recipes) for common gulp use-cases. Post on [StackOverflow with a #gulp tag](https://stackoverflow.com/questions/tagged/gulp) or come chat with us in [#gulpjs](https://webchat.freenode.net/?channels=gulpjs) on [Freenode](https://freenode.net/). +## Videos +* [Intro to Gulp 4](https://youtu.be/N42LQ2dLoA8) presented by @addyosmani and @gauntface ## Books * [Developing a gulp Edge](http://shop.oreilly.com/product/9781939902146.do) From e1afdfdbd38add2c059532055eb3c9f0299d09e3 Mon Sep 17 00:00:00 2001 From: Jere Menichelli Date: Wed, 2 Mar 2016 17:10:54 -0300 Subject: [PATCH 056/225] Docs: Add ES2015 gulpfile example to readme --- README.md | 184 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 143 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index ea3cf1ad..8f102d85 100644 --- a/README.md +++ b/README.md @@ -28,65 +28,167 @@ This file will give you a taste of what gulp does. ```js var gulp = require('gulp'); -var coffee = require('gulp-coffee'); +var less = require('gulp-less'); +var babel = require('gulp-babel'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); -var imagemin = require('gulp-imagemin'); -var sourcemaps = require('gulp-sourcemaps'); +var rename = require('gulp-rename'); +var cleanCSS = require('gulp-clean-css'); var del = require('del'); var paths = { - scripts: ['client/js/**/*.coffee', '!client/external/**/*.coffee'], - images: 'client/img/**/*' + styles: { + src: 'src/styles/**/*.less', + dest: 'assets/styles/' + }, + scripts: { + src: 'src/scripts/**/*.js', + dest: 'assets/scripts/' + } }; -/* Register some tasks to expose to the cli */ -gulp.task('build', gulp.series( - clean, - gulp.parallel(scripts, images) -)); -gulp.task(clean); -gulp.task(watch); +/* Not all tasks need to use streams, a gulpfile is just another node program + * and you can use all packages available on npm, but it must return either a + * Promise, a Stream or take a callback and call it + */ +function clean() { + // You can use multiple globbing patterns as you would with `gulp.src`, + // for example if you are using del 2.0 or above, return its promise + return del([ 'assets' ]); +} -// The default task (called when you run `gulp` from cli) -gulp.task('default', gulp.series('build')); +/* + * Define our tasks using plain functions + */ +function styles() { + return gulp.src(paths.styles.src) + .pipe(less()) + .pipe(cleanCSS()) + // pass in options to the stream + .pipe(rename({ + basename: 'main', + suffix: '.min' + })) + .pipe(gulp.dest(paths.styles.dest)); +} +function scripts() { + return gulp.src(paths.scripts.src, { sourcemaps: true }) + .pipe(babel()) + .pipe(uglify()) + .pipe(concat('main.min.js')) + .pipe(gulp.dest(paths.scripts.dest)); +} -/* Define our tasks using plain functions */ +function watch() { + gulp.watch(paths.scripts.src, scripts); + gulp.watch(paths.styles.src, styles); +} -// Not all tasks need to use streams -// But it must return either a Promise or Stream or take a Callback and call it -function clean() { - // You can use multiple globbing patterns as you would with `gulp.src` - // If you are using del 2.0 or above, return its promise - return del(['build']); +/* + * You can use CommonJS `exports` module notation to declare tasks + */ +exports.clean = clean; +exports.styles = styles; +exports.scripts = scripts; +exports.watch = watch; + +/* + * Specify if tasks run in series or parallel using `gulp.series` and `gulp.parallel` + */ +var build = gulp.series(clean, gulp.parallel(styles, scripts)); + +/* + * You can still use `gulp.task` to expose tasks + */ +gulp.task('build', build); + +/* + * Define default task that can be called by just running `gulp` from cli + */ +gulp.task('default', build); +``` + +## Use latest JavaScript version in your gulpfile + +Node already supports a lot of **ES2015**, to avoid compatibility problem we suggest to install Babel and rename your `gulpfile.js` as `gulpfile.babel.js`. + +```sh +npm install --save-dev babel-register babel-preset-es2015 +``` + +Then create a **.babelrc** file with the preset configuration. + +```js +{ + "presets": [ "es2015" ] } +``` -// Copy all static images -function images() { - return gulp.src(paths.images) - // Pass in options to the task - .pipe(imagemin({optimizationLevel: 5})) - .pipe(gulp.dest('build/img')); +And here's the same sample from above written in **ES2015**. + +```js +import gulp from 'gulp'; +import less from 'gulp-less'; +import babel from 'gulp-babel'; +import concat from 'gulp-concat'; +import uglify from 'gulp-uglify'; +import rename from 'gulp-rename'; +import cleanCSS from 'gulp-clean-css'; +import del from 'del'; + +const paths = { + styles: { + src: 'src/styles/**/*.less', + dest: 'assets/styles/' + }, + scripts: { + src: 'src/scripts/**/*.js', + dest: 'assets/scripts/' + } +}; + +/* + * For small tasks you can use arrow functions and export + */ +const clean = () => del([ 'assets' ]); +export { clean }; + +/* + * You can still declare named functions and export them as tasks + */ +export function styles() { + return gulp.src(paths.styles.src) + .pipe(less()) + .pipe(cleanCSS()) + // pass in options to the stream + .pipe(rename({ + basename: 'main', + suffix: '.min' + })) + .pipe(gulp.dest(paths.styles.dest)); } -// Minify and copy all JavaScript (except vendor scripts) -// with sourcemaps all the way down -function scripts() { - return gulp.src(paths.scripts) - .pipe(sourcemaps.init()) - .pipe(coffee()) - .pipe(uglify()) - .pipe(concat('all.min.js')) - .pipe(sourcemaps.write()) - .pipe(gulp.dest('build/js')); +export function scripts() { + return gulp.src(paths.scripts.src, { sourcemaps: true }) + .pipe(babel()) + .pipe(uglify()) + .pipe(concat('main.min.js')) + .pipe(gulp.dest(paths.scripts.dest)); } -// Rerun the task when a file changes -function watch() { - gulp.watch(paths.scripts, scripts); - gulp.watch(paths.images, images); +export function watch() { + gulp.watch(paths.scripts.src, scripts); + gulp.watch(paths.styles.src, styles); } + +const build = gulp.series(clean, gulp.parallel(styles, scripts)); +export { build }; + +/* + * Export a default task + */ +export default build; ``` ## Incremental Builds From 5ddd6734537095c4f8cde846d89160f87d0a54a1 Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Fri, 22 Jan 2016 12:20:42 -0500 Subject: [PATCH 057/225] Docs: Update "getting started" example for new syntax --- docs/getting-started.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 06e0c9b8..724b942b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -37,10 +37,12 @@ In your project directory, create a file named `gulpfile.js` in your project roo ```js var gulp = require('gulp'); -gulp.task('default', function(done) { +gulp.task('default', defaultTask); + +function defaultTask(done) { // place code for your default task here done(); -}); +} ``` #### Test it out @@ -63,6 +65,10 @@ Using gulpfile ~/my-project/gulpfile.js [11:15:51] Finished 'default' after 103 μs ``` +## .src, .watch, .dest, .parallel, .series, CLI args - How do I use these things? + +For API specific documentation, you can check out the [documentation for that](API.md). + ## Where do I go now? - [API Documentation](API.md) - The programming interface, defined From e89431257333b8089ab39332c279a93aacd30753 Mon Sep 17 00:00:00 2001 From: Mike Street Date: Tue, 5 Apr 2016 22:33:11 +0100 Subject: [PATCH 058/225] Docs: Add link to "Upgrading to Gulp 4" article --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index db9b6cdd..4f8761b4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -44,7 +44,7 @@ Post on [StackOverflow with a #gulp tag](https://stackoverflow.com/questions/tag * [Get started with gulp (video series)](https://www.youtube.com/playlist?list=PLRk95HPmOM6PN-G1xyKj9q6ap_dc9Yckm) * [Optimize your web code with gulp](http://www.linuxuser.co.uk/tutorials/optimise-your-web-code-with-gulp-js) * [Automate Your Tasks Easily with Gulp.js ](https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js) - +* [How to upgrade to Gulp v4](https://www.liquidlight.co.uk/blog/article/how-do-i-update-to-gulp-4/) ## Examples From 1351fb8d13531f5ff931bbe902d7cda1bf31f182 Mon Sep 17 00:00:00 2001 From: ptb Date: Sat, 9 Apr 2016 15:55:36 -0400 Subject: [PATCH 059/225] Docs: Add missing parenthesis (#1599) --- docs/recipes/running-tasks-in-series.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/running-tasks-in-series.md b/docs/recipes/running-tasks-in-series.md index 5dfad24d..b28e692a 100644 --- a/docs/recipes/running-tasks-in-series.md +++ b/docs/recipes/running-tasks-in-series.md @@ -41,7 +41,7 @@ gulp.task('templates', gulp.series('clean', function() { return gulp.src(['src/templates/*.hbs']) // do some concatenation, minification, etc. .pipe(gulp.dest('output/templates/')); -}); +})); gulp.task('styles', gulp.series('clean', function() { return gulp.src(['src/styles/app.less']) From c3dbc10afa7dcd8c86eebcd7f87967ac1f680da2 Mon Sep 17 00:00:00 2001 From: Gregory Date: Mon, 18 Apr 2016 19:54:56 -0400 Subject: [PATCH 060/225] Docs: Clarify incremental builds example (#1609) --- README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8f102d85..8b8ce9bc 100644 --- a/README.md +++ b/README.md @@ -196,14 +196,22 @@ export default build; You can filter out unchanged files between runs of a task using the `gulp.src` function's `since` option and `gulp.lastRun`: ```js +const paths = { + ... + images: { + src: 'src/images/**/*.{jpg,jpeg,png}', + dest: 'build/img/' + } +} + function images() { - return gulp.src(paths.images, {since: gulp.lastRun('images')}) + return gulp.src(paths.images.src, {since: gulp.lastRun('images')}) .pipe(imagemin({optimizationLevel: 5})) - .pipe(gulp.dest('build/img')); + .pipe(gulp.dest(paths.images.dest)); } function watch() { - gulp.watch(paths.images, images); + gulp.watch(paths.images.src, images); } ``` Task run times are saved in memory and are lost when gulp exits. It will only From 0c660697b8376c0185bb9e65aca0c01107b7433e Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 27 Apr 2016 20:02:30 -0700 Subject: [PATCH 061/225] Breaking: Replace chokidar as gulp.watch with glob-watcher wrapper --- index.js | 16 ++-------------- package.json | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index 2058ce0b..cddf7eb6 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ var util = require('util'); var Undertaker = require('undertaker'); var vfs = require('vinyl-fs'); -var chokidar = require('chokidar'); +var watch = require('glob-watcher'); function Gulp() { Undertaker.call(this); @@ -42,19 +42,7 @@ Gulp.prototype.watch = function(glob, opt, task) { fn = this.parallel(task); } - if (opt.ignoreInitial == null) { - opt.ignoreInitial = true; - } - - var watcher = chokidar.watch(glob, opt); - if (fn) { - watcher - .on('change', fn) - .on('unlink', fn) - .on('add', fn); - } - - return watcher; + return watch(glob, opt, fn); }; // Let people use this class from our instance diff --git a/package.json b/package.json index af155392..a23a0dd8 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ }, "man": "gulp.1", "dependencies": { - "chokidar": "^1.2.0", + "glob-watcher": "^3.0.0", "gulp-cli": "^1.0.0", "undertaker": "^0.15.0", "vinyl-fs": "^2.0.0" From 5dc3b07bd61c217c432c508573583827ef592cd1 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 30 Apr 2016 13:35:10 -0700 Subject: [PATCH 062/225] Docs: Update gulp.watch API to align with glob-watcher --- docs/API.md | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/docs/API.md b/docs/API.md index e95cc52f..dd41e9c7 100644 --- a/docs/API.md +++ b/docs/API.md @@ -7,7 +7,7 @@ * [gulp.lastRun](#gulplastruntaskname-timeresolution) - Get timestamp of last successful run * [gulp.parallel](#gulpparalleltasks) - Run tasks in parallel * [gulp.series](#gulpseriestasks) - Run tasks in series -* [gulp.watch](#gulpwatchglob-opts-fn) - Do something when a file changes +* [gulp.watch](#gulpwatchglobs-opts-fn) - Do something when a file changes * [gulp.tree](#gulptreeoptions) - Get the tree of tasks * [gulp.registry](#gulpregistryregistry) - Get or set the task registry @@ -504,28 +504,31 @@ Type: `Array`, `String` or `Function` A task name, a function or an array of either. -### gulp.watch(glob[, opts][, fn]) +### gulp.watch(globs[, opts][, fn]) -Watch files and do something when a file changes. -File watching is provided by the [`chokidar`][chokidar] module. -Please report any file watching problems directly to its -[issue tracker](https://github.com/paulmillr/chokidar/issues). +Takes a path string, an array of path strings, a [glob][node-glob] string or an array of [glob][node-glob] strings as `globs` to watch on the filesystem. Also optionally takes `options` to configure the watcher and a `fn` to execute when a file changes. + +Returns an instance of [`chokidar`][chokidar]. ```js -gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); +gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify')); ``` In the example, `gulp.watch` runs the function returned by `gulp.parallel` each time a file with the `js` extension in `js/` is updated. -#### glob +#### globs Type: `String` or `Array` -A single glob or array of globs that indicate which files to watch for changes. +A path string, an array of path strings, a [glob][node-glob] string or an array of [glob][node-glob] strings that indicate which files to watch for changes. #### opts Type: `Object` +* `delay` (milliseconds, default: `200`). The delay to wait before triggering the fn. Useful for waiting on many changes before doing the work on changed files, e.g. find-and-replace on many files. +* `queue` (boolean, default: `true`). Whether or not a file change should queue the fn execution if the fn is already running. Useful for a long running fn. +* `ignoreInitial` (boolean, default: `true`). If set to `false` the `fn` is called during [chokidar][chokidar] instantiation as it discovers the file paths. Useful if it is desirable to trigger the `fn` during startup. __Passed through to [chokidar][chokidar], but defaulted to `true` instead of `false`.__ + Options that are passed to [`chokidar`][chokidar]. Commonly used options: @@ -548,17 +551,21 @@ Read about the full set of options in [`chokidar`'s README][chokidar]. #### fn Type: `Function` -An [async](#async-support) function to run when a file changes. Does not provide -access to the `path` parameter. +If the `fn` is passed, it will be called when the watcher emits a `change`, `add` or `unlink` event. It is automatically debounced with a default delay of 200 milliseconds and subsequent calls will be queued and called upon completion. These defaults can be changed using the `options`. + +The `fn` is passed a single argument, `callback`, which is a function that must be called when work in the `fn` is complete. Instead of calling the `callback` function, [async completion][async-completion] can be signalled by: + * Returning a `Stream` or `EventEmitter` + * Returning a `Child Process` + * Returning a `Promise` + * Returning an `Observable` + +Once async completion is signalled, if another run is queued, it will be executed. -`gulp.watch` returns a wrapped [chokidar] FSWatcher object. If provided, -the callback will be triggered upon any `add`, `change`, or `unlink` event. -Listeners can also be set directly for any of [chokidar]'s events, such as -`addDir`, `unlinkDir`, and `error`. You must set listeners directly to get +`gulp.watch` returns a wrapped [chokidar] FSWatcher object. Listeners can also be set directly for any of [chokidar]'s events, such as `addDir`, `unlinkDir`, and `error`. You must set listeners directly to get access to chokidar's callback parameters, such as `path`. ```js -var watcher = gulp.watch('js/**/*.js', gulp.parallel('uglify', 'reload')); +var watcher = gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify')); watcher.on('change', function(path, stats) { console.log('File ' + path + ' was changed'); }); @@ -815,3 +822,4 @@ module.exports = new MyCompanyTasksRegistry(); [vinyl File instance]: https://github.com/gulpjs/vinyl [Vinyl files]: https://github.com/gulpjs/vinyl-fs [fs stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats +[async-completion]: https://github.com/gulpjs/async-done#completion-and-error-resolution From d4ed3c7e3fb13f3b1bf6f8309cca8459e53f9edb Mon Sep 17 00:00:00 2001 From: xiaoyu2er Date: Fri, 13 May 2016 05:04:37 +0800 Subject: [PATCH 063/225] Docs: Add options.cwd for gulp.src API (#1645) --- docs/API.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/API.md b/docs/API.md index dd41e9c7..1415c6af 100644 --- a/docs/API.md +++ b/docs/API.md @@ -60,6 +60,15 @@ Options to pass to [node-glob] through [glob-stream]. gulp adds some additional options in addition to the [options supported by node-glob][node-glob documentation] and [glob-stream]: +##### options.cwd + +The working directory the folder is relative to. + +Type: `String` + +Default: `process.cwd()` + + ##### options.buffer Type: `Boolean` From 477db84761551ab25127447a8425c79dc4808e15 Mon Sep 17 00:00:00 2001 From: Lim H Date: Fri, 13 May 2016 19:49:32 +0100 Subject: [PATCH 064/225] Docs: Add a "BrowserSync with Gulp 4" recipe (#1659) --- .../minimal-browsersync-setup-with-gulp4.md | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 docs/recipes/minimal-browsersync-setup-with-gulp4.md diff --git a/docs/recipes/minimal-browsersync-setup-with-gulp4.md b/docs/recipes/minimal-browsersync-setup-with-gulp4.md new file mode 100644 index 00000000..ec22c071 --- /dev/null +++ b/docs/recipes/minimal-browsersync-setup-with-gulp4.md @@ -0,0 +1,161 @@ +# Minimal BrowserSync setup with Gulp 4 + +[BrowserSync](https://www.browsersync.io/) is a great tool to streamline +the development process with the ability to reflect code changes instantaneously +in the browser through live-reloading. Setting up a live-reloading +BrowserSync server with Gulp 4 is very clean and easy. + +## Step 1: Install the dependencies + +``` +npm install --save-dev browser-sync +``` + +## Step 2: Setup the project structure + +``` +src/ + scripts/ + |__ index.js +dist/ + scripts/ +index.html +gulpfile.babel.js +``` + +The goal here is to be able to: +- Build the source script file in `src/scripts/`, e.g. compiling with babel, minifying, etc. +- Put the compiled version in `dist/scripts` for use in `index.html` +- Watch for changes in the source file and rebuild the `dist` package +- With each rebuild of the `dist` package, reload the browser to immediately reflect the changes + +## Step 3: Write the gulpfile + +The gulpfile could be broken in 3 parts. + +### 1. Write the task to prepare the dist package as usual + +Refer to the main [README](https://github.com/gulpjs/gulp/blob/4.0/README.md#use-last-javascript-version-in-your-gulpfile) +for more information. + +```javascript +import babel from 'gulp-babel'; +import concat from 'gulp-concat'; +import del from 'del'; +import gulp from 'gulp'; +import uglify from 'gulp-uglify'; + +const paths = { + scripts: { + src: 'src/scripts/*.js', + dest: 'dist/scripts/' + } +}; + +const clean = () => del(['dist']); + +function scripts() { + return gulp.src(paths.scripts.src, { sourcemaps: true }) + .pipe(babel()) + .pipe(uglify()) + .pipe(concat('index.min.js')) + .pipe(gulp.dest(paths.scripts.dest)); +} +``` + +### 2. Setup the BrowserSync server + +And write the tasks to serve and reload the server accordingly. + +```javascript +import browserSync from 'browser-sync'; +const server = browserSync.create(); + +function reload(done) { + server.reload(); + done(); +} + +function serve(done) { + server.init({ + server: { + baseDir: './' + } + }); + done(); +} +``` + +### 3. Watch for source change, rebuild the scripts and reload the server + +This is trivially accomplished with `gulp.series` + +```javascript +const watch = () => gulp.watch(paths.scripts.src, gulp.series(scripts, reload)); +``` + +## Step 4: Bring it all together + +The last step is to expose the default task + +```javascript +const dev = gulp.series(clean, scripts, serve, watch); +export default dev; +``` + +And profit + +```bash +$ gulp +``` + +Now if you go to [http://localhost:3000](http://localhost:3000), which is the default address of the +BrowserSync server, you will see that the end result in the browser is updated everytime you change +the content of the source file. Here is the whole gulpfile: + +```javascript +import babel from 'gulp-babel'; +import concat from 'gulp-concat'; +import del from 'del'; +import gulp from 'gulp'; +import uglify from 'gulp-uglify'; +import browserSync from 'browser-sync'; + +const server = browserSync.create(); + +const paths = { + scripts: { + src: 'src/scripts/*.js', + dest: 'dist/scripts/' + } +}; + +const clean = () => del(['dist']); + +function scripts() { + return gulp.src(paths.scripts.src, { sourcemaps: true }) + .pipe(babel()) + .pipe(uglify()) + .pipe(concat('index.min.js')) + .pipe(gulp.dest(paths.scripts.dest)); +} + +function reload(done) { + server.reload(); + done(); +} + +function serve(done) { + server.init({ + server: { + baseDir: './' + } + }); + done(); +} + +const watch = () => gulp.watch(paths.scripts.src, gulp.series(scripts, reload)); + +const dev = gulp.series(clean, scripts, serve, watch); +export default dev; +``` From e931cb0bbf5acfb68f3e3086dae311ec733f0f14 Mon Sep 17 00:00:00 2001 From: "Chris J. Lee" Date: Tue, 21 Jun 2016 13:59:54 -0500 Subject: [PATCH 065/225] Docs: Fix changelog typos (#1696) --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 860674c5..d6555ded 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,9 +40,9 @@ - add babel support - add transpiler fallback support -- add support for some renamed transpilers (livescript, etc) +- add support for some renamed transpilers: livescript, etc - add JSCS -- update dependecies (liftoff, interpret) +- update dependencies (liftoff, interpret) - documentation tweaks ## 3.8.11 From 29ece6fc230fec095b84906437530b0257b26a4c Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 27 Jun 2016 19:54:55 -0700 Subject: [PATCH 066/225] Upgrade: Update undertaker --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a23a0dd8..89ce486a 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dependencies": { "glob-watcher": "^3.0.0", "gulp-cli": "^1.0.0", - "undertaker": "^0.15.0", + "undertaker": "^1.0.0", "vinyl-fs": "^2.0.0" }, "devDependencies": { From d420a6a742af91dcfc3e5a83f7552d2a8114471f Mon Sep 17 00:00:00 2001 From: Jake Archibald Date: Mon, 24 Oct 2016 12:48:33 +0100 Subject: [PATCH 067/225] Docs: Have gulp.lastRun take a function to avoid task registration (#1828) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b8ce9bc..7f999680 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,7 @@ const paths = { } function images() { - return gulp.src(paths.images.src, {since: gulp.lastRun('images')}) + return gulp.src(paths.images.src, {since: gulp.lastRun(images)}) .pipe(imagemin({optimizationLevel: 5})) .pipe(gulp.dest(paths.images.dest)); } From 723cbc40e76f3b43c3ec7d56fa4ed36298e912b4 Mon Sep 17 00:00:00 2001 From: Martin van Driel Date: Tue, 8 Nov 2016 04:21:48 +0100 Subject: [PATCH 068/225] Docs: Fix syntax in recipe example (#1715) --- docs/recipes/server-with-livereload-and-css-injection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/server-with-livereload-and-css-injection.md b/docs/recipes/server-with-livereload-and-css-injection.md index 74280505..f5e1222f 100644 --- a/docs/recipes/server-with-livereload-and-css-injection.md +++ b/docs/recipes/server-with-livereload-and-css-injection.md @@ -96,7 +96,7 @@ gulp.task('serve', gulp.series('sass', function() { }); gulp.watch('scss/*.scss', gulp.series('sass')); -}); +})); ``` and including the pre-processed CSS in `index.html`: From 0ac9e043a4d6947ff2ae4496657ae44b21b5a958 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Fri, 18 Nov 2016 21:26:26 +0000 Subject: [PATCH 069/225] Docs: Add "Project structure" section to CONTRIBUTING.md (#1859) --- CONTRIBUTING.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7d8f4d5c..15e8baa3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,6 +28,53 @@ of the content - formatting: help keep content easy to read with consistent formatting - code: Fix issues or contribute new features to this or any related projects +# Project structure + +Gulp itself is tiny: index.js contains [very few lines of code](https://github.com/gulpjs/gulp/blob/4.0/index.js). +It is powered by a few other libraries which each handle a few specific tasks +each. + +You can view all issues with the "help wanted" label across all gulp projects +here: https://github.com/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+user%3Agulpjs+label%3A%22help+wanted%22+ + +## Undertaker: task management + +Undertaker handles task management in Gulp: the `gulp.task()`, `gulp.series()` +and `gulp.parallel()` functions. `gulp.series()` and `gulp.parallel()` are in +turn powered by Bach. + +- https://github.com/gulpjs/undertaker +- https://github.com/gulpjs/bach + +## vinyl-fs: file streams + +vinyl-fs powers the `gulp.src()` and `gulp.dest()` functions: they take files +and globs specified by the user, turns them into a stream of file objects, +and then puts them back into the filesystem when `gulp.dest()` is called. + +The file objects themselves are vinyl objects: that's another library (a simple +one!) + +- https://github.com/gulpjs/vinyl-fs +- https://github.com/gulpjs/vinyl + +## chokidar: file watching + +`gulp.watch()` is using chokidar for file watching. It's actually wrapped in a +small library on the gulp organization, glob-watcher. + +- https://github.com/paulmillr/chokidar +- https://github.com/gulpjs/glob-watcher + +## gulp-cli: running gulp + +Finally, we have gulp-cli. This uses liftoff to take what people run in the +command line and run the correct tasks. It works with both gulp 4 and older +versions of gulp. + +- https://github.com/gulpjs/gulp-cli +- https://github.com/js-cli/js-liftoff + # Conduct We are committed to providing a friendly, safe and welcoming environment for From 89acc5c17e115ec03ec6b17341c3ffdf5e2db837 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Mon, 24 Jul 2017 19:16:35 +0100 Subject: [PATCH 070/225] Docs: Improve ES2015 task exporting examples (#1999) --- README.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7f999680..3bc84dba 100644 --- a/README.md +++ b/README.md @@ -149,13 +149,12 @@ const paths = { }; /* - * For small tasks you can use arrow functions and export + * For small tasks you can export arrow functions */ -const clean = () => del([ 'assets' ]); -export { clean }; +export const clean = () => del([ 'assets' ]); /* - * You can still declare named functions and export them as tasks + * You can also declare named functions and export them as tasks */ export function styles() { return gulp.src(paths.styles.src) @@ -177,13 +176,21 @@ export function scripts() { .pipe(gulp.dest(paths.scripts.dest)); } -export function watch() { + /* + * You could even use `export as` to rename exported tasks + */ +function watchFiles() { gulp.watch(paths.scripts.src, scripts); gulp.watch(paths.styles.src, styles); } +export { watchFiles as watch }; -const build = gulp.series(clean, gulp.parallel(styles, scripts)); -export { build }; +/* + * You can still use `gulp.task` + * for example to set task names that would otherwise be invalid + */ +const clean = gulp.series(clean, gulp.parallel(styles, scripts)); +gulp.task('clean', clean); /* * Export a default task From c1ba80cb6b1a2e1469a7f422ec6ee93ac589d714 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 21 Dec 2017 16:04:04 -0700 Subject: [PATCH 071/225] Breaking: Upgrade major versions of glob-watcher, gulp-cli & vinyl-fs --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 89ce486a..398cf95e 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ }, "man": "gulp.1", "dependencies": { - "glob-watcher": "^3.0.0", - "gulp-cli": "^1.0.0", + "glob-watcher": "^4.0.0", + "gulp-cli": "^2.0.0", "undertaker": "^1.0.0", - "vinyl-fs": "^2.0.0" + "vinyl-fs": "^3.0.0" }, "devDependencies": { "coveralls": "^2.7.0", From 057df5963034eb6426d99650abba15e4d912b0b7 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 14:59:05 -0700 Subject: [PATCH 072/225] Release: 4.0.0-alpha.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 398cf95e..3b4d869d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "gulp", "description": "The streaming build system", - "version": "4.0.0-alpha.2", + "version": "4.0.0-alpha.3", "homepage": "http://gulpjs.com", "repository": "gulpjs/gulp", "author": "Fractal (http://wearefractal.com/)", From 064d1001528bc493282f006db6b02d24f97bd981 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 21 Dec 2017 16:12:23 -0700 Subject: [PATCH 073/225] Build: Avoid broken node 9 --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8cf5aded..5756ce0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,7 @@ node_js: - "0.10" - "0.12" - "4" - - "5" - "6" - - "7" - "8" after_script: - npm run coveralls From 361ab63d5d661dee46e032c3ecac1e085c526f1a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 29 Dec 2017 19:05:28 -0700 Subject: [PATCH 074/225] Upgrade: Update glob-watcher --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b4d869d..5f6679b9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ }, "man": "gulp.1", "dependencies": { - "glob-watcher": "^4.0.0", + "glob-watcher": "^5.0.0", "gulp-cli": "^2.0.0", "undertaker": "^1.0.0", "vinyl-fs": "^3.0.0" From f27be05f6d7650ffb3ec3f9375f2d9c50c7010df Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 29 Dec 2017 19:06:54 -0700 Subject: [PATCH 075/225] Update: Remove graceful-fs from test suite --- package.json | 1 - test/dest.js | 3 ++- test/watch.js | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 5f6679b9..7ea402ec 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "coveralls": "^2.7.0", "eslint": "^1.7.3", "eslint-config-gulp": "^2.0.0", - "graceful-fs": "^3.0.0", "istanbul": "^0.3.0", "jscs": "^2.3.5", "jscs-preset-gulp": "^1.0.0", diff --git a/test/dest.js b/test/dest.js index 90dcb9d0..c5f2729f 100644 --- a/test/dest.js +++ b/test/dest.js @@ -1,10 +1,11 @@ 'use strict'; +var fs = require('fs'); + var gulp = require('../'); var should = require('should'); var join = require('path').join; var rimraf = require('rimraf'); -var fs = require('graceful-fs'); require('mocha'); diff --git a/test/watch.js b/test/watch.js index d2d15b48..d943944e 100644 --- a/test/watch.js +++ b/test/watch.js @@ -1,7 +1,8 @@ 'use strict'; +var fs = require('fs'); + var gulp = require('../'); -var fs = require('graceful-fs'); var rimraf = require('rimraf'); var mkdirp = require('mkdirp'); var path = require('path'); From 3011cf9a50898030304a159c9e0bad30630380e3 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 13:12:33 -0700 Subject: [PATCH 076/225] Scaffold: Normalize repository --- .editorconfig | 4 +- .gitattributes | 1 + .gitignore | 40 +++++-- .jscsrc | 2 +- .npmignore | 12 --- .travis.yml | 12 +-- LICENSE | 33 +++--- appveyor.yml | 25 +++++ package.json | 67 ++++++------ test/dest.js | 206 ++++++++++++++++++------------------ test/src.js | 254 ++++++++++++++++++++++---------------------- test/watch.js | 279 +++++++++++++++++++++++++------------------------ 12 files changed, 483 insertions(+), 452 deletions(-) create mode 100644 .gitattributes delete mode 100644 .npmignore create mode 100644 appveyor.yml diff --git a/.editorconfig b/.editorconfig index 5d126348..e000b0ce 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,13 +1,13 @@ -# editorconfig.org +# http://editorconfig.org root = true [*] indent_style = space indent_size = 2 -end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true +end_of_line = lf [*.md] trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..fcadb2cf --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text eol=lf diff --git a/.gitignore b/.gitignore index cef23f00..6f636468 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,31 @@ -.DS_Store +# Logs +logs *.log -node_modules -build -*.node -components + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul coverage -*.orig -.idea -sandbox -test/out-fixtures/* -test/watch-*.txt -gulp.1 + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- +node_modules + +# Users Environment Variables +.lock-wscript + +# Garbage files +.DS_Store diff --git a/.jscsrc b/.jscsrc index d9e4b9a1..703b33fc 100644 --- a/.jscsrc +++ b/.jscsrc @@ -1,3 +1,3 @@ { - "preset": "gulp", + "preset": "gulp" } diff --git a/.npmignore b/.npmignore deleted file mode 100644 index f93c3951..00000000 --- a/.npmignore +++ /dev/null @@ -1,12 +0,0 @@ -.DS_Store -*.log -node_modules -build -*.node -components -coverage -*.orig -.idea -sandbox -test/out-fixtures/* -test/watch-*.txt diff --git a/.travis.yml b/.travis.yml index 5756ce0c..f621cabd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,10 @@ sudo: false language: node_js node_js: - - "0.10" - - "0.12" - - "4" - - "6" - - "8" + - '8' + - '6' + - '4' + - '0.12' + - '0.10' after_script: - npm run coveralls -git: - depth: 10 diff --git a/LICENSE b/LICENSE index ee25a909..6355a4b4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,22 +1,21 @@ The MIT License (MIT) -Copyright (c) 2013-2016 Fractal +Copyright (c) 2013-2017 Blaine Bublitz , Eric Schoffstall and other contributors -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..e2d9fb3a --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,25 @@ +# http://www.appveyor.com/docs/appveyor-yml +# http://www.appveyor.com/docs/lang/nodejs-iojs + +environment: + matrix: + # node.js + - nodejs_version: "0.10" + - nodejs_version: "0.12" + - nodejs_version: "4" + - nodejs_version: "6" + - nodejs_version: "8" + +install: + - ps: Install-Product node $env:nodejs_version + - npm install + +test_script: + - node --version + - npm --version + - cmd: npm test + +build: off + +# build version format +version: "{build}" diff --git a/package.json b/package.json index 7ea402ec..31dab214 100644 --- a/package.json +++ b/package.json @@ -1,27 +1,34 @@ { "name": "gulp", - "description": "The streaming build system", "version": "4.0.0-alpha.3", + "description": "The streaming build system.", "homepage": "http://gulpjs.com", - "repository": "gulpjs/gulp", - "author": "Fractal (http://wearefractal.com/)", - "keywords": [ - "build", - "stream", - "system", - "make", - "tool", - "asset", - "pipeline" + "author": "Gulp Team (http://gulpjs.com/)", + "contributors": [ + "Eric Schoffstall ", + "Blaine Bublitz " ], + "repository": "gulpjs/gulp", + "license": "MIT", + "engines": { + "node": ">= 0.10" + }, + "main": "index.js", "files": [ + "LICENSE", "index.js", "bin" ], "bin": { "gulp": "./bin/gulp.js" }, - "man": "gulp.1", + "scripts": { + "lint": "eslint . && jscs index.js bin/ test/", + "pretest": "npm run lint", + "test": "mocha --async-only", + "cover": "istanbul cover _mocha --report lcovonly", + "coveralls": "npm run cover && istanbul-coveralls" + }, "dependencies": { "glob-watcher": "^5.0.0", "gulp-cli": "^2.0.0", @@ -29,27 +36,27 @@ "vinyl-fs": "^3.0.0" }, "devDependencies": { - "coveralls": "^2.7.0", "eslint": "^1.7.3", "eslint-config-gulp": "^2.0.0", - "istanbul": "^0.3.0", + "expect": "^1.20.2", + "istanbul": "^0.4.3", + "istanbul-coveralls": "^1.0.3", "jscs": "^2.3.5", "jscs-preset-gulp": "^1.0.0", - "mkdirp": "^0.5.0", - "mocha": "^2.0.1", - "mocha-lcov-reporter": "^1.0.0", - "q": "^1.0.0", - "rimraf": "^2.2.5", - "should": "^5.0.1" - }, - "scripts": { - "lint": "eslint . && jscs *.js bin/ test/", - "pretest": "npm run lint", - "test": "mocha --reporter spec", - "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" + "mkdirp": "^0.5.1", + "mocha": "^3.0.0", + "rimraf": "^2.2.5" }, - "engines": { - "node": ">= 0.9" - }, - "license": "MIT" + "keywords": [ + "build", + "stream", + "system", + "make", + "tool", + "asset", + "pipeline", + "series", + "parallel", + "streaming" + ] } diff --git a/test/dest.js b/test/dest.js index c5f2729f..3dbba460 100644 --- a/test/dest.js +++ b/test/dest.js @@ -1,133 +1,127 @@ 'use strict'; var fs = require('fs'); +var path = require('path'); -var gulp = require('../'); -var should = require('should'); -var join = require('path').join; +var expect = require('expect'); var rimraf = require('rimraf'); -require('mocha'); +var gulp = require('../'); -var outpath = join(__dirname, './out-fixtures'); +var outpath = path.join(__dirname, './out-fixtures'); -describe('gulp output stream', function() { - describe('dest()', function() { - beforeEach(rimraf.bind(null, outpath)); - afterEach(rimraf.bind(null, outpath)); +describe('gulp.dest()', function() { + beforeEach(rimraf.bind(null, outpath)); + afterEach(rimraf.bind(null, outpath)); - it('should return a stream', function(done) { - var stream = gulp.dest(join(__dirname, './fixtures/')); - should.exist(stream); - should.exist(stream.on); - done(); - }); + it('should return a stream', function(done) { + var stream = gulp.dest(path.join(__dirname, './fixtures/')); + expect(stream).toExist(); + expect(stream.on).toExist(); + done(); + }); - it('should return a output stream that writes files', function(done) { - var instream = gulp.src(join(__dirname, './fixtures/**/*.txt')); - var outstream = gulp.dest(outpath); - instream.pipe(outstream); - - outstream.on('error', done); - outstream.on('data', function(file) { - // Data should be re-emitted right - should.exist(file); - should.exist(file.path); - should.exist(file.contents); - join(file.path, '').should.equal(join(outpath, './copy/example.txt')); - String(file.contents).should.equal('this is a test'); - }); - outstream.on('end', function() { - fs.readFile(join(outpath, 'copy', 'example.txt'), function(err, contents) { - should.not.exist(err); - should.exist(contents); - String(contents).should.equal('this is a test'); - done(); - }); + it('should return a output stream that writes files', function(done) { + var instream = gulp.src('./fixtures/**/*.txt', { cwd: __dirname }); + var outstream = gulp.dest(outpath); + instream.pipe(outstream); + + outstream.on('error', done); + outstream.on('data', function(file) { + // Data should be re-emitted right + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.contents).toExist(); + expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); + expect(file.contents).toEqual('this is a test'); + }); + outstream.on('end', function() { + fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { + expect(err).toNotExist(); + expect(contents).toExist(); + expect(contents).toEqual('this is a test'); + done(); }); }); + }); - it('should return a output stream that does not write non-read files', function(done) { - var instream = gulp.src(join(__dirname, './fixtures/**/*.txt'), { read: false }); - var outstream = gulp.dest(outpath); - instream.pipe(outstream); - - outstream.on('error', done); - outstream.on('data', function(file) { - // Data should be re-emitted right - should.exist(file); - should.exist(file.path); - should.not.exist(file.contents); - join(file.path, '').should.equal(join(outpath, './copy/example.txt')); - }); - outstream.on('end', function() { - fs.readFile(join(outpath, 'copy', 'example.txt'), function(err, contents) { - should.exist(err); - should.not.exist(contents); - done(); - }); + it('should return a output stream that does not write non-read files', function(done) { + var instream = gulp.src('./fixtures/**/*.txt', { read: false, cwd: __dirname }); + var outstream = gulp.dest(outpath); + instream.pipe(outstream); + + outstream.on('error', done); + outstream.on('data', function(file) { + // Data should be re-emitted right + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.contents).toNotExist(); + expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); + }); + outstream.on('end', function() { + fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { + expect(err).toExist(); + expect(contents).toNotExist(); + done(); }); }); + }); - it('should return a output stream that writes streaming files', function(done) { - var instream = gulp.src(join(__dirname, './fixtures/**/*.txt'), { buffer: false }); - var outstream = instream.pipe(gulp.dest(outpath)); - - outstream.on('error', done); - outstream.on('data', function(file) { - // Data should be re-emitted right - should.exist(file); - should.exist(file.path); - should.exist(file.contents); - join(file.path, '').should.equal(join(outpath, './copy/example.txt')); - }); - outstream.on('end', function() { - fs.readFile(join(outpath, 'copy', 'example.txt'), function(err, contents) { - should.not.exist(err); - should.exist(contents); - String(contents).should.equal('this is a test'); - done(); - }); + it('should return a output stream that writes streaming files', function(done) { + var instream = gulp.src('./fixtures/**/*.txt', { buffer: false, cwd: __dirname }); + var outstream = instream.pipe(gulp.dest(outpath)); + + outstream.on('error', done); + outstream.on('data', function(file) { + // Data should be re-emitted right + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.contents).toExist(); + expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); + }); + outstream.on('end', function() { + fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { + expect(err).toNotExist(); + expect(contents).toExist(); + expect(contents).toEqual('this is a test'); + done(); }); }); + }); - it('should return a output stream that writes streaming files into new directories', function(done) { - testWriteDir({}, done); - }); + it('should return a output stream that writes streaming files into new directories', function(done) { + testWriteDir({ cwd: __dirname }, done); + }); - it('should return a output stream that writes streaming files into new directories (buffer: false)', function(done) { - testWriteDir({ buffer: false }, done); - }); + it('should return a output stream that writes streaming files into new directories (buffer: false)', function(done) { + testWriteDir({ buffer: false, cwd: __dirname }, done); + }); - it('should return a output stream that writes streaming files into new directories (read: false)', function(done) { - testWriteDir({ read: false }, done); - }); + it('should return a output stream that writes streaming files into new directories (read: false)', function(done) { + testWriteDir({ read: false, cwd: __dirname }, done); + }); - it('should return a output stream that writes streaming files into new directories (read: false, buffer: false)', function(done) { - testWriteDir({ buffer: false, read: false }, done); - }); + it('should return a output stream that writes streaming files into new directories (read: false, buffer: false)', function(done) { + testWriteDir({ buffer: false, read: false, cwd: __dirname }, done); + }); - function testWriteDir(srcOptions, done) { - var instream = gulp.src(join(__dirname, './fixtures/stuff'), srcOptions); - var outstream = instream.pipe(gulp.dest(outpath)); + function testWriteDir(srcOptions, done) { + var instream = gulp.src('./fixtures/stuff', srcOptions); + var outstream = instream.pipe(gulp.dest(outpath)); - outstream.on('error', done); - outstream.on('data', function(file) { - // Data should be re-emitted right - should.exist(file); - should.exist(file.path); - join(file.path, '').should.equal(join(outpath, './stuff')); - }); - outstream.on('end', function() { - fs.exists(join(outpath, 'stuff'), function(exists) { - /* Stinks that ok is an expression instead of a function call */ - /* jshint expr: true */ - should(exists).be.ok; - /* jshint expr: false */ - done(); - }); + outstream.on('error', done); + outstream.on('data', function(file) { + // Data should be re-emitted right + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.path).toEqual(path.join(outpath, './stuff')); + }); + outstream.on('end', function() { + fs.exists(path.join(outpath, 'stuff'), function(exists) { + expect(exists).toExist(); + done(); }); - } + }); + } - }); }); diff --git a/test/src.js b/test/src.js index a85f237d..4ec1df96 100644 --- a/test/src.js +++ b/test/src.js @@ -1,152 +1,150 @@ 'use strict'; -var gulp = require('../'); -var should = require('should'); -var join = require('path').join; +var path = require('path'); -require('mocha'); +var expect = require('expect'); -describe('gulp input stream', function() { - describe('src()', function() { - it('should return a stream', function(done) { - var stream = gulp.src(join(__dirname, './fixtures/*.coffee')); - should.exist(stream); - should.exist(stream.on); - done(); +var gulp = require('../'); + +describe('gulp.src()', function() { + it('should return a stream', function(done) { + var stream = gulp.src('./fixtures/*.coffee', { cwd: __dirname }); + expect(stream).toExist(); + expect(stream.on).toExist(); + done(); + }); + it('should return a input stream from a flat glob', function(done) { + var stream = gulp.src('./fixtures/*.coffee', { cwd: __dirname }); + stream.on('error', done); + stream.on('data', function(file) { + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.contents).toExist(); + expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); + expect(file.contents).toEqual('this is a test'); }); - it('should return a input stream from a flat glob', function(done) { - var stream = gulp.src(join(__dirname, './fixtures/*.coffee')); - stream.on('error', done); - stream.on('data', function(file) { - should.exist(file); - should.exist(file.path); - should.exist(file.contents); - join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee')); - String(file.contents).should.equal('this is a test'); - }); - stream.on('end', function() { - done(); - }); + stream.on('end', function() { + done(); }); + }); - it('should return a input stream for multiple globs', function(done) { - var globArray = [ - join(__dirname, './fixtures/stuff/run.dmc'), - join(__dirname, './fixtures/stuff/test.dmc'), - ]; - var stream = gulp.src(globArray); + it('should return a input stream for multiple globs', function(done) { + var globArray = [ + './fixtures/stuff/run.dmc', + './fixtures/stuff/test.dmc', + ]; + var stream = gulp.src(globArray, { cwd: __dirname }); - var files = []; - stream.on('error', done); - stream.on('data', function(file) { - should.exist(file); - should.exist(file.path); - files.push(file); - }); - stream.on('end', function() { - files.length.should.equal(2); - files[0].path.should.equal(globArray[0]); - files[1].path.should.equal(globArray[1]); - done(); - }); + var files = []; + stream.on('error', done); + stream.on('data', function(file) { + expect(file).toExist(); + expect(file.path).toExist(); + files.push(file); + }); + stream.on('end', function() { + expect(files.length).toEqual(2); + expect(files[0].path).toEqual(path.join(__dirname, globArray[0])); + expect(files[1].path).toEqual(path.join(__dirname, globArray[1])); + done(); }); + }); - it('should return a input stream for multiple globs, with negation', function(done) { - var expectedPath = join(__dirname, './fixtures/stuff/run.dmc'); - var globArray = [ - join(__dirname, './fixtures/stuff/*.dmc'), - '!' + join(__dirname, './fixtures/stuff/test.dmc'), - ]; - var stream = gulp.src(globArray); + it('should return a input stream for multiple globs, with negation', function(done) { + var expectedPath = path.join(__dirname, './fixtures/stuff/run.dmc'); + var globArray = [ + './fixtures/stuff/*.dmc', + '!fixtures/stuff/test.dmc', + ]; + var stream = gulp.src(globArray, { cwd: __dirname }); - var files = []; - stream.on('error', done); - stream.on('data', function(file) { - should.exist(file); - should.exist(file.path); - files.push(file); - }); - stream.on('end', function() { - files.length.should.equal(1); - files[0].path.should.equal(expectedPath); - done(); - }); + var files = []; + stream.on('error', done); + stream.on('data', function(file) { + expect(file).toExist(); + expect(file.path).toExist(); + files.push(file); }); + stream.on('end', function() { + expect(files.length).toEqual(1); + expect(files[0].path).toEqual(expectedPath); + done(); + }); + }); - it('should return a input stream with no contents when read is false', function(done) { - var stream = gulp.src(join(__dirname, './fixtures/*.coffee'), { read: false }); - stream.on('error', done); - stream.on('data', function(file) { - should.exist(file); - should.exist(file.path); - should.not.exist(file.contents); - join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee')); - }); - stream.on('end', function() { - done(); - }); + it('should return a input stream with no contents when read is false', function(done) { + var stream = gulp.src('./fixtures/*.coffee', { read: false, cwd: __dirname }); + stream.on('error', done); + stream.on('data', function(file) { + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.contents).toNotExist(); + expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); }); - it('should return a input stream with contents as stream when buffer is false', function(done) { - var stream = gulp.src(join(__dirname, './fixtures/*.coffee'), { buffer: false }); - stream.on('error', done); - stream.on('data', function(file) { - should.exist(file); - should.exist(file.path); - should.exist(file.contents); - var buf = ''; - file.contents.on('data', function(d) { - buf += d; - }); - file.contents.on('end', function() { - buf.should.equal('this is a test'); - done(); - }); - join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee')); - }); + stream.on('end', function() { + done(); }); - it('should return a input stream from a deep glob', function(done) { - var stream = gulp.src(join(__dirname, './fixtures/**/*.jade')); - stream.on('error', done); - stream.on('data', function(file) { - should.exist(file); - should.exist(file.path); - should.exist(file.contents); - join(file.path, '').should.equal(join(__dirname, './fixtures/test/run.jade')); - String(file.contents).should.equal('test template'); + }); + it('should return a input stream with contents as stream when buffer is false', function(done) { + var stream = gulp.src('./fixtures/*.coffee', { buffer: false, cwd: __dirname }); + stream.on('error', done); + stream.on('data', function(file) { + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.contents).toExist(); + var buf = ''; + file.contents.on('data', function(d) { + buf += d; }); - stream.on('end', function() { + file.contents.on('end', function() { + expect(buf).toEqual('this is a test'); done(); }); + expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); }); - it('should return a input stream from a deeper glob', function(done) { - var stream = gulp.src(join(__dirname, './fixtures/**/*.dmc')); - var a = 0; - stream.on('error', done); - stream.on('data', function() { - ++a; - }); - stream.on('end', function() { - a.should.equal(2); - done(); - }); + }); + it('should return a input stream from a deep glob', function(done) { + var stream = gulp.src('./fixtures/**/*.jade', { cwd: __dirname }); + stream.on('error', done); + stream.on('data', function(file) { + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.contents).toExist(); + expect(file.path).toEqual(path.join(__dirname, './fixtures/test/run.jade')); + expect(file.contents).toEqual('test template'); + }); + stream.on('end', function() { + done(); + }); + }); + it('should return a input stream from a deeper glob', function(done) { + var stream = gulp.src('./fixtures/**/*.dmc', { cwd: __dirname }); + var a = 0; + stream.on('error', done); + stream.on('data', function() { + ++a; }); + stream.on('end', function() { + expect(a).toEqual(2); + done(); + }); + }); - it('should return a file stream from a flat path', function(done) { - var a = 0; - var stream = gulp.src(join(__dirname, './fixtures/test.coffee')); - stream.on('error', done); - stream.on('data', function(file) { - ++a; - should.exist(file); - should.exist(file.path); - should.exist(file.contents); - join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee')); - String(file.contents).should.equal('this is a test'); - }); - stream.on('end', function() { - a.should.equal(1); - done(); - }); + it('should return a file stream from a flat path', function(done) { + var a = 0; + var stream = gulp.src(path.join(__dirname, './fixtures/test.coffee')); + stream.on('error', done); + stream.on('data', function(file) { + ++a; + expect(file).toExist(); + expect(file.path).toExist(); + expect(file.contents).toExist(); + expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); + expect(file.contents).toEqual('this is a test'); + }); + stream.on('end', function() { + expect(a).toEqual(1); + done(); }); }); }); diff --git a/test/watch.js b/test/watch.js index d943944e..0ac076d2 100644 --- a/test/watch.js +++ b/test/watch.js @@ -1,14 +1,15 @@ 'use strict'; +/* eslint-disable no-use-before-define */ + var fs = require('fs'); +var path = require('path'); -var gulp = require('../'); +var expect = require('expect'); var rimraf = require('rimraf'); var mkdirp = require('mkdirp'); -var path = require('path'); -var should = require('should'); -require('mocha'); +var gulp = require('../'); var outpath = path.join(__dirname, './out-fixtures'); @@ -19,187 +20,189 @@ function createTempFile(path) { } function updateTempFile(path) { - var gazeTimeout = 125; setTimeout(function() { fs.appendFileSync(path, ' changed'); - }, gazeTimeout); + }, 125); } -describe('gulp', function() { - describe('watch()', function() { - beforeEach(rimraf.bind(null, outpath)); - beforeEach(mkdirp.bind(null, outpath)); - afterEach(rimraf.bind(null, outpath)); - - it('should call the function when file changes: no options', function(done) { - var tempFile = path.join(outpath, 'watch-func.txt'); +describe('gulp.watch()', function() { + beforeEach(rimraf.bind(null, outpath)); + beforeEach(mkdirp.bind(null, outpath)); + afterEach(rimraf.bind(null, outpath)); - createTempFile(tempFile); + it('should call the function when file changes: no options', function(done) { + var tempFile = path.join(outpath, 'watch-func.txt'); - var watcher = gulp.watch(tempFile, function(cb) { - watcher.close(); - cb(); - done(); - }); + createTempFile(tempFile); - updateTempFile(tempFile); + var watcher = gulp.watch('watch-func.txt', { cwd: outpath }, function(cb) { + watcher.close(); + cb(); + done(); }); - it('should execute the gulp.parallel tasks', function(done) { - var tempFile = path.join(outpath, 'watch-func.txt'); - - createTempFile(tempFile); + updateTempFile(tempFile); + }); - gulp.task('test', function(cb) { - watcher.close(); - cb(); - done(); - }); + it('should execute the gulp.parallel tasks', function(done) { + var tempFile = path.join(outpath, 'watch-func.txt'); - var watcher = gulp.watch(tempFile, gulp.parallel('test')); + createTempFile(tempFile); - updateTempFile(tempFile); + gulp.task('test', function(cb) { + watcher.close(); + cb(); + done(); }); - it('should work with destructuring', function(done) { - var tempFile = path.join(outpath, 'watch-func.txt'); - var watch = gulp.watch; - var parallel = gulp.parallel; - var task = gulp.task; - createTempFile(tempFile); + var watcher = gulp.watch('watch-func.txt', { cwd: outpath }, gulp.parallel('test')); - task('test', function(cb) { - watcher.close(); - cb(); - done(); - }); - - var watcher = watch(tempFile, parallel('test')); + updateTempFile(tempFile); + }); - updateTempFile(tempFile); + it('should work with destructuring', function(done) { + var tempFile = path.join(outpath, 'watch-func.txt'); + var watch = gulp.watch; + var parallel = gulp.parallel; + var task = gulp.task; + createTempFile(tempFile); + + task('test', function(cb) { + watcher.close(); + cb(); + done(); }); - it('should not call the function when no file changes: no options', function(done) { - var tempFile = path.join(outpath, 'watch-func.txt'); - - createTempFile(tempFile); + var watcher = watch('watch-func.txt', { cwd: outpath }, parallel('test')); - var watcher = gulp.watch(tempFile, function() { - should.fail('Watcher erroneously called'); - }); - - setTimeout(function() { - watcher.close(); - done(); - }, 10); - }); - - it('should call the function when file changes: w/ options', function(done) { - var tempFile = path.join(outpath, 'watch-func-options.txt'); + updateTempFile(tempFile); + }); - createTempFile(tempFile); + it('should not call the function when no file changes: no options', function(done) { + var tempFile = path.join(outpath, 'watch-func.txt'); - var watcher = gulp.watch(tempFile, function(cb) { - watcher.close(); - cb(); - done(); - }); + createTempFile(tempFile); - updateTempFile(tempFile); + var watcher = gulp.watch('watch-func.txt', { cwd: outpath }, function() { + // TODO: proper fail here + expect('Watcher erroneously called'); }); - it('should not drop options when no callback specified', function(done) { - var tempFile = path.join(outpath, 'watch-func-nodrop-options.txt'); - // By passing a cwd option, ensure options are not lost to gaze - var relFile = '../watch-func-nodrop-options.txt'; - var cwd = outpath + '/subdir'; + setTimeout(function() { + watcher.close(); + done(); + }, 10); + }); - createTempFile(tempFile); + it('should call the function when file changes: w/ options', function(done) { + var tempFile = path.join(outpath, 'watch-func-options.txt'); - var watcher = gulp.watch(relFile, {cwd: cwd}) - .on('change', function(filepath) { - should.exist(filepath); - path.resolve(cwd, filepath).should.equal(path.resolve(tempFile)); - watcher.close(); - done(); - }); + createTempFile(tempFile); - updateTempFile(tempFile); + var watcher = gulp.watch('watch-func-options.txt', { cwd: outpath }, function(cb) { + watcher.close(); + cb(); + done(); }); - it('should work without options or callback', function() { - gulp.watch('x'); - }); + updateTempFile(tempFile); + }); - it('should run many tasks: w/ options', function(done) { - var tempFile = path.join(outpath, 'watch-task-options.txt'); - var a = 0; + it('should not drop options when no callback specified', function(done) { + var tempFile = path.join(outpath, 'watch-func-nodrop-options.txt'); + // By passing a cwd option, ensure options are not lost to gaze + var relFile = '../watch-func-nodrop-options.txt'; + var cwd = path.join(outpath, '/subdir'); - createTempFile(tempFile); + createTempFile(tempFile); - gulp.task('task1', function(cb) { - a++; - cb(); - }); - gulp.task('task2', function(cb) { - a += 10; - a.should.equal(11); + var watcher = gulp.watch(relFile, { cwd: cwd }) + .on('change', function(filepath) { + expect(filepath).toExist(); + expect(path.resolve(cwd, filepath)).toEqual(path.resolve(tempFile)); watcher.close(); - cb(); done(); }); - var watcher = gulp.watch(tempFile, gulp.series('task1', 'task2')); + updateTempFile(tempFile); + }); - updateTempFile(tempFile); - }); + it('should work without options or callback', function(done) { + // TODO: check we return watcher? + gulp.watch('x'); + done(); + }); - it('should run many tasks: no options', function(done) { - var tempFile = path.join(outpath, 'watch-many-tasks-no-options.txt'); - var a = 0; + it('should run many tasks: w/ options', function(done) { + var tempFile = path.join(outpath, 'watch-task-options.txt'); + var a = 0; - createTempFile(tempFile); + createTempFile(tempFile); - gulp.task('task1', function(cb) { - a++; - cb(); - }); - gulp.task('task2', function(cb) { - a += 10; - a.should.equal(11); - watcher.close(); - cb(); - done(); - }); + gulp.task('task1', function(cb) { + a++; + cb(); + }); + gulp.task('task2', function(cb) { + a += 10; + expect(a).toEqual(11); + watcher.close(); + cb(); + done(); + }); - var watcher = gulp.watch(tempFile, gulp.series('task1', 'task2')); + var watcher = gulp.watch('watch-task-options.txt', { cwd: outpath }, gulp.series('task1', 'task2')); - updateTempFile(tempFile); - }); + updateTempFile(tempFile); + }); - it('should throw an error: passed parameter (string) is not a function', function(done) { - var tempFile = path.join(outpath, 'empty.txt'); + it('should run many tasks: no options', function(done) { + var tempFile = path.join(outpath, 'watch-many-tasks-no-options.txt'); + var a = 0; - createTempFile(tempFile); - try { - gulp.watch(tempFile, 'task1'); - } catch (err) { - err.message.should.equal('watching ' + tempFile + ': watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)'); - done(); - } + createTempFile(tempFile); + + gulp.task('task1', function(cb) { + a++; + cb(); + }); + gulp.task('task2', function(cb) { + a += 10; + expect(a).toEqual(11); + watcher.close(); + cb(); + done(); }); - it('should throw an error: passed parameter (array) is not a function', function(done) { - var tempFile = path.join(outpath, 'empty.txt'); + var watcher = gulp.watch('./test/out-fixtures/watch-many-tasks-no-options.txt', gulp.series('task1', 'task2')); - createTempFile(tempFile); - try { - gulp.watch(tempFile, ['task1']); - } catch (err) { - err.message.should.equal('watching ' + tempFile + ': watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)'); - done(); - } - }); + updateTempFile(tempFile); + }); + it('should throw an error: passed parameter (string) is not a function', function(done) { + var filename = 'empty.txt'; + var tempFile = path.join(outpath, filename); + + createTempFile(tempFile); + try { + gulp.watch(filename, { cwd: outpath }, 'task1'); + } catch (err) { + expect(err.message).toEqual('watching ' + filename + ': watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)'); + done(); + } }); + + it('should throw an error: passed parameter (array) is not a function', function(done) { + var filename = 'empty.txt'; + var tempFile = path.join(outpath, filename); + + createTempFile(tempFile); + try { + gulp.watch(filename, { cwd: outpath }, ['task1']); + } catch (err) { + expect(err.message).toEqual('watching ' + filename + ': watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)'); + done(); + } + }); + }); From fbc162fe92b6c73c5332b069f2347a0fe8b5d5f3 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 16:50:31 -0700 Subject: [PATCH 077/225] Docs: Remove references to gulp-util --- docs/recipes/automate-release-workflow.md | 4 ++-- docs/recipes/browserify-multiple-destination.md | 4 ++-- docs/recipes/browserify-transforms.md | 4 ++-- docs/recipes/browserify-uglify-sourcemap.md | 4 ++-- docs/recipes/browserify-with-globs.md | 4 ++-- docs/recipes/fast-browserify-builds-with-watchify.md | 6 +++--- docs/recipes/mocha-test-runner-with-gulp.md | 6 +++--- docs/writing-a-plugin/README.md | 11 +++++------ docs/writing-a-plugin/dealing-with-streams.md | 3 +-- docs/writing-a-plugin/guidelines.md | 5 ++--- docs/writing-a-plugin/using-buffers.md | 3 +-- 11 files changed, 25 insertions(+), 29 deletions(-) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-release-workflow.md index 650691c9..6b2f90d0 100644 --- a/docs/recipes/automate-release-workflow.md +++ b/docs/recipes/automate-release-workflow.md @@ -10,7 +10,7 @@ var runSequence = require('run-sequence'); var conventionalChangelog = require('gulp-conventional-changelog'); var conventionalGithubReleaser = require('conventional-github-releaser'); var bump = require('gulp-bump'); -var gutil = require('gulp-util'); +var log = require('gulplog'); var git = require('gulp-git'); var fs = require('fs'); @@ -38,7 +38,7 @@ gulp.task('bump-version', function () { // use minimist (https://www.npmjs.com/package/minimist) to determine with a // command argument whether you are doing a 'major', 'minor' or a 'patch' change. return gulp.src(['./bower.json', './package.json']) - .pipe(bump({type: "patch"}).on('error', gutil.log)) + .pipe(bump({type: "patch"}).on('error', log.error)) .pipe(gulp.dest('./')); }); diff --git a/docs/recipes/browserify-multiple-destination.md b/docs/recipes/browserify-multiple-destination.md index 6a9af199..474f5828 100644 --- a/docs/recipes/browserify-multiple-destination.md +++ b/docs/recipes/browserify-multiple-destination.md @@ -8,7 +8,7 @@ The below `js` task bundles all the `.js` files under `src/` as entry points and ```js var gulp = require('gulp'); var browserify = require('browserify'); -var gutil = require('gulp-util'); +var log = require('gulplog'); var tap = require('gulp-tap'); var buffer = require('gulp-buffer'); var sourcemaps = require('gulp-sourcemaps'); @@ -21,7 +21,7 @@ gulp.task('js', function () { // transform file objects using gulp-tap plugin .pipe(tap(function (file) { - gutil.log('bundling ' + file.path); + log.info('bundling ' + file.path); // replace file contents with browserify's bundle stream file.contents = browserify(file.path, {debug: true}).bundle(); diff --git a/docs/recipes/browserify-transforms.md b/docs/recipes/browserify-transforms.md index 0137c6ed..47a0d4d5 100644 --- a/docs/recipes/browserify-transforms.md +++ b/docs/recipes/browserify-transforms.md @@ -13,7 +13,7 @@ var browserify = require('browserify'); var gulp = require('gulp'); var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); -var gutil = require('gulp-util'); +var log = require('gulplog'); var uglify = require('gulp-uglify'); var sourcemaps = require('gulp-sourcemaps'); var reactify = require('reactify'); @@ -33,7 +33,7 @@ gulp.task('javascript', function () { .pipe(sourcemaps.init({loadMaps: true})) // Add transformation tasks to the pipeline here. .pipe(uglify()) - .on('error', gutil.log) + .on('error', log.error) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./dist/js/')); }); diff --git a/docs/recipes/browserify-uglify-sourcemap.md b/docs/recipes/browserify-uglify-sourcemap.md index 08287edb..cccfec09 100644 --- a/docs/recipes/browserify-uglify-sourcemap.md +++ b/docs/recipes/browserify-uglify-sourcemap.md @@ -17,7 +17,7 @@ var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var uglify = require('gulp-uglify'); var sourcemaps = require('gulp-sourcemaps'); -var gutil = require('gulp-util'); +var log = require('gulplog'); gulp.task('javascript', function () { // set up the browserify instance on a task basis @@ -32,7 +32,7 @@ gulp.task('javascript', function () { .pipe(sourcemaps.init({loadMaps: true})) // Add transformation tasks to the pipeline here. .pipe(uglify()) - .on('error', gutil.log) + .on('error', log.error) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./dist/js/')); }); diff --git a/docs/recipes/browserify-with-globs.md b/docs/recipes/browserify-with-globs.md index ad7df6f8..72695fb6 100644 --- a/docs/recipes/browserify-with-globs.md +++ b/docs/recipes/browserify-with-globs.md @@ -14,7 +14,7 @@ var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var globby = require('globby'); var through = require('through2'); -var gutil = require('gulp-util'); +var log = require('gulplog'); var uglify = require('gulp-uglify'); var sourcemaps = require('gulp-sourcemaps'); var reactify = require('reactify'); @@ -33,7 +33,7 @@ gulp.task('javascript', function () { .pipe(sourcemaps.init({loadMaps: true})) // Add gulp plugins to the pipeline here. .pipe(uglify()) - .on('error', gutil.log) + .on('error', log.error) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./dist/js/')); diff --git a/docs/recipes/fast-browserify-builds-with-watchify.md b/docs/recipes/fast-browserify-builds-with-watchify.md index 32847d7c..b5646958 100644 --- a/docs/recipes/fast-browserify-builds-with-watchify.md +++ b/docs/recipes/fast-browserify-builds-with-watchify.md @@ -14,7 +14,7 @@ var browserify = require('browserify'); var gulp = require('gulp'); var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); -var gutil = require('gulp-util'); +var log = require('gulplog'); var sourcemaps = require('gulp-sourcemaps'); var assign = require('lodash.assign'); @@ -31,12 +31,12 @@ var b = watchify(browserify(opts)); gulp.task('js', bundle); // so you can run `gulp js` to build the file b.on('update', bundle); // on any dep update, runs the bundler -b.on('log', gutil.log); // output build logs to terminal +b.on('log', log.info); // output build logs to terminal function bundle() { return b.bundle() // log errors if they happen - .on('error', gutil.log.bind(gutil, 'Browserify Error')) + .on('error', log.error.bind(log, 'Browserify Error')) .pipe(source('bundle.js')) // optional, remove if you don't need to buffer file contents .pipe(buffer()) diff --git a/docs/recipes/mocha-test-runner-with-gulp.md b/docs/recipes/mocha-test-runner-with-gulp.md index 775e3a72..4a6b2179 100644 --- a/docs/recipes/mocha-test-runner-with-gulp.md +++ b/docs/recipes/mocha-test-runner-with-gulp.md @@ -22,16 +22,16 @@ gulp.task('default', function() { ### Running mocha tests when files change ```js -// npm install gulp gulp-mocha gulp-util +// npm install gulp gulp-mocha gulplog var gulp = require('gulp'); var mocha = require('gulp-mocha'); -var gutil = require('gulp-util'); +var log = require('gulplog'); gulp.task('mocha', function() { return gulp.src(['test/*.js'], { read: false }) .pipe(mocha({ reporter: 'list' })) - .on('error', gutil.log); + .on('error', log.error); }); gulp.task('watch-mocha', function() { diff --git a/docs/writing-a-plugin/README.md b/docs/writing-a-plugin/README.md index b5042a60..bcd70835 100644 --- a/docs/writing-a-plugin/README.md +++ b/docs/writing-a-plugin/README.md @@ -126,7 +126,7 @@ A simple example showing how to detect & handle each form is provided below, for approach follow the links above. ```js -var PluginError = require('gulp-util').PluginError; +var PluginError = require('plugin-error'); // consts var PLUGIN_NAME = 'gulp-example'; @@ -176,11 +176,10 @@ if (someCondition) { ## Useful resources -* [File object](https://github.com/gulpjs/gulp-util/#new-fileobj) -* [PluginError](https://github.com/gulpjs/gulp-util#new-pluginerrorpluginname-message-options) -* [event-stream](https://github.com/dominictarr/event-stream) -* [BufferStream](https://github.com/nfroidure/BufferStream) -* [gulp-util](https://github.com/gulpjs/gulp-util) +* [File object](https://github.com/gulpjs/vinyl) +* [PluginError](https://github.com/gulpjs/plugin-error) +* [through2](https://www.npmjs.com/package/through2) +* [bufferstreams](https://www.npmjs.com/package/bufferstreams) ## Sample plugins diff --git a/docs/writing-a-plugin/dealing-with-streams.md b/docs/writing-a-plugin/dealing-with-streams.md index 57d390b9..fd518bd6 100644 --- a/docs/writing-a-plugin/dealing-with-streams.md +++ b/docs/writing-a-plugin/dealing-with-streams.md @@ -12,8 +12,7 @@ Let's implement a plugin prepending some text to files. This plugin supports all ```js var through = require('through2'); -var gutil = require('gulp-util'); -var PluginError = gutil.PluginError; +var PluginError = require('plugin-error'); // consts const PLUGIN_NAME = 'gulp-prefixer'; diff --git a/docs/writing-a-plugin/guidelines.md b/docs/writing-a-plugin/guidelines.md index 8d97e4e9..b810ad8a 100644 --- a/docs/writing-a-plugin/guidelines.md +++ b/docs/writing-a-plugin/guidelines.md @@ -30,7 +30,7 @@ - If you encounter an error **outside** the stream, such as invalid configuration while creating the stream, you may throw it. 1. Prefix any errors with the name of your plugin - For example: `gulp-replace: Cannot do regexp replace on a stream` - - Use gulp-util's [PluginError](https://github.com/gulpjs/gulp-util#new-pluginerrorpluginname-message-options) class to make this easy + - Use [PluginError](https://github.com/gulpjs/plugin-error) module to make this easy 1. Name your plugin appropriately: it should begin with "gulp-" if it is a gulp plugin - If it is not a gulp plugin, it should not begin with "gulp-" 1. The type of `file.contents` should always be the same going out as it was when it came in @@ -58,8 +58,7 @@ npm is open for everyone, and you are free to make whatever you want but these g ```js // through2 is a thin wrapper around node transform streams var through = require('through2'); -var gutil = require('gulp-util'); -var PluginError = gutil.PluginError; +var PluginError = require('plugin-error'); // Consts const PLUGIN_NAME = 'gulp-prefixer'; diff --git a/docs/writing-a-plugin/using-buffers.md b/docs/writing-a-plugin/using-buffers.md index ae021448..e35e41b5 100644 --- a/docs/writing-a-plugin/using-buffers.md +++ b/docs/writing-a-plugin/using-buffers.md @@ -9,8 +9,7 @@ If your plugin is relying on a buffer based library, you will probably choose to ```js var through = require('through2'); -var gutil = require('gulp-util'); -var PluginError = gutil.PluginError; +var PluginError = require('plugin-error'); // consts const PLUGIN_NAME = 'gulp-prefixer'; From 76eb4d68c72a87cb1450fdbb069882ee6508f235 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 17:14:34 -0700 Subject: [PATCH 078/225] Docs: Add installation instructions & update badges --- README.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3bc84dba..abd03bdf 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

The streaming build system

-[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![OpenCollective Backers][backer-badge]][backer-url] [![OpenCollective Sponsors][sponsor-badge]][sponsor-url] [![Gitter chat][gitter-image]][gitter-url] +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![OpenCollective Backers][backer-badge]][backer-url] [![OpenCollective Sponsors][sponsor-badge]][sponsor-url] [![Gitter chat][gitter-image]][gitter-url] ## What is gulp? @@ -15,12 +15,21 @@ - **Strong Ecosystem** - Use npm modules to do anything you want + over 2000 curated plugins for streaming file transformations - **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use +## Installation + +There are a few ways to install: + +* gulp v4.0.0 - `npm install gulp@next` +* gulp v4.0.0-alpha.3 - `npm install gulpjs/gulp#4.0.0-alpha.3` +* gulp v4.0.0-alpha.2 - `npm install gulpjs/gulp#4.0.0-alpha.2` +* gulp v3.9.1 - `npm install gulp` + ## Documentation For a Getting started guide, API docs, recipes, making a plugin, etc. check out our docs! -- Need something reliable? Check out the [documentation for the current release](/docs/README.md)! -- Want to help us test the latest and greatest? Check out the [documentation for the next release](https://github.com/gulpjs/gulp/tree/4.0)! +- Check out the [documentation for v4.0.0](/docs/README.md)! __Note: these docs might be behind while we get everything updated.__ +- Using the older v3.9.1? Check out the [documentation at the v3.9.1 tag](https://github.com/gulpjs/gulp/tree/v3.9.1/docs)! ## Sample `gulpfile.js` @@ -259,16 +268,6 @@ function scripts() { } ``` -## Want to test the latest and greatest? - -We're hard at work on our latest release, but we need your help testing it! - -```sh -npm install gulpjs/gulp#4.0 -``` - -There's a slew of major (wonderful) changes in 4.0, so make sure you check out the [docs on that branch](https://github.com/gulpjs/gulp/tree/4.0)! - ## Want to contribute? Anyone can help make this project better - check out our [Contributing guide](/CONTRIBUTING.md)! @@ -290,7 +289,10 @@ Become a sponsor to get your logo on our README on Github. [npm-image]: https://img.shields.io/npm/v/gulp.svg [travis-url]: https://travis-ci.org/gulpjs/gulp -[travis-image]: https://img.shields.io/travis/gulpjs/gulp/master.svg +[travis-image]: https://img.shields.io/travis/gulpjs/gulp.svg?label=travis-ci + +[appveyor-url]: https://ci.appveyor.com/project/gulpjs/gulp +[appveyor-image]: https://img.shields.io/appveyor/ci/gulpjs/gulp.svg?label=appveyor [coveralls-url]: https://coveralls.io/r/gulpjs/gulp [coveralls-image]: https://img.shields.io/coveralls/gulpjs/gulp/master.svg From 2eba29ed5d4d72209548c5b16798ff4c2d2c50a9 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 17:17:53 -0700 Subject: [PATCH 079/225] Docs: Remove run-sequence from recipes --- docs/recipes/automate-release-workflow.md | 36 ++++++++--------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-release-workflow.md index 6b2f90d0..0f18006a 100644 --- a/docs/recipes/automate-release-workflow.md +++ b/docs/recipes/automate-release-workflow.md @@ -6,7 +6,6 @@ Below you have a simple recipe that bumps the project version, commits the chang ``` javascript var gulp = require('gulp'); -var runSequence = require('run-sequence'); var conventionalChangelog = require('gulp-conventional-changelog'); var conventionalGithubReleaser = require('conventional-github-releaser'); var bump = require('gulp-bump'); @@ -48,17 +47,17 @@ gulp.task('commit-changes', function () { .pipe(git.commit('[Prerelease] Bumped version number')); }); -gulp.task('push-changes', function (cb) { - git.push('origin', 'master', cb); +gulp.task('push-changes', function (done) { + git.push('origin', 'master', done); }); -gulp.task('create-new-tag', function (cb) { +gulp.task('create-new-tag', function (done) { var version = getPackageJsonVersion(); git.tag(version, 'Created Tag for version: ' + version, function (error) { if (error) { - return cb(error); + return done(error); } - git.push('origin', 'master', {args: '--tags'}, cb); + git.push('origin', 'master', {args: '--tags'}, done); }); function getPackageJsonVersion () { @@ -68,22 +67,13 @@ gulp.task('create-new-tag', function (cb) { }; }); -gulp.task('release', function (callback) { - runSequence( - 'bump-version', - 'changelog', - 'commit-changes', - 'push-changes', - 'create-new-tag', - 'github-release', - function (error) { - if (error) { - console.log(error.message); - } else { - console.log('RELEASE FINISHED SUCCESSFULLY'); - } - callback(error); - }); -}); +gulp.task('release', gulp.series( + 'bump-version', + 'changelog', + 'commit-changes', + 'push-changes', + 'create-new-tag', + 'github-release' +)); ``` From 03b7c9860bea45649dbfd0c3d83e82a9ea58b4b2 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 17:22:01 -0700 Subject: [PATCH 080/225] Docs: Update recipes to install gulp@next --- docs/getting-started.md | 2 +- docs/recipes/delete-files-folder.md | 4 ++-- docs/recipes/mocha-test-runner-with-gulp.md | 4 ++-- docs/recipes/only-pass-through-changed-files.md | 2 +- docs/recipes/pass-arguments-from-cli.md | 2 +- docs/recipes/rollup-with-rollup-stream.md | 4 ++-- docs/recipes/run-grunt-tasks-from-gulp.md | 2 +- docs/recipes/server-with-livereload-and-css-injection.md | 4 ++-- docs/recipes/split-tasks-across-multiple-files.md | 2 +- docs/recipes/using-external-config-file.md | 2 +- docs/recipes/using-multiple-sources-in-one-task.md | 4 ++-- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 724b942b..d5240cd1 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -27,7 +27,7 @@ If you don't have a package.json, create one. If you need help, run an `npm init Run this command in your project directory: ```sh -npm install --save-dev gulp +npm install --save-dev gulp@next ``` #### Create a `gulpfile` diff --git a/docs/recipes/delete-files-folder.md b/docs/recipes/delete-files-folder.md index 1373ce6a..5f7cc1af 100644 --- a/docs/recipes/delete-files-folder.md +++ b/docs/recipes/delete-files-folder.md @@ -6,7 +6,7 @@ You might want to delete some files before running your build. Since deleting fi Let's use the [`del`](https://github.com/sindresorhus/del) module for this example as it supports multiple files and [globbing](https://github.com/sindresorhus/multimatch#globbing-patterns): ```sh -$ npm install --save-dev gulp del +$ npm install --save-dev gulp@next del ``` Imagine the following file structure: @@ -50,7 +50,7 @@ You might want to delete some files after processing them in a pipeline. We'll use [vinyl-paths](https://github.com/sindresorhus/vinyl-paths) to easily get the file path of files in the stream and pass it to the `del` method. ```sh -$ npm install --save-dev gulp del vinyl-paths +$ npm install --save-dev gulp@next del vinyl-paths ``` Imagine the following file structure: diff --git a/docs/recipes/mocha-test-runner-with-gulp.md b/docs/recipes/mocha-test-runner-with-gulp.md index 4a6b2179..c6ca3873 100644 --- a/docs/recipes/mocha-test-runner-with-gulp.md +++ b/docs/recipes/mocha-test-runner-with-gulp.md @@ -3,7 +3,7 @@ ### Passing shared module in all tests ```js -// npm install gulp gulp-mocha +// npm install gulp@next gulp-mocha var gulp = require('gulp'); var mocha = require('gulp-mocha'); @@ -22,7 +22,7 @@ gulp.task('default', function() { ### Running mocha tests when files change ```js -// npm install gulp gulp-mocha gulplog +// npm install gulp@next gulp-mocha gulplog var gulp = require('gulp'); var mocha = require('gulp-mocha'); diff --git a/docs/recipes/only-pass-through-changed-files.md b/docs/recipes/only-pass-through-changed-files.md index f2db5972..1b0a3449 100644 --- a/docs/recipes/only-pass-through-changed-files.md +++ b/docs/recipes/only-pass-through-changed-files.md @@ -4,7 +4,7 @@ Files are passed through the whole pipe chain on every run by default. By using ```js -// npm install --save-dev gulp gulp-changed gulp-jscs gulp-uglify +// npm install --save-dev gulp@next gulp-changed gulp-jscs gulp-uglify var gulp = require('gulp'); var changed = require('gulp-changed'); diff --git a/docs/recipes/pass-arguments-from-cli.md b/docs/recipes/pass-arguments-from-cli.md index 48185b6b..1f9c74b1 100644 --- a/docs/recipes/pass-arguments-from-cli.md +++ b/docs/recipes/pass-arguments-from-cli.md @@ -1,7 +1,7 @@ # Pass arguments from the command line ```js -// npm install --save-dev gulp gulp-if gulp-uglify minimist +// npm install --save-dev gulp@next gulp-if gulp-uglify minimist var gulp = require('gulp'); var gulpif = require('gulp-if'); diff --git a/docs/recipes/rollup-with-rollup-stream.md b/docs/recipes/rollup-with-rollup-stream.md index 5311fd51..24679d55 100644 --- a/docs/recipes/rollup-with-rollup-stream.md +++ b/docs/recipes/rollup-with-rollup-stream.md @@ -4,7 +4,7 @@ Like Browserify, [Rollup](https://rollupjs.org/) is a bundler and thus only fits ## Basic usage ```js -// npm install --save-dev rollup-stream vinyl-source-stream +// npm install --save-dev gulp@next rollup-stream vinyl-source-stream var gulp = require('gulp'); var rollup = require('rollup-stream'); var source = require('vinyl-source-stream'); @@ -24,7 +24,7 @@ gulp.task('rollup', function() { ## Usage with sourcemaps ```js -// npm install --save-dev rollup-stream gulp-sourcemaps vinyl-source-stream vinyl-buffer +// npm install --save-dev gulp@next rollup-stream gulp-sourcemaps vinyl-source-stream vinyl-buffer // optional: npm install --save-dev gulp-rename var gulp = require('gulp'); var rollup = require('rollup-stream'); diff --git a/docs/recipes/run-grunt-tasks-from-gulp.md b/docs/recipes/run-grunt-tasks-from-gulp.md index cdd4f686..ddf137d6 100644 --- a/docs/recipes/run-grunt-tasks-from-gulp.md +++ b/docs/recipes/run-grunt-tasks-from-gulp.md @@ -7,7 +7,7 @@ It is possible to run Grunt tasks / Grunt plugins from within Gulp. This can be very simple example `gulpfile.js`: ```js -// npm install gulp grunt grunt-contrib-copy --save-dev +// npm install gulp@next grunt grunt-contrib-copy --save-dev var gulp = require('gulp'); var grunt = require('grunt'); diff --git a/docs/recipes/server-with-livereload-and-css-injection.md b/docs/recipes/server-with-livereload-and-css-injection.md index f5e1222f..a23cc239 100644 --- a/docs/recipes/server-with-livereload-and-css-injection.md +++ b/docs/recipes/server-with-livereload-and-css-injection.md @@ -2,10 +2,10 @@ With [BrowserSync](https://browsersync.io) and gulp, you can easily create a development server that is accessible to any device on the same WiFi network. BrowserSync also has live-reload built in, so there's nothing else to configure. -First install the module: +First install the modules: ```sh -$ npm install --save-dev browser-sync +$ npm install --save-dev gulp@next browser-sync ``` Then, considering the following file structure... diff --git a/docs/recipes/split-tasks-across-multiple-files.md b/docs/recipes/split-tasks-across-multiple-files.md index 4f69bbde..afee1be1 100644 --- a/docs/recipes/split-tasks-across-multiple-files.md +++ b/docs/recipes/split-tasks-across-multiple-files.md @@ -17,7 +17,7 @@ tasks/ Install the `gulp-hub` module: ```sh -npm install --save-dev gulp-hub +npm install --save-dev gulp@next gulp-hub ``` Add the following lines to your `gulpfile.js` file: diff --git a/docs/recipes/using-external-config-file.md b/docs/recipes/using-external-config-file.md index 6c740761..b073f1df 100644 --- a/docs/recipes/using-external-config-file.md +++ b/docs/recipes/using-external-config-file.md @@ -30,7 +30,7 @@ Beneficial because it's keeping tasks DRY and config.json can be used by another ###### `gulpfile.js` ```js -// npm install --save-dev gulp gulp-uglify merge-stream +// npm install --save-dev gulp@next gulp-uglify merge-stream var gulp = require('gulp'); var uglify = require('gulp-uglify'); var merge = require('merge-stream'); diff --git a/docs/recipes/using-multiple-sources-in-one-task.md b/docs/recipes/using-multiple-sources-in-one-task.md index 42279378..39e3e3b2 100644 --- a/docs/recipes/using-multiple-sources-in-one-task.md +++ b/docs/recipes/using-multiple-sources-in-one-task.md @@ -1,7 +1,7 @@ # Using multiple sources in one task ```js -// npm install --save-dev gulp merge-stream +// npm install --save-dev gulp@next merge-stream var gulp = require('gulp'); var merge = require('merge-stream'); @@ -20,7 +20,7 @@ gulp.task('test', function() { `gulp.src` will emit files in the order they were added: ```js -// npm install gulp gulp-concat +// npm install gulp@next gulp-concat var gulp = require('gulp'); var concat = require('gulp-concat'); From ec54d09570a891d39a2ccd6f5b13d9a5dd57c68f Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 17:23:34 -0700 Subject: [PATCH 081/225] Docs: Improve note about out-of-date docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index abd03bdf..00e1d1c0 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ There are a few ways to install: For a Getting started guide, API docs, recipes, making a plugin, etc. check out our docs! -- Check out the [documentation for v4.0.0](/docs/README.md)! __Note: these docs might be behind while we get everything updated.__ +- Check out the [documentation for v4.0.0](/docs/README.md)! __Excuse our dust; these docs might be behind while we get everything updated. Please open an issue if something isn't working.__ - Using the older v3.9.1? Check out the [documentation at the v3.9.1 tag](https://github.com/gulpjs/gulp/tree/v3.9.1/docs)! ## Sample `gulpfile.js` From 173a532d0b79912ccf0050e6c5b4ffddd0d0fd1d Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 18:24:54 -0700 Subject: [PATCH 082/225] Docs: Fix the installation instructions --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 00e1d1c0..3fd3f6fe 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,7 @@ There are a few ways to install: * gulp v4.0.0 - `npm install gulp@next` -* gulp v4.0.0-alpha.3 - `npm install gulpjs/gulp#4.0.0-alpha.3` -* gulp v4.0.0-alpha.2 - `npm install gulpjs/gulp#4.0.0-alpha.2` +* gulp v4.0.0-alpha.3 - `npm install gulpjs/gulp#v4.0.0-alpha.3` * gulp v3.9.1 - `npm install gulp` ## Documentation From 55eb23a268dcc7340bb40808600fd4802848c06f Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 31 Dec 2017 18:25:46 -0700 Subject: [PATCH 083/225] Release: 4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 31dab214..b50db540 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gulp", - "version": "4.0.0-alpha.3", + "version": "4.0.0", "description": "The streaming build system.", "homepage": "http://gulpjs.com", "author": "Gulp Team (http://gulpjs.com/)", From a010db615fae4fbf8ecfdaff5530a4d84107d984 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 1 Jan 2018 20:12:47 -0700 Subject: [PATCH 084/225] Scaffold: Mark *.png and *.jpg as binary files to git --- .gitattributes | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitattributes b/.gitattributes index fcadb2cf..1de36465 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,5 @@ * text eol=lf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary From a4e8d4853c1a846654eeb809e6fc6aac30df6c11 Mon Sep 17 00:00:00 2001 From: Charles Samborski Date: Thu, 18 Jan 2018 18:16:31 +0100 Subject: [PATCH 085/225] Docs: Fix error in ES2015 usage example (fixes #2099) (#2100) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3fd3f6fe..1d6e35c7 100644 --- a/README.md +++ b/README.md @@ -197,8 +197,8 @@ export { watchFiles as watch }; * You can still use `gulp.task` * for example to set task names that would otherwise be invalid */ -const clean = gulp.series(clean, gulp.parallel(styles, scripts)); -gulp.task('clean', clean); +const build = gulp.series(clean, gulp.parallel(styles, scripts)); +gulp.task('build', build); /* * Export a default task From 126423ac824f0a3bc3ac6a718077b5f40d0d0792 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Wed, 7 Feb 2018 11:17:53 -0800 Subject: [PATCH 086/225] Docs: Add temporary notice for 4.0.0 vs 3.9.1 documentation (#2121) --- docs/API.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/API.md b/docs/API.md index 1415c6af..338bff40 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,3 +1,7 @@ +Note: these docs are for version v4.0.0 (aka `gulp@next`) If you're on gulp +v3.9.1, which is the current standard `npm` release, you probably want [that +version's documentation](https://github.com/gulpjs/gulp/blob/v3.9.1/docs/API.md). + ## gulp API docs * [gulp.src](#gulpsrcglobs-options) - Emit files matching one or more globs From 45830cf9bab1c5bf2d39602aea12f30f189d3a65 Mon Sep 17 00:00:00 2001 From: contra Date: Fri, 9 Feb 2018 16:31:55 -0500 Subject: [PATCH 087/225] Docs: Improve recipe for empty glob array (closes #2122) --- docs/recipes/running-task-steps-per-folder.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/recipes/running-task-steps-per-folder.md b/docs/recipes/running-task-steps-per-folder.md index 905f697b..3abd0e17 100644 --- a/docs/recipes/running-task-steps-per-folder.md +++ b/docs/recipes/running-task-steps-per-folder.md @@ -36,9 +36,9 @@ function getFolders(dir) { }); } -gulp.task('scripts', function() { +gulp.task('scripts', function(done) { var folders = getFolders(scriptsPath); - + if (folder.length === 0) return done(); // nothing to do! var tasks = folders.map(function(folder) { return gulp.src(path.join(scriptsPath, folder, '/**/*.js')) // concat into foldername.js From b065a132a68ee8d68e94a5c650169e45468a3a78 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 14 Feb 2018 12:53:55 -0700 Subject: [PATCH 088/225] Docs: Reword standard to default --- docs/API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/API.md b/docs/API.md index 338bff40..017164bf 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,5 +1,5 @@ Note: these docs are for version v4.0.0 (aka `gulp@next`) If you're on gulp -v3.9.1, which is the current standard `npm` release, you probably want [that +v3.9.1, which is the current default `npm` release, you probably want [that version's documentation](https://github.com/gulpjs/gulp/blob/v3.9.1/docs/API.md). ## gulp API docs From 86acdea1d4b01deb9edcb2400b92b6ebc07fc4a7 Mon Sep 17 00:00:00 2001 From: Christopher Andersson Date: Sun, 13 May 2018 18:46:09 -0400 Subject: [PATCH 089/225] Docs: Fix recipe typo (#2156) --- docs/recipes/running-task-steps-per-folder.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/running-task-steps-per-folder.md b/docs/recipes/running-task-steps-per-folder.md index 3abd0e17..df5c5369 100644 --- a/docs/recipes/running-task-steps-per-folder.md +++ b/docs/recipes/running-task-steps-per-folder.md @@ -38,7 +38,7 @@ function getFolders(dir) { gulp.task('scripts', function(done) { var folders = getFolders(scriptsPath); - if (folder.length === 0) return done(); // nothing to do! + if (folders.length === 0) return done(); // nothing to do! var tasks = folders.map(function(folder) { return gulp.src(path.join(scriptsPath, folder, '/**/*.js')) // concat into foldername.js From d693e499ac7c40b6c52891aa111947cad95aa2ab Mon Sep 17 00:00:00 2001 From: Cole Gentry Date: Mon, 29 Jan 2018 16:01:01 -0500 Subject: [PATCH 090/225] Docs: Add front-matter to each file (#2109) --- docs/API.md | 7 ++++++ docs/CLI.md | 9 +++++++- docs/FAQ.md | 7 ++++++ docs/README.md | 7 ++++++ docs/getting-started.md | 7 ++++++ docs/recipes/README.md | 7 ++++++ docs/recipes/automate-release-workflow.md | 7 ++++++ .../browserify-multiple-destination.md | 7 ++++++ docs/recipes/browserify-transforms.md | 7 ++++++ docs/recipes/browserify-uglify-sourcemap.md | 9 +++++++- docs/recipes/browserify-with-globs.md | 7 ++++++ .../combining-streams-to-handle-errors.md | 7 ++++++ docs/recipes/cron-task.md | 9 +++++++- docs/recipes/delete-files-folder.md | 6 +++++ docs/recipes/exports-as-tasks.md | 7 ++++++ .../fast-browserify-builds-with-watchify.md | 9 +++++++- .../handling-the-delete-event-on-watch.md | 7 ++++++ .../incremental-builds-with-concatenate.md | 7 ++++++ ...tain-directory-structure-while-globbing.md | 22 ++++++++++++------- docs/recipes/make-stream-from-buffer.md | 15 +++++++++---- docs/recipes/minified-and-non-minified.md | 7 ++++++ .../minimal-browsersync-setup-with-gulp4.md | 7 ++++++ docs/recipes/mocha-test-runner-with-gulp.md | 7 ++++++ .../only-pass-through-changed-files.md | 7 ++++++ docs/recipes/pass-arguments-from-cli.md | 7 ++++++ .../recipes/rebuild-only-files-that-change.md | 7 ++++++ docs/recipes/rollup-with-rollup-stream.md | 7 ++++++ docs/recipes/run-grunt-tasks-from-gulp.md | 9 +++++++- docs/recipes/running-shell-commands.md | 7 ++++++ docs/recipes/running-task-steps-per-folder.md | 11 ++++++++-- docs/recipes/running-tasks-in-series.md | 7 ++++++ ...erver-with-livereload-and-css-injection.md | 7 ++++++ .../sharing-streams-with-stream-factories.md | 7 ++++++ docs/recipes/specifying-a-cwd.md | 7 ++++++ .../split-tasks-across-multiple-files.md | 7 ++++++ ...plating-with-swig-and-yaml-front-matter.md | 7 ++++++ docs/recipes/using-external-config-file.md | 7 ++++++ .../using-multiple-sources-in-one-task.md | 7 ++++++ docs/why-use-pump/README.md | 7 ++++++ docs/writing-a-plugin/README.md | 7 ++++++ docs/writing-a-plugin/dealing-with-streams.md | 8 ++++++- docs/writing-a-plugin/guidelines.md | 7 ++++++ docs/writing-a-plugin/recommended-modules.md | 7 ++++++ docs/writing-a-plugin/testing.md | 7 ++++++ docs/writing-a-plugin/using-buffers.md | 7 ++++++ 45 files changed, 332 insertions(+), 20 deletions(-) diff --git a/docs/API.md b/docs/API.md index 017164bf..5a9771bb 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,3 +1,10 @@ + + Note: these docs are for version v4.0.0 (aka `gulp@next`) If you're on gulp v3.9.1, which is the current default `npm` release, you probably want [that version's documentation](https://github.com/gulpjs/gulp/blob/v3.9.1/docs/API.md). diff --git a/docs/CLI.md b/docs/CLI.md index c4af45f7..daa3f5d0 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -1,3 +1,10 @@ + + ## gulp CLI docs ### Flags @@ -105,7 +112,7 @@ Output: Command: `gulp --tasks-simple` -Output: +Output: ```shell one two diff --git a/docs/FAQ.md b/docs/FAQ.md index f8a649ea..9c89c143 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -1,3 +1,10 @@ + + # FAQ ## Why gulp? Why not ____? diff --git a/docs/README.md b/docs/README.md index 4f8761b4..d1b9f8c2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,10 @@ + + # gulp documentation * [Getting Started](getting-started.md) - Get started with gulp diff --git a/docs/getting-started.md b/docs/getting-started.md index d5240cd1..6cfe981b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,3 +1,10 @@ + + # Getting Started *If you've previously installed gulp globally, run `npm rm --global gulp` before following these instructions.* For more information, read this [Sip](https://medium.com/gulpjs/gulp-sips-command-line-interface-e53411d4467). diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 3e822432..e1ec3721 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -1,3 +1,10 @@ + + # Recipes * [Automate release workflow](automate-release-workflow.md) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-release-workflow.md index 0f18006a..3b929866 100644 --- a/docs/recipes/automate-release-workflow.md +++ b/docs/recipes/automate-release-workflow.md @@ -1,3 +1,10 @@ + + # Automate release workflow If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release. diff --git a/docs/recipes/browserify-multiple-destination.md b/docs/recipes/browserify-multiple-destination.md index 474f5828..fa1b65ce 100644 --- a/docs/recipes/browserify-multiple-destination.md +++ b/docs/recipes/browserify-multiple-destination.md @@ -1,3 +1,10 @@ + + # Browserify + Globs (multiple destination) This example shows how to set up a task of bundling multiple entry points into multiple destinations using browserify. diff --git a/docs/recipes/browserify-transforms.md b/docs/recipes/browserify-transforms.md index 47a0d4d5..8659614f 100644 --- a/docs/recipes/browserify-transforms.md +++ b/docs/recipes/browserify-transforms.md @@ -1,3 +1,10 @@ + + # Browserify + Transforms [Browserify](https://github.com/browserify/browserify) has become an important and indispensable diff --git a/docs/recipes/browserify-uglify-sourcemap.md b/docs/recipes/browserify-uglify-sourcemap.md index cccfec09..99800ed5 100644 --- a/docs/recipes/browserify-uglify-sourcemap.md +++ b/docs/recipes/browserify-uglify-sourcemap.md @@ -1,10 +1,17 @@ + + # Browserify + Uglify2 with sourcemaps [Browserify](https://github.com/browserify/browserify) has become an important and indispensable tool but requires being wrapped before working well with gulp. Below is a simple recipe for using Browserify with full sourcemaps that resolve to the original individual files. -See also: the [Combining Streams to Handle Errors](https://github.com/gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md) recipe for handling errors with browserify or uglify in your stream. +See also: the [Combining Streams to Handle Errors](https://github.com/gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md) recipe for handling errors with browserify or uglify in your stream. A simple `gulpfile.js` file for Browserify + Uglify2 with sourcemaps: diff --git a/docs/recipes/browserify-with-globs.md b/docs/recipes/browserify-with-globs.md index 72695fb6..d9396f1b 100644 --- a/docs/recipes/browserify-with-globs.md +++ b/docs/recipes/browserify-with-globs.md @@ -1,3 +1,10 @@ + + # Browserify + Globs [Browserify + Uglify2](https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-uglify-sourcemap.md) shows how to setup a basic gulp task to bundle a JavaScript file with its dependencies, and minify the bundle with UglifyJS while preserving source maps. diff --git a/docs/recipes/combining-streams-to-handle-errors.md b/docs/recipes/combining-streams-to-handle-errors.md index 7c38654a..16b56166 100644 --- a/docs/recipes/combining-streams-to-handle-errors.md +++ b/docs/recipes/combining-streams-to-handle-errors.md @@ -1,3 +1,10 @@ + + # Combining streams to handle errors By default, emitting an error on a stream will cause it to be thrown unless it already has a listener attached to the `error` event. This gets a bit tricky when you're working with longer pipelines of streams. diff --git a/docs/recipes/cron-task.md b/docs/recipes/cron-task.md index 030fb334..ad90a6f0 100644 --- a/docs/recipes/cron-task.md +++ b/docs/recipes/cron-task.md @@ -1,9 +1,16 @@ + + # Run gulp task via cron job While logged in via a user that has privileges to run `gulp`, run the following: crontab -e - + to edit your current "[crontab](https://en.wikipedia.org/wiki/Cron)" file. Typically, within a cron job, you want to run any binary using absolute paths, diff --git a/docs/recipes/delete-files-folder.md b/docs/recipes/delete-files-folder.md index 5f7cc1af..731ae4f9 100644 --- a/docs/recipes/delete-files-folder.md +++ b/docs/recipes/delete-files-folder.md @@ -1,3 +1,9 @@ + # Delete files and folders diff --git a/docs/recipes/exports-as-tasks.md b/docs/recipes/exports-as-tasks.md index 2eaea490..892c6bbf 100644 --- a/docs/recipes/exports-as-tasks.md +++ b/docs/recipes/exports-as-tasks.md @@ -1,3 +1,10 @@ + + # Exports as Tasks Using the ES2015 module syntax you can use your exports as tasks. diff --git a/docs/recipes/fast-browserify-builds-with-watchify.md b/docs/recipes/fast-browserify-builds-with-watchify.md index b5646958..aa07f1a9 100644 --- a/docs/recipes/fast-browserify-builds-with-watchify.md +++ b/docs/recipes/fast-browserify-builds-with-watchify.md @@ -1,3 +1,10 @@ + + # Fast browserify builds with watchify As a [browserify](https://github.com/browserify/browserify) project begins to expand, the time to bundle it slowly gets longer and longer. While it might start at 1 second, it's possible to be waiting 30 seconds for your project to build on particularly large projects. @@ -24,7 +31,7 @@ var customOpts = { debug: true }; var opts = assign({}, watchify.args, customOpts); -var b = watchify(browserify(opts)); +var b = watchify(browserify(opts)); // add transformations here // i.e. b.transform(coffeeify); diff --git a/docs/recipes/handling-the-delete-event-on-watch.md b/docs/recipes/handling-the-delete-event-on-watch.md index 05bd683a..ba7a77cd 100644 --- a/docs/recipes/handling-the-delete-event-on-watch.md +++ b/docs/recipes/handling-the-delete-event-on-watch.md @@ -1,3 +1,10 @@ + + # Handling the Delete Event on Watch You can listen for `'unlink'` events to fire on the watcher returned from `gulp.watch`. diff --git a/docs/recipes/incremental-builds-with-concatenate.md b/docs/recipes/incremental-builds-with-concatenate.md index c9fdaa0d..797bd0ca 100644 --- a/docs/recipes/incremental-builds-with-concatenate.md +++ b/docs/recipes/incremental-builds-with-concatenate.md @@ -1,3 +1,10 @@ + + # Incremental rebuilding, including operating on full file sets The trouble with incremental rebuilds is you often want to operate on _all_ processed files, not just single files. For example, you may want to lint and module-wrap just the file(s) that have changed, then concatenate it with all other linted and module-wrapped files. This is difficult without the use of temp files. diff --git a/docs/recipes/maintain-directory-structure-while-globbing.md b/docs/recipes/maintain-directory-structure-while-globbing.md index aadd32ef..279eac11 100644 --- a/docs/recipes/maintain-directory-structure-while-globbing.md +++ b/docs/recipes/maintain-directory-structure-while-globbing.md @@ -1,9 +1,16 @@ + + # Maintain Directory Structure while Globbing If you are planning to read a few files/folders from a directory and maintain their relative path, you need to pass `{base: '.'}` as the second argument to `gulp.src()`. -For example, if you have a directory structure like +For example, if you have a directory structure like ![Dev setup](https://cloud.githubusercontent.com/assets/2562992/3178498/bedf75b4-ec1a-11e3-8a71-a150ad94b450.png) @@ -27,18 +34,17 @@ If you want to maintain the structure, you need to pass `{base: '.'}` to `gulp.s ```js gulp.task('task', function () { - return gulp.src(['index.html', - 'css/**', - 'js/**', - 'lib/**', - 'images/**', + return gulp.src(['index.html', + 'css/**', + 'js/**', + 'lib/**', + 'images/**', 'plugin/**' ], {base: '.'}) .pipe(operation1()) .pipe(operation2()); }); ``` -And the input to your `operation1()` will be a folder structure like +And the input to your `operation1()` will be a folder structure like ![with-base](https://cloud.githubusercontent.com/assets/2562992/3178607/053d6722-ec1c-11e3-9ba8-7ce39e1a480e.png) - diff --git a/docs/recipes/make-stream-from-buffer.md b/docs/recipes/make-stream-from-buffer.md index f11c1161..b376eafc 100644 --- a/docs/recipes/make-stream-from-buffer.md +++ b/docs/recipes/make-stream-from-buffer.md @@ -1,3 +1,10 @@ + + # Make stream from buffer (memory contents) Sometimes you may need to start a stream with files that their contents are in a variable and not in a physical file. In other words, how to start a 'gulp' stream without using `gulp.src()`. @@ -78,9 +85,9 @@ gulp.task('write-versions', function() { availableVersions.forEach(function(v) { // make a new stream with fake file name var stream = source('final.' + v); - + var streamEnd = stream; - + // we load the data from the concatenated libs var fileContents = memory['libs.concat.js'] + // we add the version's data @@ -99,11 +106,11 @@ gulp.task('write-versions', function() { .pipe(vinylBuffer()) //.pipe(tap(function(file) { /* do something with the file contents here */ })) .pipe(gulp.dest('output')); - + // add the end of the stream, otherwise the task would finish before all the processing // is done streams.push(streamEnd); - + }); return es.merge.apply(this, streams); diff --git a/docs/recipes/minified-and-non-minified.md b/docs/recipes/minified-and-non-minified.md index e1a6a429..3cc603a9 100644 --- a/docs/recipes/minified-and-non-minified.md +++ b/docs/recipes/minified-and-non-minified.md @@ -1,3 +1,10 @@ + + # Output both a minified and non-minified version Outputting both a minified and non-minified version of your combined JavaScript files can be achieved by using `gulp-rename` and piping to `dest` twice (once before minifying and once after minifying): diff --git a/docs/recipes/minimal-browsersync-setup-with-gulp4.md b/docs/recipes/minimal-browsersync-setup-with-gulp4.md index ec22c071..55a5ac38 100644 --- a/docs/recipes/minimal-browsersync-setup-with-gulp4.md +++ b/docs/recipes/minimal-browsersync-setup-with-gulp4.md @@ -1,3 +1,10 @@ + + # Minimal BrowserSync setup with Gulp 4 [BrowserSync](https://www.browsersync.io/) is a great tool to streamline diff --git a/docs/recipes/mocha-test-runner-with-gulp.md b/docs/recipes/mocha-test-runner-with-gulp.md index c6ca3873..eab0725c 100644 --- a/docs/recipes/mocha-test-runner-with-gulp.md +++ b/docs/recipes/mocha-test-runner-with-gulp.md @@ -1,3 +1,10 @@ + + # Mocha test-runner with gulp ### Passing shared module in all tests diff --git a/docs/recipes/only-pass-through-changed-files.md b/docs/recipes/only-pass-through-changed-files.md index 1b0a3449..64d16dbe 100644 --- a/docs/recipes/only-pass-through-changed-files.md +++ b/docs/recipes/only-pass-through-changed-files.md @@ -1,3 +1,10 @@ + + # Only pass through changed files Files are passed through the whole pipe chain on every run by default. By using [gulp-changed](https://github.com/sindresorhus/gulp-changed) only changed files will be passed through. This can speed up consecutive runs considerably. diff --git a/docs/recipes/pass-arguments-from-cli.md b/docs/recipes/pass-arguments-from-cli.md index 1f9c74b1..40c44bc1 100644 --- a/docs/recipes/pass-arguments-from-cli.md +++ b/docs/recipes/pass-arguments-from-cli.md @@ -1,3 +1,10 @@ + + # Pass arguments from the command line ```js diff --git a/docs/recipes/rebuild-only-files-that-change.md b/docs/recipes/rebuild-only-files-that-change.md index 245ddc4f..d60a8025 100644 --- a/docs/recipes/rebuild-only-files-that-change.md +++ b/docs/recipes/rebuild-only-files-that-change.md @@ -1,3 +1,10 @@ + + # Rebuild only files that change With [`gulp-watch`](https://github.com/floatdrop/gulp-watch): diff --git a/docs/recipes/rollup-with-rollup-stream.md b/docs/recipes/rollup-with-rollup-stream.md index 24679d55..4c77aacc 100644 --- a/docs/recipes/rollup-with-rollup-stream.md +++ b/docs/recipes/rollup-with-rollup-stream.md @@ -1,3 +1,10 @@ + + # Rollup with rollup-stream Like Browserify, [Rollup](https://rollupjs.org/) is a bundler and thus only fits naturally into gulp if it's at the start of the pipeline. Unlike Browserify, Rollup doesn't natively produce a stream as output and needs to be wrapped before it can take this position. [rollup-stream](https://github.com/Permutatrix/rollup-stream) does this for you, producing output just like that of Browserify's `bundle()` method—as a result, most of the Browserify recipes here will also work with rollup-stream. diff --git a/docs/recipes/run-grunt-tasks-from-gulp.md b/docs/recipes/run-grunt-tasks-from-gulp.md index ddf137d6..ee633125 100644 --- a/docs/recipes/run-grunt-tasks-from-gulp.md +++ b/docs/recipes/run-grunt-tasks-from-gulp.md @@ -1,3 +1,10 @@ + + # Run Grunt Tasks from Gulp It is possible to run Grunt tasks / Grunt plugins from within Gulp. This can be useful during a gradual migration from Grunt to Gulp or if there's a specific plugin that you need. With the described approach no Grunt CLI and no Gruntfile is required. @@ -32,7 +39,7 @@ gulp.task('copy', function (done) { ``` -Now start the task with: +Now start the task with: `gulp copy` With the aforementioned approach the grunt tasks get registered within gulp's task system. **Keep in mind grunt tasks are usually blocking (unlike gulp), therefore no other task (not even a gulp task) can run until a grunt task is completed.** diff --git a/docs/recipes/running-shell-commands.md b/docs/recipes/running-shell-commands.md index 5d344747..7bc4eb1f 100644 --- a/docs/recipes/running-shell-commands.md +++ b/docs/recipes/running-shell-commands.md @@ -1,3 +1,10 @@ + + # Running Shell Commands Sometimes it is helpful to be able to call existing command line tools from gulp. diff --git a/docs/recipes/running-task-steps-per-folder.md b/docs/recipes/running-task-steps-per-folder.md index df5c5369..5ee3b649 100644 --- a/docs/recipes/running-task-steps-per-folder.md +++ b/docs/recipes/running-task-steps-per-folder.md @@ -1,3 +1,10 @@ + + # Generating a file per folder If you have a set of folders, and wish to perform a set of tasks on each, for instance... @@ -44,11 +51,11 @@ gulp.task('scripts', function(done) { // concat into foldername.js .pipe(concat(folder + '.js')) // write to output - .pipe(gulp.dest(scriptsPath)) + .pipe(gulp.dest(scriptsPath)) // minify .pipe(uglify()) // rename to folder.min.js - .pipe(rename(folder + '.min.js')) + .pipe(rename(folder + '.min.js')) // write to output again .pipe(gulp.dest(scriptsPath)); }); diff --git a/docs/recipes/running-tasks-in-series.md b/docs/recipes/running-tasks-in-series.md index b28e692a..be60816f 100644 --- a/docs/recipes/running-tasks-in-series.md +++ b/docs/recipes/running-tasks-in-series.md @@ -1,3 +1,10 @@ + + # Running tasks in series By default, gulp CLI run tasks with maximum concurrency - e.g. it launches diff --git a/docs/recipes/server-with-livereload-and-css-injection.md b/docs/recipes/server-with-livereload-and-css-injection.md index a23cc239..51b65226 100644 --- a/docs/recipes/server-with-livereload-and-css-injection.md +++ b/docs/recipes/server-with-livereload-and-css-injection.md @@ -1,3 +1,10 @@ + + # Server with live-reloading and CSS injection With [BrowserSync](https://browsersync.io) and gulp, you can easily create a development server that is accessible to any device on the same WiFi network. BrowserSync also has live-reload built in, so there's nothing else to configure. diff --git a/docs/recipes/sharing-streams-with-stream-factories.md b/docs/recipes/sharing-streams-with-stream-factories.md index 16c110a0..93208523 100644 --- a/docs/recipes/sharing-streams-with-stream-factories.md +++ b/docs/recipes/sharing-streams-with-stream-factories.md @@ -1,3 +1,10 @@ + + # Sharing streams with stream factories If you use the same plugins in multiple tasks you might find yourself getting that itch to DRY things up. This method will allow you to create factories to split out your commonly used stream chains. diff --git a/docs/recipes/specifying-a-cwd.md b/docs/recipes/specifying-a-cwd.md index eba0ceca..b6306d6a 100644 --- a/docs/recipes/specifying-a-cwd.md +++ b/docs/recipes/specifying-a-cwd.md @@ -1,3 +1,10 @@ + + # Specifying a new cwd (current working directory) This is helpful for projects using a nested directory structure, such as: diff --git a/docs/recipes/split-tasks-across-multiple-files.md b/docs/recipes/split-tasks-across-multiple-files.md index afee1be1..efdd942f 100644 --- a/docs/recipes/split-tasks-across-multiple-files.md +++ b/docs/recipes/split-tasks-across-multiple-files.md @@ -1,3 +1,10 @@ + + # Split tasks across multiple files If your `gulpfile.js` is starting to grow too large, you can split the tasks diff --git a/docs/recipes/templating-with-swig-and-yaml-front-matter.md b/docs/recipes/templating-with-swig-and-yaml-front-matter.md index 50c98e5f..dbda0ad1 100644 --- a/docs/recipes/templating-with-swig-and-yaml-front-matter.md +++ b/docs/recipes/templating-with-swig-and-yaml-front-matter.md @@ -1,3 +1,10 @@ + + # Templating with Swig and YAML front-matter Templating can be setup using `gulp-swig` and `gulp-front-matter`: diff --git a/docs/recipes/using-external-config-file.md b/docs/recipes/using-external-config-file.md index b073f1df..4a2215d4 100644 --- a/docs/recipes/using-external-config-file.md +++ b/docs/recipes/using-external-config-file.md @@ -1,3 +1,10 @@ + + # Using external config file Beneficial because it's keeping tasks DRY and config.json can be used by another task runner, like `grunt`. diff --git a/docs/recipes/using-multiple-sources-in-one-task.md b/docs/recipes/using-multiple-sources-in-one-task.md index 39e3e3b2..6e5622ec 100644 --- a/docs/recipes/using-multiple-sources-in-one-task.md +++ b/docs/recipes/using-multiple-sources-in-one-task.md @@ -1,3 +1,10 @@ + + # Using multiple sources in one task ```js diff --git a/docs/why-use-pump/README.md b/docs/why-use-pump/README.md index de6ebc85..c4810725 100644 --- a/docs/why-use-pump/README.md +++ b/docs/why-use-pump/README.md @@ -1,3 +1,10 @@ + + # Why Use Pump? When using `pipe` from the Node.js streams, errors are not propagated forward diff --git a/docs/writing-a-plugin/README.md b/docs/writing-a-plugin/README.md index bcd70835..d876250c 100644 --- a/docs/writing-a-plugin/README.md +++ b/docs/writing-a-plugin/README.md @@ -1,3 +1,10 @@ + + # Writing a plugin If you plan to create your own Gulp plugin, you will save time by reading the full documentation. diff --git a/docs/writing-a-plugin/dealing-with-streams.md b/docs/writing-a-plugin/dealing-with-streams.md index fd518bd6..d1ad36a8 100644 --- a/docs/writing-a-plugin/dealing-with-streams.md +++ b/docs/writing-a-plugin/dealing-with-streams.md @@ -1,3 +1,10 @@ + + # Dealing with streams > It is highly recommended to write plugins supporting streams. Here is some information on creating a gulp plugin that supports streams. @@ -75,4 +82,3 @@ gulp.src('files/**/*.js', { buffer: false }) ## Some plugins using streams * [gulp-svgicons2svgfont](https://github.com/nfroidure/gulp-svgiconstosvgfont) - diff --git a/docs/writing-a-plugin/guidelines.md b/docs/writing-a-plugin/guidelines.md index b810ad8a..a1d626c9 100644 --- a/docs/writing-a-plugin/guidelines.md +++ b/docs/writing-a-plugin/guidelines.md @@ -1,3 +1,10 @@ + + # Guidelines > While these guidelines are totally optional, we **HIGHLY** recommend that everyone follows them. Nobody wants to use a bad plugin. These guidelines will actually help make your life easier by giving you assurance that your plugin fits well within gulp. diff --git a/docs/writing-a-plugin/recommended-modules.md b/docs/writing-a-plugin/recommended-modules.md index 0b49b39d..a2faa94c 100644 --- a/docs/writing-a-plugin/recommended-modules.md +++ b/docs/writing-a-plugin/recommended-modules.md @@ -1,3 +1,10 @@ + + # Recommended Modules > Sticking to this curated list of recommended modules will make sure you don't violate the plugin guidelines and ensure consistency across plugins. diff --git a/docs/writing-a-plugin/testing.md b/docs/writing-a-plugin/testing.md index 487a87f9..cc9f9846 100644 --- a/docs/writing-a-plugin/testing.md +++ b/docs/writing-a-plugin/testing.md @@ -1,3 +1,10 @@ + + # Testing > Testing your plugin is the only way to ensure quality. It brings confidence to your users and makes your life easier. diff --git a/docs/writing-a-plugin/using-buffers.md b/docs/writing-a-plugin/using-buffers.md index e35e41b5..b7ea0554 100644 --- a/docs/writing-a-plugin/using-buffers.md +++ b/docs/writing-a-plugin/using-buffers.md @@ -1,3 +1,10 @@ + + # Using buffers > Here is some information on creating gulp plugin that manipulates buffers. From 6a0fa00b8cae384fddf6ec6b905766bfcaf89ece Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Wed, 25 Apr 2018 14:53:10 -0700 Subject: [PATCH 091/225] Docs: Rename "Getting Started" to "Quick Start" & update it --- docs/getting-started.md | 84 ------------------------- docs/getting-started/1-quick-start.md | 88 +++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 84 deletions(-) delete mode 100644 docs/getting-started.md create mode 100644 docs/getting-started/1-quick-start.md diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index 6cfe981b..00000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,84 +0,0 @@ - - -# Getting Started - -*If you've previously installed gulp globally, run `npm rm --global gulp` before following these instructions.* For more information, read this [Sip](https://medium.com/gulpjs/gulp-sips-command-line-interface-e53411d4467). - -#### Check for Node and npm -Make sure that you've installed Node and npm before attempting to install gulp. - -```sh -node --version -``` -```sh -npm --version -``` - -#### Install the `gulp` command - -```sh -npm install --global gulp-cli -``` - -#### Create a `package.json` in your project directory -If you don't have a package.json, create one. If you need help, run an `npm init` which will walk you through giving it a name, version, description, etc. - - -#### Install `gulp` in your devDependencies - -Run this command in your project directory: - -```sh -npm install --save-dev gulp@next -``` - -#### Create a `gulpfile` - -In your project directory, create a file named `gulpfile.js` in your project root with these contents: - -```js -var gulp = require('gulp'); - -gulp.task('default', defaultTask); - -function defaultTask(done) { - // place code for your default task here - done(); -} -``` - -#### Test it out - -Run the gulp command in your project directory: - -```sh -gulp -``` - -To run multiple tasks, you can use `gulp `. - -#### Result - -Voila! The default task will run and do nothing. - -```sh -Using gulpfile ~/my-project/gulpfile.js -[11:15:51] Starting 'default'... -[11:15:51] Finished 'default' after 103 μs -``` - -## .src, .watch, .dest, .parallel, .series, CLI args - How do I use these things? - -For API specific documentation, you can check out the [documentation for that](API.md). - -## Where do I go now? - -- [API Documentation](API.md) - The programming interface, defined -- [Recipes](recipes) - Specific examples from the community -- [In Depth Help](https://travismaynard.com/writing/getting-started-with-gulp) - A tutorial from the guy who wrote the book -- [Plugins](https://gulpjs.com/plugins/) - Building blocks for your gulp file diff --git a/docs/getting-started/1-quick-start.md b/docs/getting-started/1-quick-start.md new file mode 100644 index 00000000..6f13d107 --- /dev/null +++ b/docs/getting-started/1-quick-start.md @@ -0,0 +1,88 @@ + + +# Quick Start + +If you've previously installed gulp globally, run `npm rm --global gulp` before following these instructions. For more information, read this [Sip][sip-article]. + +### Check for node, npm, and npx +```sh +node --version +``` +![Output: v8.11.1][img-node-version-command] +```sh +npm --version +``` +![Output: 5.6.0][img-npm-version-command] +```sh +npx --version +``` +![Output: 9.7.1][img-npx-version-command] + +If they are not installed, follow the instructions [here][node-install]. + +### Install the gulp command line utility +```sh +npm install --global gulp-cli +``` + + +### Create a project directory and navigate into it +```sh +npx mkdirp my-project +``` +```sh +cd my-project +``` + +### Create a package.json file in your project directory +```sh +npm init +``` + +This will guide you through giving your project a name, version, description, etc. + +### Install the gulp package in your devDependencies +```sh +npm install --save-dev gulp +``` + +### Verify your gulp versions +```sh +gulp --version +``` +![Output: CLI version 2.0.1 & Local version 4.0.0][img-gulp-version-command] + +### Create a gulpfile +Using your text editor, create a file named gulpfile.js in your project root with these contents: +```js +function defaultTask(done) { + // place code for your default task here + done(); +} + +exports.default = defaultTask +``` + +### Test it +Run the gulp command in your project directory: +```sh +gulp +``` +To run multiple tasks, you can use `gulp `. + +### Result +The default task will run and do nothing. +![Output: Starting default & Finished default][img-gulp-command] + +[sip-article]: https://medium.com/gulpjs/gulp-sips-command-line-interface-e53411d4467 +[node-install]: https://nodejs.org/en/ +[img-node-version-command]: https://gulpjs.com/img/docs-node-version-command.png +[img-npm-version-command]: https://gulpjs.com/img/docs-npm-version-command.png +[img-npx-version-command]: https://gulpjs.com/img/docs-npx-version-command.png +[img-gulp-version-command]: https://gulpjs.com/img/docs-gulp-version-command.png +[img-gulp-command]: https://gulpjs.com/img/docs-gulp-command.png From 21b696213603d35bebfbf9da925a0febf0e675eb Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 1 May 2018 15:18:06 -0700 Subject: [PATCH 092/225] Docs: Add "Creating Tasks" documentation --- docs/getting-started/3-creating-tasks.md | 191 +++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 docs/getting-started/3-creating-tasks.md diff --git a/docs/getting-started/3-creating-tasks.md b/docs/getting-started/3-creating-tasks.md new file mode 100644 index 00000000..e870b495 --- /dev/null +++ b/docs/getting-started/3-creating-tasks.md @@ -0,0 +1,191 @@ + + +# Creating Tasks + +Each gulp task is an asynchronous JavaScript function - a function that accepts an error-first callback or returns a stream, promise, event emitter, child process, or observable ([more on that later][async-completion-docs]). Due to some platform limitations, synchronous tasks aren't supported, though there is a pretty nifty [alternative][using-async-await-docs]. + +## Exporting + +Tasks can be considered **public** or **private**. + +* **Public tasks** are exported from your gulpfile, which allows them to be run by the `gulp` command. +* **Private tasks** are made to be used internally, usually used as part of `series()` or `parallel()` composition. + +A private task looks and acts like any other task, but an end-user can't ever execute it independently. To register a task publicly, export it from your gulpfile. + +```js +const { series } = require('gulp'); + +// The `clean` function is not exported so it can be considered a private task. +// It can still be used within the `series()` composition. +function clean(cb) { + // body omitted + cb(); +} + +// The `build` function is exported so it is public and can be run with the `gulp` command. +// It can also be used within the `series()` composition. +function build(cb) { + // body omitted + cb(); +} + +exports.build = build; +exports.default = series(clean, build); +``` + +![ALT TEXT MISSING][img-gulp-tasks-command] + +In the past, `task()` was used to register your functions as tasks. While that API is still available, exporting should be the primary registration mechanism, except in edge cases where exports won't work. + +## Compose tasks + +Gulp provides two powerful composition methods, `series()` and `parallel()`, allowing individual tasks to be composed into larger operations. Both methods accept any number of task functions or composed operations. `series()` and `parallel()` can be nested within themselves or each other to any depth. + +To have your tasks execute in order, use the `series()` method. +```js +const { series } = require('gulp'); + +function transpile(cb) { + // body omitted + cb(); +} + +function bundle(cb) { + // body omitted + cb(); +} + +exports.build = series(transpile, bundle); +``` + +For tasks to run at maximum concurrency, combine them with the `parallel()` method. +```js +const { parallel } = require('gulp'); + +function javascript(cb) { + // body omitted + cb(); +} + +function css(cb) { + // body omitted + cb(); +} + +exports.build = parallel(javascript, css); +``` + +Tasks are composed immediately when either `series()` or `parallel()` is called. This allows variation in the composition instead of conditional behavior inside individual tasks. + +```js +const { series } = require('gulp'); + +function minify(cb) { + // body omitted + cb(); +} + + +function transpile(cb) { + // body omitted + cb(); +} + +function livereload(cb) { + // body omitted + cb(); +} + +if (process.env.NODE_ENV === 'production') { + exports.build = series(transpile, minify); +} else { + exports.build = series(transpile, livereload); +} +``` + +`series()` and `parallel()` can be nested to any arbitrary depth. + +```js +const { series, parallel } = require('gulp'); + +function clean(cb) { + // body omitted + cb(); +} + +function cssTranspile(cb) { + // body omitted + cb(); +} + +function cssMinify(cb) { + // body omitted + cb(); +} + +function jsTranspile(cb) { + // body omitted + cb(); +} + +function jsBundle(cb) { + // body omitted + cb(); +} + +function jsMinify(cb) { + // body omitted + cb(); +} + +function publish(cb) { + // body omitted + cb(); +} + +exports.build = series( + clean, + parallel( + cssTranspile, + series(jsTranspile, jsBundle) + ), + parallel(cssMinify, jsMinify), + publish +); +``` + +When a composed operation is run, each task will be executed every time it was referenced. For example, a `clean` task referenced before two different tasks would be run twice and lead to undesired results. Tasks can be wrapped with the [async-once][async-once] module if this **(not recommended)** pattern is needed. + +```js +// This pattern is NOT recommended but some edge cases might require it. +const { series } = require('gulp'); +const once = require('async-once'); + +const clean = once(function(cb) { + // body omitted + cb(); +}); + +const css = series(clean, function(cb) { + // body omitted + cb(); +}); + +const javascript = series(clean, function(cb) { + // body omitted + cb(); +}) + +exports.build = series(css, javascript); +``` + +[async-completion-docs]: 4-async-completion.md +[using-async-await-docs]: 4-async-completion.md#using-asyncawait +[img-gulp-tasks-command]: https://gulpjs.com/img/docs-gulp-tasks-command.png +[async-once]: https://github.com/gulpjs/async-once From 31adf075f07d85c238bbf1d025bc9f74a74b4f24 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Mon, 21 May 2018 10:46:09 -0700 Subject: [PATCH 093/225] Docs: Add "JavaScript and Gulpfiles" documentation --- .../2-javascript-and-gulpfiles.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/getting-started/2-javascript-and-gulpfiles.md diff --git a/docs/getting-started/2-javascript-and-gulpfiles.md b/docs/getting-started/2-javascript-and-gulpfiles.md new file mode 100644 index 00000000..0c3b6823 --- /dev/null +++ b/docs/getting-started/2-javascript-and-gulpfiles.md @@ -0,0 +1,36 @@ + + +# JavaScript and Gulpfiles + +Gulp allows you to use existing JavaScript knowledge to write gulpfiles or to use your experience with gulpfiles to write plain JavaScript. Although a few utilities are provided to simplify working with the filesystem and command line, everything else you write is pure JavaScript. + +## Gulpfile explained + +A gulpfile is a file in your project directory titled `gulpfile.js` (or capitalized as `Gulpfile.js`, like Makefile), that automatically loads when you run the `gulp` command. Within this file, you'll often see gulp APIs, like `src()`, `dest()`, `series()`, or `parallel()` but any vanilla JavaScript or Node modules can be used. Any exported functions will be registered into gulp's task system. + +## Transpilation + +You can write a gulpfile using a language that requires transpilation, like TypeScript or Babel, by changing the extension on your `gulpfile.js` to indicate the language and install the matching transpiler module. + +* For TypeScript, rename to `gulpfile.ts` and install the [ts-node][ts-node-module] module. +* For Babel, rename to `gulpfile.babel.js` and install the [@babel/register][babel-register-module] module. + +For a more advanced dive into this topic and the full list of supported extensions, see our [gulpfile transpilation][gulpfile-transpilation-advanced] documentation. + +## Splitting a gulpfile + +Many users start by adding all logic to a gulpfile. If it ever grows too big, it can be refactored into separate files. + +Each task can be split into its own file, then imported into your gulpfile for composition. Not only does this keep things organized, but it allows you to test each task independently or vary composition based on conditions. + +Node's module resolution allows you to replace your `gulpfile.js` with a directory called `gulpfile` that contains an `index.js` file which is treated as a `gulpfile.js`. This directory could then contain your individual modules for tasks. + + +[gulpfile-transpilation-advanced]: LINK_NEEDED +[ts-node-module]: https://www.npmjs.com/package/ts-node +[babel-register-module]: https://www.npmjs.com/package/@babel/register From 50fafc6431c54f4a83dbcb2895ad442dd9341b77 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Mon, 21 May 2018 11:55:50 -0700 Subject: [PATCH 094/225] Docs: Add "Working with Files" documentation --- docs/getting-started/5-working-with-files.md | 98 ++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 docs/getting-started/5-working-with-files.md diff --git a/docs/getting-started/5-working-with-files.md b/docs/getting-started/5-working-with-files.md new file mode 100644 index 00000000..fb520586 --- /dev/null +++ b/docs/getting-started/5-working-with-files.md @@ -0,0 +1,98 @@ + + +# Working with Files + +The `src()` and `dest()` methods are exposed by gulp to interact with files on your computer. + +`src()` is given a [glob][explaining-globs-docs] to read from the file system and produces a [Node stream][node-streams-docs]. It locates all matching files and reads them into memory to pass through the stream. + +The stream produced by `src()` should be returned from a task to signal async completion, as mentioned in [Creating Tasks][creating-tasks-docs]. + +```js +const { src, dest } = require('gulp'); + +exports.default = function() { + return src('src/*.js') + .pipe(dest('output/')); +} +``` + +The main API of a stream is the `.pipe()` method for chaining Transform or Writable streams. + +```js +const { src, dest } = require('gulp'); +const babel = require('gulp-babel'); + +exports.default = function() { + return src('src/*.js') + .pipe(babel()) + .pipe(dest('output/')); +} +``` + +`dest()` is given an output directory string which is generally used as a terminator stream. When it receives a file passed through the pipeline, it writes the contents and other details out to the filesystem at a given directory. The `symlink()` method is also available and operates like `dest()`, but creates links instead of files (see [`symlink()`][symlink-api-docs] for details). + +Most often plugins will be placed between `src()` and `dest()` using the `.pipe()` method and will transform the files within the stream. + +## Adding files to the stream + +`src()` can also be placed in the middle of a pipeline to add files to the stream based on the given globs. The additional files will only be available to transformations later in the stream. If [globs overlap][overlapping-globs-docs], the files will be added again. + +This can be useful for transpiling some files before adding plain JavaScript files to the pipeline and uglifying everything. + +```js +const { src, dest } = require('gulp'); +const babel = require('gulp-babel'); +const uglify = require('gulp-uglify'); + +exports.default = function() { + return src('src/*.js') + .pipe(babel()) + .pipe(src('vendor/*.js')) + .pipe(uglify()) + .pipe(dest('output/')); +} +``` + +## Output in phases + +`dest()` can be used in the middle of a pipeline to write intermediate states to the filesystem. When a file is received, the current state is written out to the filesystem, the path is updated to represent the new location of the output file, then that file is passed down the pipeline. + +This feature can be useful to create an unminified and minified file with the same pipeline. + +```js +const { src, dest } = require('gulp'); +const babel = require('gulp-babel'); +const uglify = require('gulp-uglify'); +const rename = require('gulp-rename'); + +exports.default = function() { + return src('src/*.js') + .pipe(babel()) + .pipe(src('vendor/*.js')) + .pipe(dest('output/')) + .pipe(uglify()) + .pipe(rename({ extname: '.min.js' })) + .pipe(dest('output/')); +} +``` + +## Modes: streaming, buffered, and empty + +`src()` can operate in three modes: buffering, streaming, and empty. These are configured with the `buffer` and `read` [options][src-options-api-docs] on `src()`. + +* Buffering mode is the default and loads the file contents into memory. Plugins usually operate in buffering mode and many don't support streaming mode. +* Streaming mode exists mainly to operate on large files that can't fit in memory, like giant images or movies. The contents are streamed from the filesystem in small chunks instead of loaded all at once. If you need to use streaming mode, look for a plugin that supports it or write your own. +* Empty mode contains no contents and is useful when only working with file metadata. + +[explaining-globs-docs]: 6-explaining-globs.md +[creating-tasks-docs]: 3-creating-tasks.md +[overlapping-globs-docs]: 6-explaining-globs.md#overlapping-globs +[node-streams-docs]: https://nodejs.org/api/stream.html +[symlink-api-docs]: LINK_NEEDED +[src-options-api-docs]: LINK_NEEDED From ad8b568878b894712801ed46fa8262b13091152c Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Wed, 23 May 2018 14:39:51 -0700 Subject: [PATCH 095/225] Docs: Add "Async Completion" documentation --- docs/getting-started/4-async-completion.md | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 docs/getting-started/4-async-completion.md diff --git a/docs/getting-started/4-async-completion.md b/docs/getting-started/4-async-completion.md new file mode 100644 index 00000000..ac816524 --- /dev/null +++ b/docs/getting-started/4-async-completion.md @@ -0,0 +1,144 @@ + + +# Async Completion + +Node libraries handle asynchronicity in a variety of ways. The most common pattern is [error-first callbacks][node-api-error-first-callbacks], but you might also encounter [streams][stream-docs], [promises][promise-docs], [event emitters][event-emitter-docs], [child processes][child-process-docs], or [observables][observable-docs]. Gulp tasks normalize all these types of asynchronicity. + +## Signal task completion + +When a stream, promise, event emitter, child process, or observable is returned from a task, the success or error informs gulp whether to continue or end. If a task errors, gulp will end immediately and show that error. + +When composing tasks with `series()`, an error will end the composition and no further tasks will be executed. When composing tasks with `parallel()`, an error will end the composition but the other parallel tasks may or may not complete. + +### Returning a stream + +```js +const { src, dest } = require('gulp'); + +function streamTask() { + return src('*.js') + .pipe(dest('output')); +} + +exports.default = streamTask; +``` + +### Returning a promise + +```js +function promiseTask() { + return Promise.resolve('some ignored value'); +} + +exports.default = promiseTask; +``` + +### Returning an event emitter + +```js +const { EventEmitter } = require('events'); + +function eventEmitterTask() { + const emitter = new EventEmitter(); + // Emit has to happen async otherwise gulp isn't listening yet + setTimeout(() => emitter.emit('finish'), 250); + return emitter; +} + +exports.default = eventEmitterTask; +``` + +### Returning a child process + +```js +const { exec } = require('child_process'); + +function childProcessTask() { + return exec('date'); +} + +exports.default = childProcessTask; +``` + +### Returning an observable + +```js +const { Observable } = require('rxjs'); + +function observableTask() { + return Observable.of(1, 2, 3); +} + +exports.default = observableTask; +``` + +### Using an error-first callback + +If nothing is returned from your task, you must use the error-first callback to signal completion. The callback will be passed to your task as the only argument - named `done()` in the examples below. + +```js +function callbackTask(done) { + // `done()` should be called by some async work + done(); +} + +exports.default = callbackTask; +``` + +To indicate to gulp that an error occurred in a task using an error-first callback, call it with an `Error` as the only argument. + +```js +function callbackError(done) { + // `done()` should be called by some async work + done(new Error('kaboom')); +} + +exports.default = callbackError; +``` + +However, you'll often pass this callback to another API instead of calling it yourself. + +```js +const fs = require('fs'); + +function passingCallback(done) { + fs.access('gulpfile.js', done); +} + +exports.default = passingCallback; +``` + +## No synchronous tasks + +Synchronous tasks are no longer supported. They often led to subtle mistakes that were hard to debug, like forgetting to return your streams from a task. + +When you see the _"Did you forget to signal async completion?"_ warning, none of the techniques mentioned above were used. You'll need to use the error-first callback or return a stream, promise, event emitter, child process, or observable to resolve the issue. + +## Using async/await + +When not using any of the previous options, you can define your task as an [`async` function][async-await-docs], which wraps your task in a promise. This allows you to work with promises synchronously using `await` and use other synchronous code. + +```js +const fs = require('fs'); + +async function asyncAwaitTask() { + const { version } = fs.readFileSync('package.json'); + console.log(version); + await Promise.resolve('some result'); +} + +exports.default = asyncAwaitTask; +``` + +[node-api-error-first-callbacks]: https://nodejs.org/api/errors.html#errors_error_first_callbacks +[stream-docs]: https://nodejs.org/api/stream.html#stream_stream +[promise-docs]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises +[event-emitter-docs]: https://nodejs.org/api/events.html#events_events +[child-process-docs]: https://nodejs.org/api/child_process.html#child_process_child_process +[observable-docs]: https://github.com/tc39/proposal-observable/blob/master/README.md +[async-await-docs]: https://developers.google.com/web/fundamentals/primers/async-functions From f8cafa05726f570ef35b08e4fb9e7de623c5d34c Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 22 May 2018 14:56:07 -0700 Subject: [PATCH 096/225] Docs: Add "Explaining Globs" documentation --- docs/getting-started/6-explaining-globs.md | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 docs/getting-started/6-explaining-globs.md diff --git a/docs/getting-started/6-explaining-globs.md b/docs/getting-started/6-explaining-globs.md new file mode 100644 index 00000000..de524d84 --- /dev/null +++ b/docs/getting-started/6-explaining-globs.md @@ -0,0 +1,88 @@ + + +# Explaining Globs + +A glob is a string of literal and/or wildcard characters used to match filepaths. Globbing is the act of locating files on a filesystem using one or more globs. + +The `src()` method expects a single glob string or an array of globs to determine which files your pipeline will operate on. At least one match must be found for your glob(s) otherwise `src()` will error. When an array of globs is used, they are matched in array order - especially useful for negative globs. + +## Segments and separators + +A segment is everything between separators. The separator in a glob is always the `/` character - regardless of the operating system - even in Windows where the path separator is `\\`. In a glob, `\\` is reserved as the escape character. + +Here, the * is escaped, so it is treated as a literal instead of a wildcard character. +```js +'glob_with_uncommon_\\*_character.js' +``` + +Avoid using Node's `path` methods, like `path.join`, to create globs. On Windows, it produces an invalid glob because Node uses `\\` as the separator. Also avoid the `__dirname` global, `__filename` global, or `process.cwd()` for the same reasons. + +```js +const invalidGlob = path.join(__dirname, 'src/*.js'); +``` + +## Special character: * (single-star) + +Matches any amount - including none - of characters within a single segment. Useful for globbing files within one directory. + +This glob will match files like `index.js`, but not files like `scripts/index.js` or `scripts/nested/index.js` +```js +'*.js' +``` + +## Special character: ** (double-star) + +Matches any amount - including none - of characters across segments. Useful for globbing files in nested directories. Make sure to appropriately restrict your double-star globs, to avoid matching large directories unnecessarily. + +Here, the glob is appropriately restricted to the `scripts/` directory. It will match files like `scripts/index.js`, `scripts/nested/index.js`, and `scripts/nested/twice/index.js`. + +```js +'scripts/**/*.js' +``` + +In the previous example, if `scripts/` wasn't prefixed, all dependencies in `node_modules` or other directories would also be matched. + +## Special character: ! (negative) + +Since globs are matched in array order, a negative glob must follow at least one non-negative glob in an array. The first finds a set of matches, then the negative glob removes a portion of those results. These are most performant when they only include literal characters. + +```js +['script/**/*.js', '!scripts/vendor/'] +``` + +If any non-negative globs follow a negative, nothing will be removed from the later set of matches. + +```js +['script/**/*.js', '!scripts/vendor/', 'scripts/vendor/react.js'] +``` + +Negative globs can be used as an alternative for restricting double-star globs. + +```js +['**/*.js', '!node_modules/'] +``` + +In the previous example, if the negative glob was `!node_modules/**/*.js`, every match would have to be compared against the negative glob, which would be extremely slow. + +## Overlapping globs + +Two or more globs that (un)intentionally match the same file are considered overlapping. When overlapping globs are used within a single `src()`, gulp does its best to remove the duplicates, but doesn't attempt to deduplicate across separate `src()` calls. + +## Advanced resources + +Most of what you'll need to work with globs in gulp is covered here. If you'd like to get more in depth, here are a few resources. + +* [Micromatch Documentation][micromatch-docs] +* [node-glob's Glob Primer][glob-primer-docs] +* [Begin's Globbing Documentation][begin-globbing-docs] +* [Wikipedia's Glob Page][wikipedia-glob] + +[micromatch-docs]: https://github.com/micromatch/micromatch +[glob-primer-docs]: https://github.com/isaacs/node-glob#glob-primer +[begin-globbing-docs]: https://github.com/begin/globbing#what-is-globbing +[wikipedia-glob]: https://en.wikipedia.org/wiki/Glob_(programming) From 233c3f9aa7f5fbfe6dd4765e3334eb45fddd3f0f Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 29 May 2018 13:41:13 -0700 Subject: [PATCH 097/225] Docs: Add "Using Plugins" documentation --- docs/getting-started/7-using-plugins.md | 113 ++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 docs/getting-started/7-using-plugins.md diff --git a/docs/getting-started/7-using-plugins.md b/docs/getting-started/7-using-plugins.md new file mode 100644 index 00000000..e14a5063 --- /dev/null +++ b/docs/getting-started/7-using-plugins.md @@ -0,0 +1,113 @@ + + +# Using Plugins + +Gulp plugins are [Node Transform Streams][through2-docs] that encapsulate common behavior to transform files in a pipeline - often placed between `src()` and `dest()` using the `.pipe()` method. They can change the filename, metadata, or contents of every file that passes through the stream. + +Plugins from npm - using the "gulpplugin" and "gulpfriendly" keywords - can be browsed and searched on the [plugin search page][gulp-plugin-site]. + +Each plugin should only do a small amount of work, so you can connect them like building blocks. You may need to combine a bunch of them to get the desired result. + +```js +const { src, dest } = require('gulp'); +const uglify = require('gulp-uglify'); +const rename = require('gulp-rename'); + +exports.default = function() { + return src('src/*.js') + // The gulp-uglify plugin won't update the filename + .pipe(uglify()) + // So use gulp-rename to change the extension + .pipe(rename({ extname: '.min.js' })) + .pipe(dest('output/')); +} +``` + +## Do you need a plugin? + +Not everything in gulp should use plugins. They are a quick way to get started, but many operations are improved by using a module or library instead. + +```js +const { rollup } = require('rollup'); + +// Rollup's promise API works great in an `async` task +exports.default = async function() { + const bundle = await rollup.rollup({ + input: 'src/index.js' + }); + + return bundle.write({ + file: 'output/bundle.js', + format: 'iife' + }); +} +``` + +Plugins should always transform files. Use a (non-plugin) Node module or library for any other operations. + +```js +const del = require('delete'); + +exports.default = function(cb) { + // Use the `delete` module directly, instead of using gulp-rimraf + del(['output/*.js'], cb); +} +``` + +## Conditional plugins + +Since plugin operations shouldn't be file-type-aware, you may need a plugin like [gulp-if][gulp-if-package] to transform subsets of files. + +```js +const { src, dest } = require('gulp'); +const gulpif = require('gulp-if'); +const uglify = require('gulp-uglify'); + +function isJavaScript(file) { + // Check if file extension is '.js' + return file.extname === '.js'; +} + +exports.default = function() { + // Include JavaScript and CSS files in a single pipeline + return src(['src/*.js', 'src/*.css']) + // Only apply gulp-uglify plugin to JavaScript files + .pipe(gulpif(isJavaScript, uglify())) + .pipe(dest('output/')); +} +``` + +## Inline plugins + +Inline plugins are one-off Transform Streams you define inside your gulpfile by writing the desired behavior. + +There are two situations where creating an inline plugin is helpful: +* Instead of creating and maintaining your own plugin. +* Instead of forking a plugin that exists to add a feature you want. + +```js +const { src, dest } = require('gulp'); +const uglify = require('uglify-js'); +const through2 = require('through2'); + +exports.default = function() { + return src('src/*.js') + // Instead of using gulp-uglify, you can create an inline plugin + .pipe(through2.obj(function(file, _, cb) { + if (file.isBuffer()) { + const code = uglify.minify(file.contents.toString()) + file.contents = Buffer.from(code) + } + })) + .pipe(dest('output/')); +} +``` + +[gulp-plugin-site]: https://gulpjs.com/plugins/ +[through2-docs]: https://github.com/rvagg/through2 +[gulp-if-package]: https://www.npmjs.com/package/gulp-if From f3f2d9f9b624983fc4985a5ab5b45542e08bcf83 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 31 May 2018 10:46:05 -0700 Subject: [PATCH 098/225] Docs: Add "Watching Files" documentation --- docs/getting-started/8-watching-files.md | 122 +++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 docs/getting-started/8-watching-files.md diff --git a/docs/getting-started/8-watching-files.md b/docs/getting-started/8-watching-files.md new file mode 100644 index 00000000..4ed63d2f --- /dev/null +++ b/docs/getting-started/8-watching-files.md @@ -0,0 +1,122 @@ + + +# Watching Files + +The `watch()` API connects [globs][globs-docs] to [tasks][creating-tasks-docs] using a file system watcher. It watches for changes to files that match the globs and executes the task when a change occurs. If the task doesn't signal [Async Completion][async-completion-doc], it will never be run a second time. + +This API provides built-in delay and queueing based on most-common-use defaults. + +```js +const { watch, series } = require('gulp'); + +function clean(cb) { + // Body omitted + cb(); +} + +function javascript(cb) { + // Body omitted + cb(); +} + +function css(cb) { + // Body omitted + cb(); +} + +// You can use a single task +watch('src/*.css', css); +// Or a composed task +watch('src/*.js', series(clean, javascript)); +``` + +## Warning: Avoid synchronous + +A watcher's task cannot be synchronous, like tasks registered into the task system. If you pass a sync task, the completion can't be determined and the task won't run again - it is assumed to still be running. + +There is no error or warning message provided because the file watcher keeps your Node process running. Since the process doesn't exit, it cannot be determined whether the task is done or just taking a really, really long time to run. + +## Watched events + +By default, the watcher executes tasks whenever a file is created, changed, or deleted. +If you need to use different events, you can use the `events` option when calling `watch()`. The available events are `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, `'error'`. Additionally `'all'` is available, which represents all events other than `'ready'` and `'error'`. + +```js +const { watch } = require('gulp'); + +// All events will be watched +watch('src/*.js', { events: 'all' }, function(cb) { + // Body omitted + cb(); +}); +``` + +## Initial execution + +Upon calling `watch()`, the tasks won't be executed, instead they'll wait for the first file change. + +To execute tasks before the first file change, set the `ignoreInitial` option to `false`. + +```js +const { watch } = require('gulp'); + +// The task will be executed upon startup +watch('src/*.js', { ignoreInitial: false }, function(cb) { + // Body omitted + cb(); +}); +``` + +## Queueing + +Each `watch()` guarantees that its currently running task won't execute again concurrently. When a file change is made while a watcher task is running, another execution will queue up to run when the task finishes. Only one run can be queued up at a time. + +To disable queueing, set the `queue` option to `false`. + +```js +const { watch } = require('gulp'); + +// The task will be run (concurrently) for every change made +watch('src/*.js', { queue: false }, function(cb) { + // Body omitted + cb(); +}); +``` + +## Delay + +Upon file change, a watcher task won't run until a 200ms delay has elapsed. This is to avoid starting a task too early when many files are being changed at once - like find-and-replace. + +To adjust the delay duration, set the `delay` option to a positive integer. + +```js +const { watch } = require('gulp'); + +// The task won't be run until 500ms have elapsed since the first change +watch('src/*.js', { delay: 500 }, function(cb) { + // Body omitted + cb(); +}); +``` + +## Using the watcher instance + +You likely won't use this feature, but if you need full control over changed files - like access to paths or metadata - use the [chokidar][chokidar-module-package] instance returned from `watch()`. + +__Be careful:__ The returned chokidar instance doesn't have queueing, delay, or async completion features. + +## Optional dependency + +Gulp has an optional dependency called [fsevents][fsevents-package], which is a Mac-specific file watcher. If you see an installation warning for fsevents - _"npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents"_ - it is not an issue. +If fsevents installation is skipped, a fallback watcher will be used and any errors occurring in your gulpfile aren't related to this warning. + +[globs-docs]: 6-explaining-globs.md +[creating-tasks-docs]: 3-creating-tasks.md +[async-completion-doc]: 4-async-completion.md +[chokidar-module-package]: https://www.npmjs.com/package/chokidar +[fsevents-package]: https://www.npmjs.com/package/fsevents From a43caf214ebe49397d08b57caffa636268039956 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 31 May 2018 13:43:37 -0700 Subject: [PATCH 099/225] Docs: Add Table of Contents to "Getting Started" directory --- docs/getting-started/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 docs/getting-started/README.md diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md new file mode 100644 index 00000000..fe599a90 --- /dev/null +++ b/docs/getting-started/README.md @@ -0,0 +1,10 @@ +# Getting Started + +1. [Quick Start](1-quick-start.md) +2. [JavaScript and Gulpfiles](2-javascript-and-gulpfiles.md) +3. [Creating Tasks](3-creating-tasks.md) +4. [Async Completion](4-async-completion.md) +5. [Working with Files](5-working-with-files.md) +6. [Explaining Globs](6-explaining-globs.md) +7. [Using Plugins](7-using-plugins.md) +8. [Watching Files](8-watching-files.md) From 9f4a2e96506dec1d85804de8884678e72ffc5aa0 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 31 May 2018 13:57:27 -0700 Subject: [PATCH 100/225] Fix: Temporary workaround for facebook/Docusaurus#257 --- docs/getting-started/3-creating-tasks.md | 2 +- docs/getting-started/5-working-with-files.md | 6 +++--- docs/getting-started/8-watching-files.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/3-creating-tasks.md b/docs/getting-started/3-creating-tasks.md index e870b495..e14942ec 100644 --- a/docs/getting-started/3-creating-tasks.md +++ b/docs/getting-started/3-creating-tasks.md @@ -7,7 +7,7 @@ sidebar_label: Creating Tasks # Creating Tasks -Each gulp task is an asynchronous JavaScript function - a function that accepts an error-first callback or returns a stream, promise, event emitter, child process, or observable ([more on that later][async-completion-docs]). Due to some platform limitations, synchronous tasks aren't supported, though there is a pretty nifty [alternative][using-async-await-docs]. +Each gulp task is an asynchronous JavaScript function - a function that accepts an error-first callback or returns a stream, promise, event emitter, child process, or observable ([more on that later](4-async-completion.md)). Due to some platform limitations, synchronous tasks aren't supported, though there is a pretty nifty [alternative](4-async-completion.md#using-asyncawait). ## Exporting diff --git a/docs/getting-started/5-working-with-files.md b/docs/getting-started/5-working-with-files.md index fb520586..38bcd581 100644 --- a/docs/getting-started/5-working-with-files.md +++ b/docs/getting-started/5-working-with-files.md @@ -9,9 +9,9 @@ sidebar_label: Working with Files The `src()` and `dest()` methods are exposed by gulp to interact with files on your computer. -`src()` is given a [glob][explaining-globs-docs] to read from the file system and produces a [Node stream][node-streams-docs]. It locates all matching files and reads them into memory to pass through the stream. +`src()` is given a [glob](6-explaining-globs.md) to read from the file system and produces a [Node stream][node-streams-docs]. It locates all matching files and reads them into memory to pass through the stream. -The stream produced by `src()` should be returned from a task to signal async completion, as mentioned in [Creating Tasks][creating-tasks-docs]. +The stream produced by `src()` should be returned from a task to signal async completion, as mentioned in [Creating Tasks](3-creating-tasks.md). ```js const { src, dest } = require('gulp'); @@ -41,7 +41,7 @@ Most often plugins will be placed between `src()` and `dest()` using the `.pipe( ## Adding files to the stream -`src()` can also be placed in the middle of a pipeline to add files to the stream based on the given globs. The additional files will only be available to transformations later in the stream. If [globs overlap][overlapping-globs-docs], the files will be added again. +`src()` can also be placed in the middle of a pipeline to add files to the stream based on the given globs. The additional files will only be available to transformations later in the stream. If [globs overlap](6-explaining-globs.md#overlapping-globs), the files will be added again. This can be useful for transpiling some files before adding plain JavaScript files to the pipeline and uglifying everything. diff --git a/docs/getting-started/8-watching-files.md b/docs/getting-started/8-watching-files.md index 4ed63d2f..550b46e3 100644 --- a/docs/getting-started/8-watching-files.md +++ b/docs/getting-started/8-watching-files.md @@ -7,7 +7,7 @@ sidebar_label: Watching Files # Watching Files -The `watch()` API connects [globs][globs-docs] to [tasks][creating-tasks-docs] using a file system watcher. It watches for changes to files that match the globs and executes the task when a change occurs. If the task doesn't signal [Async Completion][async-completion-doc], it will never be run a second time. +The `watch()` API connects [globs](6-explaining-globs.md) to [tasks](3-creating-tasks.md) using a file system watcher. It watches for changes to files that match the globs and executes the task when a change occurs. If the task doesn't signal [Async Completion](4-async-completion.md), it will never be run a second time. This API provides built-in delay and queueing based on most-common-use defaults. From 84b023460201ba30805e5cbc684aac93cb48965f Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 29 Jul 2018 14:44:27 -0700 Subject: [PATCH 101/225] Docs: Improve & fix parts of Getting Started --- docs/getting-started/1-quick-start.md | 8 +++- docs/getting-started/3-creating-tasks.md | 40 ++++++++++++++++---- docs/getting-started/4-async-completion.md | 20 +++++----- docs/getting-started/5-working-with-files.md | 6 +-- docs/getting-started/7-using-plugins.md | 1 + docs/getting-started/8-watching-files.md | 14 +++---- 6 files changed, 59 insertions(+), 30 deletions(-) diff --git a/docs/getting-started/1-quick-start.md b/docs/getting-started/1-quick-start.md index 6f13d107..b724e048 100644 --- a/docs/getting-started/1-quick-start.md +++ b/docs/getting-started/1-quick-start.md @@ -52,17 +52,21 @@ npm install --save-dev gulp ``` ### Verify your gulp versions + ```sh gulp --version ``` + +Ensure the output matches the screenshot below or you might need to restart the steps in this guide. + ![Output: CLI version 2.0.1 & Local version 4.0.0][img-gulp-version-command] ### Create a gulpfile Using your text editor, create a file named gulpfile.js in your project root with these contents: ```js -function defaultTask(done) { +function defaultTask(cb) { // place code for your default task here - done(); + cb(); } exports.default = defaultTask diff --git a/docs/getting-started/3-creating-tasks.md b/docs/getting-started/3-creating-tasks.md index e14942ec..48ea9ed6 100644 --- a/docs/getting-started/3-creating-tasks.md +++ b/docs/getting-started/3-creating-tasks.md @@ -160,17 +160,18 @@ exports.build = series( ); ``` -When a composed operation is run, each task will be executed every time it was referenced. For example, a `clean` task referenced before two different tasks would be run twice and lead to undesired results. Tasks can be wrapped with the [async-once][async-once] module if this **(not recommended)** pattern is needed. +When a composed operation is run, each task will be executed every time it was referenced. For example, a `clean` task referenced before two different tasks would be run twice and lead to undesired results. Instead, refactor the `clean` task to be specified in the final composition. + +If you have code like this: ```js -// This pattern is NOT recommended but some edge cases might require it. -const { series } = require('gulp'); -const once = require('async-once'); +// This is INCORRECT +const { series, parallel } = require('gulp'); -const clean = once(function(cb) { +const clean = function(cb) { // body omitted cb(); -}); +}; const css = series(clean, function(cb) { // body omitted @@ -180,9 +181,32 @@ const css = series(clean, function(cb) { const javascript = series(clean, function(cb) { // body omitted cb(); -}) +}); + +exports.build = parallel(css, javascript); +``` + +Migrate to this: + +```js +const { series, parallel } = require('gulp'); + +function clean(cb) { + // body omitted + cb(); +} + +function css(cb) { + // body omitted + cb(); +} + +function javascript(cb) { + // body omitted + cb(); +} -exports.build = series(css, javascript); +exports.build = series(clean, parallel(css, javascript)); ``` [async-completion-docs]: 4-async-completion.md diff --git a/docs/getting-started/4-async-completion.md b/docs/getting-started/4-async-completion.md index ac816524..908fcc06 100644 --- a/docs/getting-started/4-async-completion.md +++ b/docs/getting-started/4-async-completion.md @@ -32,7 +32,7 @@ exports.default = streamTask; ```js function promiseTask() { - return Promise.resolve('some ignored value'); + return Promise.resolve('the value is ignored'); } exports.default = promiseTask; @@ -79,12 +79,12 @@ exports.default = observableTask; ### Using an error-first callback -If nothing is returned from your task, you must use the error-first callback to signal completion. The callback will be passed to your task as the only argument - named `done()` in the examples below. +If nothing is returned from your task, you must use the error-first callback to signal completion. The callback will be passed to your task as the only argument - named `cb()` in the examples below. ```js -function callbackTask(done) { - // `done()` should be called by some async work - done(); +function callbackTask(cb) { + // `cb()` should be called by some async work + cb(); } exports.default = callbackTask; @@ -93,9 +93,9 @@ exports.default = callbackTask; To indicate to gulp that an error occurred in a task using an error-first callback, call it with an `Error` as the only argument. ```js -function callbackError(done) { - // `done()` should be called by some async work - done(new Error('kaboom')); +function callbackError(cb) { + // `cb()` should be called by some async work + cb(new Error('kaboom')); } exports.default = callbackError; @@ -106,8 +106,8 @@ However, you'll often pass this callback to another API instead of calling it yo ```js const fs = require('fs'); -function passingCallback(done) { - fs.access('gulpfile.js', done); +function passingCallback(cb) { + fs.access('gulpfile.js', cb); } exports.default = passingCallback; diff --git a/docs/getting-started/5-working-with-files.md b/docs/getting-started/5-working-with-files.md index 38bcd581..52490572 100644 --- a/docs/getting-started/5-working-with-files.md +++ b/docs/getting-started/5-working-with-files.md @@ -35,7 +35,7 @@ exports.default = function() { } ``` -`dest()` is given an output directory string which is generally used as a terminator stream. When it receives a file passed through the pipeline, it writes the contents and other details out to the filesystem at a given directory. The `symlink()` method is also available and operates like `dest()`, but creates links instead of files (see [`symlink()`][symlink-api-docs] for details). +`dest()` is given an output directory string and also produces a [Node stream][node-streams-docs] which is generally used as a terminator stream. When it receives a file passed through the pipeline, it writes the contents and other details out to the filesystem at a given directory. The `symlink()` method is also available and operates like `dest()`, but creates links instead of files (see [`symlink()`][symlink-api-docs] for details). Most often plugins will be placed between `src()` and `dest()` using the `.pipe()` method and will transform the files within the stream. @@ -61,9 +61,9 @@ exports.default = function() { ## Output in phases -`dest()` can be used in the middle of a pipeline to write intermediate states to the filesystem. When a file is received, the current state is written out to the filesystem, the path is updated to represent the new location of the output file, then that file is passed down the pipeline. +`dest()` can be used in the middle of a pipeline to write intermediate states to the filesystem. When a file is received, the current state is written out to the filesystem, the path is updated to represent the new location of the output file, then that file continues down the pipeline. -This feature can be useful to create an unminified and minified file with the same pipeline. +This feature can be useful to create unminified and minified files with the same pipeline. ```js const { src, dest } = require('gulp'); diff --git a/docs/getting-started/7-using-plugins.md b/docs/getting-started/7-using-plugins.md index e14a5063..fda30553 100644 --- a/docs/getting-started/7-using-plugins.md +++ b/docs/getting-started/7-using-plugins.md @@ -103,6 +103,7 @@ exports.default = function() { const code = uglify.minify(file.contents.toString()) file.contents = Buffer.from(code) } + cb(null, file); })) .pipe(dest('output/')); } diff --git a/docs/getting-started/8-watching-files.md b/docs/getting-started/8-watching-files.md index 550b46e3..7c9199ed 100644 --- a/docs/getting-started/8-watching-files.md +++ b/docs/getting-started/8-watching-files.md @@ -15,17 +15,17 @@ This API provides built-in delay and queueing based on most-common-use defaults. const { watch, series } = require('gulp'); function clean(cb) { - // Body omitted + // body omitted cb(); } function javascript(cb) { - // Body omitted + // body omitted cb(); } function css(cb) { - // Body omitted + // body omitted cb(); } @@ -51,7 +51,7 @@ const { watch } = require('gulp'); // All events will be watched watch('src/*.js', { events: 'all' }, function(cb) { - // Body omitted + // body omitted cb(); }); ``` @@ -67,7 +67,7 @@ const { watch } = require('gulp'); // The task will be executed upon startup watch('src/*.js', { ignoreInitial: false }, function(cb) { - // Body omitted + // body omitted cb(); }); ``` @@ -83,7 +83,7 @@ const { watch } = require('gulp'); // The task will be run (concurrently) for every change made watch('src/*.js', { queue: false }, function(cb) { - // Body omitted + // body omitted cb(); }); ``` @@ -99,7 +99,7 @@ const { watch } = require('gulp'); // The task won't be run until 500ms have elapsed since the first change watch('src/*.js', { delay: 500 }, function(cb) { - // Body omitted + // body omitted cb(); }); ``` From 2bd75d035a2630e3de089cd9b1ec355461d00f6e Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 29 Jul 2018 15:01:10 -0700 Subject: [PATCH 102/225] Docs: Create and link-to a "docs missing" page for LINK_NEEDED references --- docs/documentation-missing.md | 5 +++++ docs/getting-started/2-javascript-and-gulpfiles.md | 2 +- docs/getting-started/5-working-with-files.md | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 docs/documentation-missing.md diff --git a/docs/documentation-missing.md b/docs/documentation-missing.md new file mode 100644 index 00000000..1c47aa2c --- /dev/null +++ b/docs/documentation-missing.md @@ -0,0 +1,5 @@ +## Excuse our dust! + +We're in the process of rewriting **all** our documentation and some of the links we've added to completed docs haven't been written yet. You've likely clicked on one of those to end up here. We're sorry about that but please check back later on the topic you're interested in. + +-The Gulp Team diff --git a/docs/getting-started/2-javascript-and-gulpfiles.md b/docs/getting-started/2-javascript-and-gulpfiles.md index 0c3b6823..b82193f3 100644 --- a/docs/getting-started/2-javascript-and-gulpfiles.md +++ b/docs/getting-started/2-javascript-and-gulpfiles.md @@ -31,6 +31,6 @@ Each task can be split into its own file, then imported into your gulpfile for c Node's module resolution allows you to replace your `gulpfile.js` with a directory called `gulpfile` that contains an `index.js` file which is treated as a `gulpfile.js`. This directory could then contain your individual modules for tasks. -[gulpfile-transpilation-advanced]: LINK_NEEDED +[gulpfile-transpilation-advanced]: ../documentation-missing.md [ts-node-module]: https://www.npmjs.com/package/ts-node [babel-register-module]: https://www.npmjs.com/package/@babel/register diff --git a/docs/getting-started/5-working-with-files.md b/docs/getting-started/5-working-with-files.md index 52490572..2e87d2e5 100644 --- a/docs/getting-started/5-working-with-files.md +++ b/docs/getting-started/5-working-with-files.md @@ -94,5 +94,5 @@ exports.default = function() { [creating-tasks-docs]: 3-creating-tasks.md [overlapping-globs-docs]: 6-explaining-globs.md#overlapping-globs [node-streams-docs]: https://nodejs.org/api/stream.html -[symlink-api-docs]: LINK_NEEDED -[src-options-api-docs]: LINK_NEEDED +[symlink-api-docs]: ../documentation-missing.md +[src-options-api-docs]: ../documentation-missing.md From 53e9727653ce4243e19c480fd382c18b196de8f8 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 29 Jul 2018 14:54:44 -0700 Subject: [PATCH 103/225] Docs: Redirect users to new Getting Started guides --- docs/README.md | 2 +- docs/getting-started.md | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 docs/getting-started.md diff --git a/docs/README.md b/docs/README.md index d1b9f8c2..f90cabc9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ sidebar_label: Docs # gulp documentation -* [Getting Started](getting-started.md) - Get started with gulp +* [Getting Started](getting-started/) - Get started with gulp * [API documentation](API.md) - The programming interface, defined * [CLI documentation](CLI.md) - Learn how to call tasks and use compilers * [Writing a Plugin](writing-a-plugin/) - The essentials of writing a gulp plugin diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 00000000..c3ec6e46 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,5 @@ +## This documentation has moved! + +You can find the new documentation in our [Quick Start](getting-started/1-quick-start.md) guide. + +While you are there, check out our expanded [Getting Started](getting-started/) documentation. From 10272369e517dbb31a9ab9f73242f7f5801fde5c Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 29 Jul 2018 15:37:32 -0700 Subject: [PATCH 104/225] Scaffold: Update some links and license year --- .editorconfig | 2 +- .gitignore | 4 ++-- LICENSE | 2 +- appveyor.yml | 4 ++-- docs/API.md | 4 ++-- package.json | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.editorconfig b/.editorconfig index e000b0ce..e7b73a7a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -# http://editorconfig.org +# https://editorconfig.org root = true [*] diff --git a/.gitignore b/.gitignore index 6f636468..ac88dd1f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,10 +13,10 @@ lib-cov # Coverage directory used by tools like istanbul coverage -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt -# Compiled binary addons (http://nodejs.org/api/addons.html) +# Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directory diff --git a/LICENSE b/LICENSE index 6355a4b4..6a29df97 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2017 Blaine Bublitz , Eric Schoffstall and other contributors +Copyright (c) 2013-2018 Blaine Bublitz , Eric Schoffstall and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/appveyor.yml b/appveyor.yml index e2d9fb3a..5020ef91 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ -# http://www.appveyor.com/docs/appveyor-yml -# http://www.appveyor.com/docs/lang/nodejs-iojs +# https://www.appveyor.com/docs/appveyor-yml +# https://www.appveyor.com/docs/lang/nodejs-iojs environment: matrix: diff --git a/docs/API.md b/docs/API.md index 5a9771bb..33f8bc60 100644 --- a/docs/API.md +++ b/docs/API.md @@ -834,9 +834,9 @@ module.exports = new MyCompanyTasksRegistry(); [gulp-if]: https://github.com/robrich/gulp-if [node-glob documentation]: https://github.com/isaacs/node-glob#options [node-glob]: https://github.com/isaacs/node-glob -[piped]: http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options +[piped]: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options [RxJS]: https://www.npmjs.com/package/rx -[stream]: http://nodejs.org/api/stream.html +[stream]: https://nodejs.org/api/stream.html [async-done]: https://www.npmjs.com/package/async-done [undertaker]: https://github.com/gulpjs/undertaker [vinyl File instance]: https://github.com/gulpjs/vinyl diff --git a/package.json b/package.json index b50db540..2d6db903 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "gulp", "version": "4.0.0", "description": "The streaming build system.", - "homepage": "http://gulpjs.com", - "author": "Gulp Team (http://gulpjs.com/)", + "homepage": "https://gulpjs.com", + "author": "Gulp Team (https://gulpjs.com/)", "contributors": [ "Eric Schoffstall ", "Blaine Bublitz " From 2cecf1ed4826cb6bc5314df338b0533565a34154 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 29 Jul 2018 15:50:47 -0700 Subject: [PATCH 105/225] Docs: Temporarily reference gulp@next in Quick Start --- docs/getting-started/1-quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/1-quick-start.md b/docs/getting-started/1-quick-start.md index b724e048..6294ecd6 100644 --- a/docs/getting-started/1-quick-start.md +++ b/docs/getting-started/1-quick-start.md @@ -48,7 +48,7 @@ This will guide you through giving your project a name, version, description, et ### Install the gulp package in your devDependencies ```sh -npm install --save-dev gulp +npm install --save-dev gulp@next ``` ### Verify your gulp versions From ad8a2f73c7d54635705255bf2e2b818a29ec0c8b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Aug 2018 16:43:33 -0700 Subject: [PATCH 106/225] Build: Remove jscs & update eslint for code formatting rules --- .jscsrc | 3 --- package.json | 8 +++----- 2 files changed, 3 insertions(+), 8 deletions(-) delete mode 100644 .jscsrc diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 703b33fc..00000000 --- a/.jscsrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "preset": "gulp" -} diff --git a/package.json b/package.json index 2d6db903..a4ce8bca 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "gulp": "./bin/gulp.js" }, "scripts": { - "lint": "eslint . && jscs index.js bin/ test/", + "lint": "eslint .", "pretest": "npm run lint", "test": "mocha --async-only", "cover": "istanbul cover _mocha --report lcovonly", @@ -36,13 +36,11 @@ "vinyl-fs": "^3.0.0" }, "devDependencies": { - "eslint": "^1.7.3", - "eslint-config-gulp": "^2.0.0", + "eslint": "^2.13.1", + "eslint-config-gulp": "^3.0.1", "expect": "^1.20.2", "istanbul": "^0.4.3", "istanbul-coveralls": "^1.0.3", - "jscs": "^2.3.5", - "jscs-preset-gulp": "^1.0.0", "mkdirp": "^0.5.1", "mocha": "^3.0.0", "rimraf": "^2.2.5" From a5eac1cff0bcb44683ba71d1e7db03c11dab8d3e Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Aug 2018 16:46:44 -0700 Subject: [PATCH 107/225] Build: Add node 10 to CI matrices --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index f621cabd..7e14b195 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ sudo: false language: node_js node_js: + - '10' - '8' - '6' - '4' diff --git a/appveyor.yml b/appveyor.yml index 5020ef91..d8845d71 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,7 @@ environment: - nodejs_version: "4" - nodejs_version: "6" - nodejs_version: "8" + - nodejs_version: "10" install: - ps: Install-Product node $env:nodejs_version From 49b5aca613b33c5b626ae68c03a385f25c142f55 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Aug 2018 16:58:32 -0700 Subject: [PATCH 108/225] Scaffold: Add tidelift configuration --- .tidelift.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .tidelift.yml diff --git a/.tidelift.yml b/.tidelift.yml new file mode 100644 index 00000000..3540e8ba --- /dev/null +++ b/.tidelift.yml @@ -0,0 +1,15 @@ +ci: + platform: + NPM: + # We use an older version that doesn't use ES6+ features to support back to node 0.10 + eslint: + tests: + outdated: skip + # We use an older version that doesn't use ES6+ features to support back to node 0.10 + expect: + tests: + outdated: skip + # We use an older version that doesn't use ES6+ features to support back to node 0.10 + mocha: + tests: + outdated: skip From 921312c32d4b42e9024d79f8f9afa3997220a078 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 18 Oct 2018 16:55:08 -0700 Subject: [PATCH 109/225] Docs: Use h2 headers within Quick Start documentation (#2241) --- docs/getting-started/1-quick-start.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/getting-started/1-quick-start.md b/docs/getting-started/1-quick-start.md index 6294ecd6..c3210274 100644 --- a/docs/getting-started/1-quick-start.md +++ b/docs/getting-started/1-quick-start.md @@ -9,7 +9,7 @@ sidebar_label: Quick Start If you've previously installed gulp globally, run `npm rm --global gulp` before following these instructions. For more information, read this [Sip][sip-article]. -### Check for node, npm, and npx +## Check for node, npm, and npx ```sh node --version ``` @@ -25,13 +25,13 @@ npx --version If they are not installed, follow the instructions [here][node-install]. -### Install the gulp command line utility +## Install the gulp command line utility ```sh npm install --global gulp-cli ``` -### Create a project directory and navigate into it +## Create a project directory and navigate into it ```sh npx mkdirp my-project ``` @@ -39,19 +39,19 @@ npx mkdirp my-project cd my-project ``` -### Create a package.json file in your project directory +## Create a package.json file in your project directory ```sh npm init ``` This will guide you through giving your project a name, version, description, etc. -### Install the gulp package in your devDependencies +## Install the gulp package in your devDependencies ```sh npm install --save-dev gulp@next ``` -### Verify your gulp versions +## Verify your gulp versions ```sh gulp --version @@ -61,7 +61,7 @@ Ensure the output matches the screenshot below or you might need to restart the ![Output: CLI version 2.0.1 & Local version 4.0.0][img-gulp-version-command] -### Create a gulpfile +## Create a gulpfile Using your text editor, create a file named gulpfile.js in your project root with these contents: ```js function defaultTask(cb) { @@ -72,14 +72,14 @@ function defaultTask(cb) { exports.default = defaultTask ``` -### Test it +## Test it Run the gulp command in your project directory: ```sh gulp ``` To run multiple tasks, you can use `gulp `. -### Result +## Result The default task will run and do nothing. ![Output: Starting default & Finished default][img-gulp-command] From 3d051d868313ee408614ae2c8ecc9b850b4b5f3d Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 18 Oct 2018 16:55:34 -0700 Subject: [PATCH 110/225] Docs: Fixed a capitalization typo in a heading (#2242) --- docs/getting-started/8-watching-files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/8-watching-files.md b/docs/getting-started/8-watching-files.md index 7c9199ed..82a16b33 100644 --- a/docs/getting-started/8-watching-files.md +++ b/docs/getting-started/8-watching-files.md @@ -35,7 +35,7 @@ watch('src/*.css', css); watch('src/*.js', series(clean, javascript)); ``` -## Warning: Avoid synchronous +## Warning: avoid synchronous A watcher's task cannot be synchronous, like tasks registered into the task system. If you pass a sync task, the completion can't be determined and the task won't run again - it is assumed to still be running. From 5c079544db5ac12c8efcb6560e1581f2339aadd9 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 Oct 2018 17:02:03 -0700 Subject: [PATCH 111/225] Docs: Remove temporary workaround for facebook/Docusaurus#257 --- docs/getting-started/3-creating-tasks.md | 2 +- docs/getting-started/5-working-with-files.md | 6 +++--- docs/getting-started/8-watching-files.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/3-creating-tasks.md b/docs/getting-started/3-creating-tasks.md index 48ea9ed6..5d784a5b 100644 --- a/docs/getting-started/3-creating-tasks.md +++ b/docs/getting-started/3-creating-tasks.md @@ -7,7 +7,7 @@ sidebar_label: Creating Tasks # Creating Tasks -Each gulp task is an asynchronous JavaScript function - a function that accepts an error-first callback or returns a stream, promise, event emitter, child process, or observable ([more on that later](4-async-completion.md)). Due to some platform limitations, synchronous tasks aren't supported, though there is a pretty nifty [alternative](4-async-completion.md#using-asyncawait). +Each gulp task is an asynchronous JavaScript function - a function that accepts an error-first callback or returns a stream, promise, event emitter, child process, or observable ([more on that later][async-completion-docs]). Due to some platform limitations, synchronous tasks aren't supported, though there is a pretty nifty [alternative][using-async-await-docs]. ## Exporting diff --git a/docs/getting-started/5-working-with-files.md b/docs/getting-started/5-working-with-files.md index 2e87d2e5..1f2e7af7 100644 --- a/docs/getting-started/5-working-with-files.md +++ b/docs/getting-started/5-working-with-files.md @@ -9,9 +9,9 @@ sidebar_label: Working with Files The `src()` and `dest()` methods are exposed by gulp to interact with files on your computer. -`src()` is given a [glob](6-explaining-globs.md) to read from the file system and produces a [Node stream][node-streams-docs]. It locates all matching files and reads them into memory to pass through the stream. +`src()` is given a [glob][explaining-globs-docs] to read from the file system and produces a [Node stream][node-streams-docs]. It locates all matching files and reads them into memory to pass through the stream. -The stream produced by `src()` should be returned from a task to signal async completion, as mentioned in [Creating Tasks](3-creating-tasks.md). +The stream produced by `src()` should be returned from a task to signal async completion, as mentioned in [Creating Tasks][creating-tasks-docs]. ```js const { src, dest } = require('gulp'); @@ -41,7 +41,7 @@ Most often plugins will be placed between `src()` and `dest()` using the `.pipe( ## Adding files to the stream -`src()` can also be placed in the middle of a pipeline to add files to the stream based on the given globs. The additional files will only be available to transformations later in the stream. If [globs overlap](6-explaining-globs.md#overlapping-globs), the files will be added again. +`src()` can also be placed in the middle of a pipeline to add files to the stream based on the given globs. The additional files will only be available to transformations later in the stream. If [globs overlap][overlapping-globs-docs], the files will be added again. This can be useful for transpiling some files before adding plain JavaScript files to the pipeline and uglifying everything. diff --git a/docs/getting-started/8-watching-files.md b/docs/getting-started/8-watching-files.md index 82a16b33..910fdbd4 100644 --- a/docs/getting-started/8-watching-files.md +++ b/docs/getting-started/8-watching-files.md @@ -7,7 +7,7 @@ sidebar_label: Watching Files # Watching Files -The `watch()` API connects [globs](6-explaining-globs.md) to [tasks](3-creating-tasks.md) using a file system watcher. It watches for changes to files that match the globs and executes the task when a change occurs. If the task doesn't signal [Async Completion](4-async-completion.md), it will never be run a second time. +The `watch()` API connects [globs][globs-docs] to [tasks][creating-tasks-docs] using a file system watcher. It watches for changes to files that match the globs and executes the task when a change occurs. If the task doesn't signal [Async Completion][async-completion-doc], it will never be run a second time. This API provides built-in delay and queueing based on most-common-use defaults. From c433c702fda288f7efd214ea348cc5b8423c67cd Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 Oct 2018 17:04:41 -0700 Subject: [PATCH 112/225] Docs: Replace some links in Getting Started --- docs/getting-started/3-creating-tasks.md | 4 ++-- docs/getting-started/5-working-with-files.md | 10 +++++----- docs/getting-started/8-watching-files.md | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/getting-started/3-creating-tasks.md b/docs/getting-started/3-creating-tasks.md index 5d784a5b..a1decb57 100644 --- a/docs/getting-started/3-creating-tasks.md +++ b/docs/getting-started/3-creating-tasks.md @@ -209,7 +209,7 @@ function javascript(cb) { exports.build = series(clean, parallel(css, javascript)); ``` -[async-completion-docs]: 4-async-completion.md -[using-async-await-docs]: 4-async-completion.md#using-asyncawait +[async-completion-docs]: ../getting-started/4-async-completion.md +[using-async-await-docs]: ../getting-started/4-async-completion.md#using-asyncawait [img-gulp-tasks-command]: https://gulpjs.com/img/docs-gulp-tasks-command.png [async-once]: https://github.com/gulpjs/async-once diff --git a/docs/getting-started/5-working-with-files.md b/docs/getting-started/5-working-with-files.md index 1f2e7af7..9ac33379 100644 --- a/docs/getting-started/5-working-with-files.md +++ b/docs/getting-started/5-working-with-files.md @@ -90,9 +90,9 @@ exports.default = function() { * Streaming mode exists mainly to operate on large files that can't fit in memory, like giant images or movies. The contents are streamed from the filesystem in small chunks instead of loaded all at once. If you need to use streaming mode, look for a plugin that supports it or write your own. * Empty mode contains no contents and is useful when only working with file metadata. -[explaining-globs-docs]: 6-explaining-globs.md -[creating-tasks-docs]: 3-creating-tasks.md -[overlapping-globs-docs]: 6-explaining-globs.md#overlapping-globs +[explaining-globs-docs]: ../getting-started/6-explaining-globs.md +[creating-tasks-docs]: ../getting-started/3-creating-tasks.md +[overlapping-globs-docs]: ../getting-started/6-explaining-globs.md#overlapping-globs [node-streams-docs]: https://nodejs.org/api/stream.html -[symlink-api-docs]: ../documentation-missing.md -[src-options-api-docs]: ../documentation-missing.md +[symlink-api-docs]: ../api/symlink.md +[src-options-api-docs]: ../api/src.md#options diff --git a/docs/getting-started/8-watching-files.md b/docs/getting-started/8-watching-files.md index 910fdbd4..9b8268eb 100644 --- a/docs/getting-started/8-watching-files.md +++ b/docs/getting-started/8-watching-files.md @@ -115,8 +115,8 @@ __Be careful:__ The returned chokidar instance doesn't have queueing, delay, or Gulp has an optional dependency called [fsevents][fsevents-package], which is a Mac-specific file watcher. If you see an installation warning for fsevents - _"npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents"_ - it is not an issue. If fsevents installation is skipped, a fallback watcher will be used and any errors occurring in your gulpfile aren't related to this warning. -[globs-docs]: 6-explaining-globs.md -[creating-tasks-docs]: 3-creating-tasks.md -[async-completion-doc]: 4-async-completion.md +[globs-docs]: ../getting-started/6-explaining-globs.md +[creating-tasks-docs]: ../getting-started/3-creating-tasks.md +[async-completion-doc]: ../getting-started/4-async-completion.md [chokidar-module-package]: https://www.npmjs.com/package/chokidar [fsevents-package]: https://www.npmjs.com/package/fsevents From af4bd514df869ee035b357c68c87437f96ed4616 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 Oct 2018 17:09:32 -0700 Subject: [PATCH 113/225] Docs: Fix hash link --- docs/getting-started/3-creating-tasks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/3-creating-tasks.md b/docs/getting-started/3-creating-tasks.md index a1decb57..79f64487 100644 --- a/docs/getting-started/3-creating-tasks.md +++ b/docs/getting-started/3-creating-tasks.md @@ -210,6 +210,6 @@ exports.build = series(clean, parallel(css, javascript)); ``` [async-completion-docs]: ../getting-started/4-async-completion.md -[using-async-await-docs]: ../getting-started/4-async-completion.md#using-asyncawait +[using-async-await-docs]: ../getting-started/4-async-completion.md#using-async-await [img-gulp-tasks-command]: https://gulpjs.com/img/docs-gulp-tasks-command.png [async-once]: https://github.com/gulpjs/async-once From a3b8ce130addedc01a7198942c6b1d96143d5e04 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 1 May 2018 11:01:34 -0700 Subject: [PATCH 114/225] Docs: Split API docs into separate markdown files --- docs/API.md | 845 ------------------------------------------- docs/README.md | 2 +- docs/api/README.md | 19 + docs/api/dest.md | 66 ++++ docs/api/lastRun.md | 43 +++ docs/api/parallel.md | 40 ++ docs/api/registry.md | 64 ++++ docs/api/series.md | 39 ++ docs/api/src.md | 139 +++++++ docs/api/symlink.md | 35 ++ docs/api/task.md | 194 ++++++++++ docs/api/tree.md | 155 ++++++++ docs/api/watch.md | 109 ++++++ 13 files changed, 904 insertions(+), 846 deletions(-) delete mode 100644 docs/API.md create mode 100644 docs/api/README.md create mode 100644 docs/api/dest.md create mode 100644 docs/api/lastRun.md create mode 100644 docs/api/parallel.md create mode 100644 docs/api/registry.md create mode 100644 docs/api/series.md create mode 100644 docs/api/src.md create mode 100644 docs/api/symlink.md create mode 100644 docs/api/task.md create mode 100644 docs/api/tree.md create mode 100644 docs/api/watch.md diff --git a/docs/API.md b/docs/API.md deleted file mode 100644 index 33f8bc60..00000000 --- a/docs/API.md +++ /dev/null @@ -1,845 +0,0 @@ - - -Note: these docs are for version v4.0.0 (aka `gulp@next`) If you're on gulp -v3.9.1, which is the current default `npm` release, you probably want [that -version's documentation](https://github.com/gulpjs/gulp/blob/v3.9.1/docs/API.md). - -## gulp API docs - -* [gulp.src](#gulpsrcglobs-options) - Emit files matching one or more globs -* [gulp.dest](#gulpdestpath-options) - Write files to directories -* [gulp.symlink](#gulpsymlinkfolder-options) - Write files to symlinks -* [gulp.task](#gulptaskname-fn) - Define tasks -* [gulp.lastRun](#gulplastruntaskname-timeresolution) - Get timestamp of last successful run -* [gulp.parallel](#gulpparalleltasks) - Run tasks in parallel -* [gulp.series](#gulpseriestasks) - Run tasks in series -* [gulp.watch](#gulpwatchglobs-opts-fn) - Do something when a file changes -* [gulp.tree](#gulptreeoptions) - Get the tree of tasks -* [gulp.registry](#gulpregistryregistry) - Get or set the task registry - -### gulp.src(globs[, options]) - -Emits files matching provided glob or array of globs. -Returns a [stream] of [Vinyl files] that can be [piped] to plugins. - -```javascript -gulp.src('client/templates/*.pug') - .pipe(pug()) - .pipe(minify()) - .pipe(gulp.dest('build/minified_templates')); -``` - -`glob` refers to [node-glob syntax][node-glob] or it can be a direct file path. - -#### globs -Type: `String` or `Array` - -Glob or array of globs to read. Globs use [node-glob syntax] except that negation is fully supported. - -A glob that begins with `!` excludes matching files from the glob results up to that point. For example, consider this directory structure: - - client/ - a.js - bob.js - bad.js - -The following expression matches `a.js` and `bad.js`: - - gulp.src(['client/*.js', '!client/b*.js', 'client/bad.js']) - - -Note that globs are evaluated in order, which means this is possible: - -```js -// exclude every JS file that starts with a b except bad.js -gulp.src(['*.js', '!b*.js', 'bad.js']) -``` - -**Note:** glob symlink following behavior is opt-in and you must specify -`follow: true` in the options object that is passed to [node-glob]. - -#### options -Type: `Object` - -Options to pass to [node-glob] through [glob-stream]. - -gulp adds some additional options in addition to the -[options supported by node-glob][node-glob documentation] and [glob-stream]: - -##### options.cwd - -The working directory the folder is relative to. - -Type: `String` - -Default: `process.cwd()` - - -##### options.buffer -Type: `Boolean` - -Default: `true` - -Setting this to `false` will return `file.contents` as a stream and not -buffer files. This is useful when working with large files. - -**Note:** Plugins might not implement support for streams. - -##### options.read -Type: `Boolean` - -Default: `true` - -Setting this to `false` will return `file.contents` as null and not read -the file at all. - -##### options.base -Type: `String` - -Default: everything before a glob starts (see [glob-parent]) - -E.g., consider `somefile.js` in `client/js/somedir`: - -```js -// Matches 'client/js/somedir/somefile.js' and resolves `base` to `client/js/` -gulp.src('client/js/**/*.js') - .pipe(minify()) - .pipe(gulp.dest('build')); // Writes 'build/somedir/somefile.js' - -gulp.src('client/js/**/*.js', { base: 'client' }) - .pipe(minify()) - .pipe(gulp.dest('build')); // Writes 'build/js/somedir/somefile.js' -``` - -##### options.since -Type: `Date` or `Number` - -Setting this to a Date or a time stamp will discard any file that have not been -modified since the time specified. - -##### options.passthrough -Type: `Boolean` - -Default: `false` - -If true, it will create a duplex stream which passes items through and -emits globbed files. - -##### options.allowEmpty -Type: `Boolean` - -Default: `false` - -When true, will allow singular globs to fail to match. Otherwise, globs which are only supposed to match one file (such as `./foo/bar.js`) will cause an error to be thrown if they don't match. - -```js -// Emits an error if app/scripts.js doesn't exist -gulp.src('app/scripts.js') - .pipe(...); - -// Won't emit an error -gulp.src('app/scripts.js', { allowEmpty: true }) - .pipe(...); -``` - - -### gulp.dest(path[, options]) - -Can be piped to and it will write files. Re-emits all data passed to it so you -can pipe to multiple folders. Folders that don't exist will be created. - -```javascript -gulp.src('./client/templates/*.pug') - .pipe(pug()) - .pipe(gulp.dest('./build/templates')) - .pipe(minify()) - .pipe(gulp.dest('./build/minified_templates')); -``` - -The write path is calculated by appending the file relative path to the given -destination directory. In turn, relative paths are calculated against -the file base. See `gulp.src` above for more info. - -#### path -Type: `String` or `Function` - -The path (output folder) to write files to. Or a function that returns it, -the function will be provided a [vinyl File instance]. - -#### options -Type: `Object` - -##### options.cwd -Type: `String` - -Default: `process.cwd()` - -`cwd` for the output folder, only has an effect if provided output folder is -relative. - -##### options.mode -Type: `String` or `Number` - -Default: the mode of the input file (file.stat.mode) or the process mode -if the input file has no mode property. - -Octal permission specifying the mode the files should be created with: e.g. -`"0744"`, `0744` or `484` (`0744` in base 10). - -##### options.dirMode -Type: `String` or `Number` - -Default: Default is the process mode. - -Octal permission specifying the mode the directory should be created with: e.g. -`"0755"`, `0755` or `493` (`0755` in base 10). - -##### options.overwrite -Type: `Boolean` - -Default: `true` - -Specify if existing files with the same path should be overwritten or not. - - -### gulp.symlink(folder[, options]) - -Functions exactly like `gulp.dest`, but will create symlinks instead of copying -a directory. - -#### folder -Type: `String` or `Function` - -A folder path or a function that receives in a file and returns a folder path. - -#### options -Type: `Object` - -##### options.cwd -Type: `String` - -Default: `process.cwd()` - -`cwd` for the output folder, only has an effect if provided output folder is -relative. - -##### options.dirMode -Type: `String` or `Number` - -Default: Default is the process mode. - -Octal permission specifying the mode the directory should be created with: e.g. -`"0755"`, `0755` or `493` (`0755` in base 10). - -### gulp.task([name,] fn) - -Define a task exposed to gulp-cli, `gulp.series`, `gulp.parallel` and -`gulp.lastRun`; inherited from [undertaker]. - -```js -gulp.task(function someTask() { - // Do stuff -}); -``` - -Or get a task that has been registered. - -```js -// someTask will be the registered task function -var someTask = gulp.task('someTask'); -``` - -#### name -Type: `String` - -If the name is not provided, the task will be named after the function -`name` or `displayName` property. The name argument is required if the -`name` and `displayName` properties of `fn` are empty. - -Since the task can be run from the command line, you should avoid using -spaces in task names. - -#### fn - -The function that performs the task's operations. Generally it takes this form: - -```js -function someTask() { - return gulp.src(['some/glob/**/*.ext']).pipe(someplugin()); -} -someTask.description = 'Does something'; - -gulp.task(someTask) -``` - -Gulp tasks are asynchronous and Gulp uses [async-done] to wait for the task's -completion. Tasks are called with a callback parameter to call to signal -completion. Alternatively, Task can return a stream, a promise, a child process -or a RxJS observable to signal the end of the task. - -**Warning:** Sync tasks are not supported and your function will never complete -if the one of the above strategies is not used to signal completion. However, -thrown errors will be caught by Gulp. - -#### fn properties - -##### fn.name - -`gulp.task` names the task after the function `name` property -if the optional `name` parameter of `gulp.task` is not provided. - -**Note:** [Function.name] is not writable; it cannot be set or edited. If -you need to assign a function name or use characters that aren't allowed -in function names, use the `displayName` property. -It will be empty for anonymous functions: - -```js -function foo() {}; -foo.name === 'foo' // true - -var bar = function() {}; -bar.name === '' // true - -bar.name = 'bar' -bar.name === '' // true -``` - -##### fn.displayName - -`gulp.task` names the task after the function `displayName` property -if function is anonymous and the optional `name` parameter of `gulp.task` -is not provided. - -##### fn.description - -gulp-cli prints this description alongside the task name when listing tasks: - -```js -var gulp = require('gulp'); - -function test(done){ - done(); -} -test.description = 'I do nothing'; - -gulp.task(test); -``` - -```sh -$> gulp --tasks -[12:00:02] Tasks for ~/Documents/some-project/gulpfile.js -[12:00:02] └── test I do nothing -``` - -#### Async support - -##### Accept a callback - -```js -var del = require('del'); - -gulp.task('clean', function(done) { - del(['.build/'], done); -}); - -// use an async result in a pipe -gulp.task('somename', function(cb) { - getFilesAsync(function(err, res) { - if (err) return cb(err); - var stream = gulp.src(res) - .pipe(minify()) - .pipe(gulp.dest('build')) - .on('end', cb); - }); -}); -``` - -The callback accepts an optional `Error` object. If it receives an error, -the task will fail. - -##### Return a stream - -```js -gulp.task('somename', function() { - return gulp.src('client/**/*.js') - .pipe(minify()) - .pipe(gulp.dest('build')); -}); -``` - -##### Return a promise - -```js -var Promise = require('promise'); -var del = require('del'); - -gulp.task('clean', function() { - return new Promise(function (resolve, reject) { - del(['.build/'], function(err) { - if (err) { - reject(err); - } else { - resolve(); - } - }); - }); -}); -``` - -or: -```js -var promisedDel = require('promised-del'); - -gulp.task('clean', function() { - return promisedDel(['.build/']); -}); -``` - -##### Return a child process - -```js -gulp.task('clean', function() { - return spawn('rm', ['-rf', path.join(__dirname, 'build')]); -}); - -``` - -##### Return a [RxJS] observable - -```js -var Observable = require('rx').Observable; - -gulp.task('sometask', function() { - return Observable.return(42); -}); -``` - - -### gulp.lastRun(taskName, [timeResolution]) - -Returns the timestamp of the last time the task ran successfully. The time -will be the time the task started. Returns `undefined` if the task has -not run yet. - -#### taskName - -Type: `String` - -The name of the registered task or of a function. - -#### timeResolution - -Type: `Number`. - -Default: `1000` on node v0.10, `0` on node v0.12 (and iojs v1.5). - -Set the time resolution of the returned timestamps. Assuming -the task named "someTask" ran at `1426000004321`: - -- `gulp.lastRun('someTask', 1000)` would return `1426000004000`. -- `gulp.lastRun('someTask', 100)` would return `1426000004300`. - -`timeResolution` allows you to compare a run time to a file [mtime stat][fs stats] -attribute. This attribute time resolution may vary depending of the node version -and the file system used: - -- on node v0.10, a file [mtime stat][fs stats] time resolution of any files will be 1s at best; -- on node v0.12 and iojs v1.5, 1ms at best; -- for files on FAT32, the mtime time resolution is 2s; -- on HFS+ and Ext3, 1s; -- on NTFS, 1s on node v0.10, 100ms on node 0.12; -- on Ext4, 1s on node v0.10, 1ms on node 0.12. - - -### gulp.parallel(...tasks) - -Takes a number of task names or functions and returns a function of the composed -tasks or functions. - -When using task names, the task should already be registered. - -When the returned function is executed, the tasks or functions will be executed -in parallel, all being executed at the same time. If an error occurs, -all execution will complete. - -```js -gulp.task('one', function(done) { - // do stuff - done(); -}); - -gulp.task('two', function(done) { - // do stuff - done(); -}); - -gulp.task('default', gulp.parallel('one', 'two', function(done) { - // do more stuff - done(); -})); -``` - -#### tasks -Type: `Array`, `String` or `Function` - -A task name, a function or an array of either. - - -### gulp.series(...tasks) - -Takes a number of task names or functions and returns a function of the composed -tasks or functions. - -When using task names, the task should already be registered. - -When the returned function is executed, the tasks or functions will be executed -in series, each waiting for the prior to finish. If an error occurs, -execution will stop. - -```js -gulp.task('one', function(done) { - // do stuff - done(); -}); - -gulp.task('two', function(done) { - // do stuff - done(); -}); - -gulp.task('default', gulp.series('one', 'two', function(done) { - // do more stuff - done(); -})); -``` - -#### tasks -Type: `Array`, `String` or `Function` - -A task name, a function or an array of either. - - -### gulp.watch(globs[, opts][, fn]) - -Takes a path string, an array of path strings, a [glob][node-glob] string or an array of [glob][node-glob] strings as `globs` to watch on the filesystem. Also optionally takes `options` to configure the watcher and a `fn` to execute when a file changes. - -Returns an instance of [`chokidar`][chokidar]. - -```js -gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify')); -``` - -In the example, `gulp.watch` runs the function returned by `gulp.parallel` each -time a file with the `js` extension in `js/` is updated. - -#### globs -Type: `String` or `Array` - -A path string, an array of path strings, a [glob][node-glob] string or an array of [glob][node-glob] strings that indicate which files to watch for changes. - -#### opts -Type: `Object` - -* `delay` (milliseconds, default: `200`). The delay to wait before triggering the fn. Useful for waiting on many changes before doing the work on changed files, e.g. find-and-replace on many files. -* `queue` (boolean, default: `true`). Whether or not a file change should queue the fn execution if the fn is already running. Useful for a long running fn. -* `ignoreInitial` (boolean, default: `true`). If set to `false` the `fn` is called during [chokidar][chokidar] instantiation as it discovers the file paths. Useful if it is desirable to trigger the `fn` during startup. __Passed through to [chokidar][chokidar], but defaulted to `true` instead of `false`.__ - -Options that are passed to [`chokidar`][chokidar]. - -Commonly used options: - -* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition). -Defines files/paths to be excluded from being watched. -* `usePolling` (boolean, default: `false`). When `true` uses a watch method backed -by stat polling. Usually necessary when watching files on a network mount or on a -VMs file system. -* `cwd` (path string). The base directory from which watch paths are to be -derived. Paths emitted with events will be relative to this. -* `alwaysStat` (boolean, default: `false`). If relying upon the -[`fs.Stats`][fs stats] object -that may get passed as a second argument with `add`, `addDir`, and `change` events -when available, set this to `true` to ensure it is provided with every event. May -have a slight performance penalty. - -Read about the full set of options in [`chokidar`'s README][chokidar]. - -#### fn -Type: `Function` - -If the `fn` is passed, it will be called when the watcher emits a `change`, `add` or `unlink` event. It is automatically debounced with a default delay of 200 milliseconds and subsequent calls will be queued and called upon completion. These defaults can be changed using the `options`. - -The `fn` is passed a single argument, `callback`, which is a function that must be called when work in the `fn` is complete. Instead of calling the `callback` function, [async completion][async-completion] can be signalled by: - * Returning a `Stream` or `EventEmitter` - * Returning a `Child Process` - * Returning a `Promise` - * Returning an `Observable` - -Once async completion is signalled, if another run is queued, it will be executed. - -`gulp.watch` returns a wrapped [chokidar] FSWatcher object. Listeners can also be set directly for any of [chokidar]'s events, such as `addDir`, `unlinkDir`, and `error`. You must set listeners directly to get -access to chokidar's callback parameters, such as `path`. - -```js -var watcher = gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify')); -watcher.on('change', function(path, stats) { - console.log('File ' + path + ' was changed'); -}); - -watcher.on('unlink', function(path) { - console.log('File ' + path + ' was removed'); -}); -``` - -##### path -Type: `String` - -Path to the file. If `opts.cwd` is set, `path` is relative to it. - -##### stats -Type: `Object` - -[File stats][fs stats] object when available. -Setting the `alwaysStat` option to `true` will ensure that a file stat object will be -provided. - -#### watcher methods - -##### watcher.close() - -Shuts down the file watcher. - -##### watcher.add(glob) - -Watch additional glob (or array of globs) with an already-running watcher instance. - -##### watcher.unwatch(glob) - -Stop watching a glob (or array of globs) while leaving the watcher running and -emitting events for the remaining paths it is watching. - - -### gulp.tree(options) - -Returns the tree of tasks. Inherited from [undertaker]. See the [undertaker docs for this function](https://github.com/phated/undertaker#treeoptions--object). - -#### options -Type: `Object` - -Options to pass to [undertaker]. - -##### options.deep -Type: `Boolean` - -Default: `false` - -If set to `true` whole tree should be returned. - -#### Example gulpfile - -```js -gulp.task('one', function(done) { - // do stuff - done(); -}); - -gulp.task('two', function(done) { - // do stuff - done(); -}); - -gulp.task('three', function(done) { - // do stuff - done(); -}); - -gulp.task('four', gulp.series('one', 'two')); - -gulp.task('five', - gulp.series('four', - gulp.parallel('three', function(done) { - // do more stuff - done(); - }) - ) -); -``` - -#### Example tree output - -```js -gulp.tree() - -// output: [ 'one', 'two', 'three', 'four', 'five' ] - -gulp.tree({ deep: true }) - -/*output: [ - { - "label":"one", - "type":"task", - "nodes":[] - }, - { - "label":"two", - "type":"task", - "nodes":[] - }, - { - "label":"three", - "type":"task", - "nodes":[] - }, - { - "label":"four", - "type":"task", - "nodes":[ - { - "label":"", - "type":"function", - "nodes":[ - { - "label":"one", - "type":"task", - "nodes":[] - }, - { - "label":"two", - "type":"task", - "nodes":[] - } - ] - } - ] - }, - { - "label":"five", - "type":"task", - "nodes":[ - { - "label":"", - "type":"function", - "nodes":[ - { - "label":"four", - "type":"task", - "nodes":[ - { - "label":"", - "type":"function", - "nodes":[ - { - "label":"one", - "type":"task", - "nodes":[] - }, - { - "label":"two", - "type":"task", - "nodes":[] - } - ] - } - ] - }, - { - "label":"", - "type":"function", - "nodes":[ - { - "label":"three", - "type":"task", - "nodes":[] - }, - { - "label":"", - "type":"function", - "nodes":[] - } - ] - } - ] - } - ] - } -] -*/ -``` - - -### gulp.registry([registry]) - -Get or set the underlying task registry. Inherited from [undertaker]; see the undertaker documention on [registries](https://github.com/phated/undertaker#registryregistryinstance). Using this, you can change registries that enhance gulp in different ways. Utilizing a custom registry has at least three use cases: - -- [Sharing tasks](https://github.com/phated/undertaker#sharing-tasks) -- [Sharing functionality](https://github.com/phated/undertaker#sharing-functionalities) (e.g. you could override the task prototype to add some additional logging, bind task metadata or include some config settings.) -- Handling other behavior that hooks into the registry lifecycle (see [gulp-hub](https://github.com/frankwallis/gulp-hub) for an example) - -To build your own custom registry see the [undertaker documentation on custom registries](https://github.com/phated/undertaker#custom-registries). - -#### registry - -A registry instance. When passed in, the tasks from the current registry will be transferred to the new registry and then current registry will be replaced with the new registry. - -#### Example - -This example shows how to create and use a simple custom registry to add tasks. - -```js -//gulpfile.js -var gulp = require('gulp'); - -var companyTasks = require('./myCompanyTasksRegistry.js'); - -gulp.registry(companyTasks); - -gulp.task('one', gulp.parallel('someCompanyTask', function(done) { - console.log('in task one'); - done(); -})); -``` - -```js -//myCompanyTasksRegistry.js -var util = require('util'); - -var DefaultRegistry = require('undertaker-registry'); - -function MyCompanyTasksRegistry() { - DefaultRegistry.call(this); -} -util.inherits(MyCompanyTasksRegistry, DefaultRegistry); - -MyCompanyTasksRegistry.prototype.init = function(gulp) { - gulp.task('clean', function(done) { - done(); - }); - gulp.task('someCompanyTask', function(done) { - console.log('performing some company task.'); - done(); - }); -}; - -module.exports = new MyCompanyTasksRegistry(); -``` - -[Function.name]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name -[chokidar]: https://github.com/paulmillr/chokidar -[glob-stream]: https://github.com/gulpjs/glob-stream -[glob-parent]: https://github.com/es128/glob-parent -[gulp-if]: https://github.com/robrich/gulp-if -[node-glob documentation]: https://github.com/isaacs/node-glob#options -[node-glob]: https://github.com/isaacs/node-glob -[piped]: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options -[RxJS]: https://www.npmjs.com/package/rx -[stream]: https://nodejs.org/api/stream.html -[async-done]: https://www.npmjs.com/package/async-done -[undertaker]: https://github.com/gulpjs/undertaker -[vinyl File instance]: https://github.com/gulpjs/vinyl -[Vinyl files]: https://github.com/gulpjs/vinyl-fs -[fs stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats -[async-completion]: https://github.com/gulpjs/async-done#completion-and-error-resolution diff --git a/docs/README.md b/docs/README.md index f90cabc9..c783b710 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,7 +8,7 @@ sidebar_label: Docs # gulp documentation * [Getting Started](getting-started/) - Get started with gulp -* [API documentation](API.md) - The programming interface, defined +* [API documentation](api/) - The programming interface, defined * [CLI documentation](CLI.md) - Learn how to call tasks and use compilers * [Writing a Plugin](writing-a-plugin/) - The essentials of writing a gulp plugin * [Why Use Pump?](why-use-pump/README.md) - Why to use the `pump` module instead of calling `.pipe` yourself diff --git a/docs/api/README.md b/docs/api/README.md new file mode 100644 index 00000000..387e2787 --- /dev/null +++ b/docs/api/README.md @@ -0,0 +1,19 @@ + + +## gulp API docs + +* [gulp.src](src.md) - Emit files matching one or more globs +* [gulp.dest](dest.md) - Write files to directories +* [gulp.symlink](symlink.md) - Write files to symlinks +* [gulp.task](task.md) - Define tasks +* [gulp.lastRun](lastRun.md) - Get timestamp of last successful run +* [gulp.parallel](parallel.md) - Run tasks in parallel +* [gulp.series](series.md) - Run tasks in series +* [gulp.watch](watch.md) - Do something when a file changes +* [gulp.tree](tree.md) - Get the tree of tasks +* [gulp.registry](registry.md) - Get or set the task registry diff --git a/docs/api/dest.md b/docs/api/dest.md new file mode 100644 index 00000000..a9b909b7 --- /dev/null +++ b/docs/api/dest.md @@ -0,0 +1,66 @@ + + +# `gulp.dest(path[, options])` + +Can be piped to and it will write files. Re-emits all data passed to it so you +can pipe to multiple folders. Folders that don't exist will be created. + +```javascript +gulp.src('./client/templates/*.pug') + .pipe(pug()) + .pipe(gulp.dest('./build/templates')) + .pipe(minify()) + .pipe(gulp.dest('./build/minified_templates')); +``` + +The write path is calculated by appending the file relative path to the given +destination directory. In turn, relative paths are calculated against +the file base. See `gulp.src` above for more info. + +## path +Type: `String` or `Function` + +The path (output folder) to write files to. Or a function that returns it, +the function will be provided a [vinyl File instance]. + +## options +Type: `Object` + +### options.cwd +Type: `String` + +Default: `process.cwd()` + +`cwd` for the output folder, only has an effect if provided output folder is +relative. + +### options.mode +Type: `String` or `Number` + +Default: the mode of the input file (file.stat.mode) or the process mode +if the input file has no mode property. + +Octal permission specifying the mode the files should be created with: e.g. +`"0744"`, `0744` or `484` (`0744` in base 10). + +### options.dirMode +Type: `String` or `Number` + +Default: Default is the process mode. + +Octal permission specifying the mode the directory should be created with: e.g. +`"0755"`, `0755` or `493` (`0755` in base 10). + +### options.overwrite +Type: `Boolean` + +Default: `true` + +Specify if existing files with the same path should be overwritten or not. + +[vinyl File instance]: https://github.com/gulpjs/vinyl diff --git a/docs/api/lastRun.md b/docs/api/lastRun.md new file mode 100644 index 00000000..2be1e668 --- /dev/null +++ b/docs/api/lastRun.md @@ -0,0 +1,43 @@ + + +# `gulp.lastRun(taskName, [timeResolution])` + +Returns the timestamp of the last time the task ran successfully. The time +will be the time the task started. Returns `undefined` if the task has +not run yet. + +## taskName + +Type: `String` + +The name of the registered task or of a function. + +## timeResolution + +Type: `Number`. + +Default: `1000` on node v0.10, `0` on node v0.12 (and iojs v1.5). + +Set the time resolution of the returned timestamps. Assuming +the task named "someTask" ran at `1426000004321`: + +- `gulp.lastRun('someTask', 1000)` would return `1426000004000`. +- `gulp.lastRun('someTask', 100)` would return `1426000004300`. + +`timeResolution` allows you to compare a run time to a file [mtime stat][fs stats] +attribute. This attribute time resolution may vary depending of the node version +and the file system used: + +- on node v0.10, a file [mtime stat][fs stats] time resolution of any files will be 1s at best; +- on node v0.12 and iojs v1.5, 1ms at best; +- for files on FAT32, the mtime time resolution is 2s; +- on HFS+ and Ext3, 1s; +- on NTFS, 1s on node v0.10, 100ms on node 0.12; +- on Ext4, 1s on node v0.10, 1ms on node 0.12. + +[fs stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats diff --git a/docs/api/parallel.md b/docs/api/parallel.md new file mode 100644 index 00000000..7d15efbb --- /dev/null +++ b/docs/api/parallel.md @@ -0,0 +1,40 @@ + + +# `gulp.parallel(...tasks)` + +Takes a number of task names or functions and returns a function of the composed +tasks or functions. + +When using task names, the task should already be registered. + +When the returned function is executed, the tasks or functions will be executed +in parallel, all being executed at the same time. If an error occurs, +all execution will complete. + +```js +gulp.task('one', function(done) { + // do stuff + done(); +}); + +gulp.task('two', function(done) { + // do stuff + done(); +}); + +gulp.task('default', gulp.parallel('one', 'two', function(done) { + // do more stuff + done(); +})); +``` + +## tasks +Type: `Array`, `String` or `Function` + +A task name, a function or an array of either. + diff --git a/docs/api/registry.md b/docs/api/registry.md new file mode 100644 index 00000000..2b04e9f8 --- /dev/null +++ b/docs/api/registry.md @@ -0,0 +1,64 @@ + + +# `gulp.registry([registry])` + +Get or set the underlying task registry. Inherited from [undertaker]; see the undertaker documention on [registries](https://github.com/phated/undertaker#registryregistryinstance). Using this, you can change registries that enhance gulp in different ways. Utilizing a custom registry has at least three use cases: + +- [Sharing tasks](https://github.com/phated/undertaker#sharing-tasks) +- [Sharing functionality](https://github.com/phated/undertaker#sharing-functionalities) (e.g. you could override the task prototype to add some additional logging, bind task metadata or include some config settings.) +- Handling other behavior that hooks into the registry lifecycle (see [gulp-hub](https://github.com/frankwallis/gulp-hub) for an example) + +To build your own custom registry see the [undertaker documentation on custom registries](https://github.com/phated/undertaker#custom-registries). + +## registry + +A registry instance. When passed in, the tasks from the current registry will be transferred to the new registry and then current registry will be replaced with the new registry. + +## Example + +This example shows how to create and use a simple custom registry to add tasks. + +```js +//gulpfile.js +var gulp = require('gulp'); + +var companyTasks = require('./myCompanyTasksRegistry.js'); + +gulp.registry(companyTasks); + +gulp.task('one', gulp.parallel('someCompanyTask', function(done) { + console.log('in task one'); + done(); +})); +``` + +```js +//myCompanyTasksRegistry.js +var util = require('util'); + +var DefaultRegistry = require('undertaker-registry'); + +function MyCompanyTasksRegistry() { + DefaultRegistry.call(this); +} +util.inherits(MyCompanyTasksRegistry, DefaultRegistry); + +MyCompanyTasksRegistry.prototype.init = function(gulp) { + gulp.task('clean', function(done) { + done(); + }); + gulp.task('someCompanyTask', function(done) { + console.log('performing some company task.'); + done(); + }); +}; + +module.exports = new MyCompanyTasksRegistry(); +``` + +[undertaker]: https://github.com/gulpjs/undertaker diff --git a/docs/api/series.md b/docs/api/series.md new file mode 100644 index 00000000..9499ed42 --- /dev/null +++ b/docs/api/series.md @@ -0,0 +1,39 @@ + + +# `gulp.series(...tasks)` + +Takes a number of task names or functions and returns a function of the composed +tasks or functions. + +When using task names, the task should already be registered. + +When the returned function is executed, the tasks or functions will be executed +in series, each waiting for the prior to finish. If an error occurs, +execution will stop. + +```js +gulp.task('one', function(done) { + // do stuff + done(); +}); + +gulp.task('two', function(done) { + // do stuff + done(); +}); + +gulp.task('default', gulp.series('one', 'two', function(done) { + // do more stuff + done(); +})); +``` + +## tasks +Type: `Array`, `String` or `Function` + +A task name, a function or an array of either. diff --git a/docs/api/src.md b/docs/api/src.md new file mode 100644 index 00000000..307d9ab6 --- /dev/null +++ b/docs/api/src.md @@ -0,0 +1,139 @@ + + +# `gulp.src(globs[, options])` + +Emits files matching provided glob or array of globs. +Returns a [stream] of [Vinyl files] that can be [piped] to plugins. + +```javascript +gulp.src('client/templates/*.pug') + .pipe(pug()) + .pipe(minify()) + .pipe(gulp.dest('build/minified_templates')); +``` + +`glob` refers to [node-glob syntax][node-glob] or it can be a direct file path. + +## globs +Type: `String` or `Array` + +Glob or array of globs to read. Globs use [node-glob syntax] except that negation is fully supported. + +A glob that begins with `!` excludes matching files from the glob results up to that point. For example, consider this directory structure: + + client/ + a.js + bob.js + bad.js + +The following expression matches `a.js` and `bad.js`: + + gulp.src(['client/*.js', '!client/b*.js', 'client/bad.js']) + + +Note that globs are evaluated in order, which means this is possible: + +```js +// exclude every JS file that starts with a b except bad.js +gulp.src(['*.js', '!b*.js', 'bad.js']) +``` + +**Note:** glob symlink following behavior is opt-in and you must specify +`follow: true` in the options object that is passed to [node-glob]. + +## options +Type: `Object` + +Options to pass to [node-glob] through [glob-stream]. + +gulp adds some additional options in addition to the +[options supported by node-glob][node-glob documentation] and [glob-stream]: + +### options.cwd + +The working directory the folder is relative to. + +Type: `String` + +Default: `process.cwd()` + + +### options.buffer +Type: `Boolean` + +Default: `true` + +Setting this to `false` will return `file.contents` as a stream and not +buffer files. This is useful when working with large files. + +**Note:** Plugins might not implement support for streams. + +### options.read +Type: `Boolean` + +Default: `true` + +Setting this to `false` will return `file.contents` as null and not read +the file at all. + +### options.base +Type: `String` + +Default: everything before a glob starts (see [glob-parent]) + +E.g., consider `somefile.js` in `client/js/somedir`: + +```js +// Matches 'client/js/somedir/somefile.js' and resolves `base` to `client/js/` +gulp.src('client/js/**/*.js') + .pipe(minify()) + .pipe(gulp.dest('build')); // Writes 'build/somedir/somefile.js' + +gulp.src('client/js/**/*.js', { base: 'client' }) + .pipe(minify()) + .pipe(gulp.dest('build')); // Writes 'build/js/somedir/somefile.js' +``` + +### options.since +Type: `Date` or `Number` + +Setting this to a Date or a time stamp will discard any file that have not been +modified since the time specified. + +### options.passthrough +Type: `Boolean` + +Default: `false` + +If true, it will create a duplex stream which passes items through and +emits globbed files. + +### options.allowEmpty +Type: `Boolean` + +Default: `false` + +When true, will allow singular globs to fail to match. Otherwise, globs which are only supposed to match one file (such as `./foo/bar.js`) will cause an error to be thrown if they don't match. + +```js +// Emits an error if app/scripts.js doesn't exist +gulp.src('app/scripts.js') + .pipe(...); + +// Won't emit an error +gulp.src('app/scripts.js', { allowEmpty: true }) + .pipe(...); +``` + +[glob-stream]: https://github.com/gulpjs/glob-stream +[glob-parent]: https://github.com/es128/glob-parent +[node-glob documentation]: https://github.com/isaacs/node-glob#options +[node-glob]: https://github.com/isaacs/node-glob +[piped]: http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options +[stream]: http://nodejs.org/api/stream.html +[Vinyl files]: https://github.com/gulpjs/vinyl-fs diff --git a/docs/api/symlink.md b/docs/api/symlink.md new file mode 100644 index 00000000..f8b00f0c --- /dev/null +++ b/docs/api/symlink.md @@ -0,0 +1,35 @@ + + +# `gulp.symlink(folder[, options])` + +Functions exactly like `gulp.dest`, but will create symlinks instead of copying +a directory. + +## folder +Type: `String` or `Function` + +A folder path or a function that receives in a file and returns a folder path. + +## options +Type: `Object` + +### options.cwd +Type: `String` + +Default: `process.cwd()` + +`cwd` for the output folder, only has an effect if provided output folder is +relative. + +### options.dirMode +Type: `String` or `Number` + +Default: Default is the process mode. + +Octal permission specifying the mode the directory should be created with: e.g. +`"0755"`, `0755` or `493` (`0755` in base 10). diff --git a/docs/api/task.md b/docs/api/task.md new file mode 100644 index 00000000..b644de60 --- /dev/null +++ b/docs/api/task.md @@ -0,0 +1,194 @@ + + +# `gulp.task([name,] fn)` + +Define a task exposed to gulp-cli, `gulp.series`, `gulp.parallel` and +`gulp.lastRun`; inherited from [undertaker]. + +```js +gulp.task(function someTask() { + // Do stuff +}); +``` + +Or get a task that has been registered. + +```js +// someTask will be the registered task function +var someTask = gulp.task('someTask'); +``` + +## name +Type: `String` + +If the name is not provided, the task will be named after the function +`name` or `displayName` property. The name argument is required if the +`name` and `displayName` properties of `fn` are empty. + +Since the task can be run from the command line, you should avoid using +spaces in task names. + +## fn + +The function that performs the task's operations. Generally it takes this form: + +```js +function someTask() { + return gulp.src(['some/glob/**/*.ext']).pipe(someplugin()); +} +someTask.description = 'Does something'; + +gulp.task(someTask) +``` + +Gulp tasks are asynchronous and Gulp uses [async-done] to wait for the task's +completion. Tasks are called with a callback parameter to call to signal +completion. Alternatively, Task can return a stream, a promise, a child process +or a RxJS observable to signal the end of the task. + +**Warning:** Sync tasks are not supported and your function will never complete +if the one of the above strategies is not used to signal completion. However, +thrown errors will be caught by Gulp. + +## fn properties + +### fn.name + +`gulp.task` names the task after the function `name` property +if the optional `name` parameter of `gulp.task` is not provided. + +**Note:** [Function.name] is not writable; it cannot be set or edited. If +you need to assign a function name or use characters that aren't allowed +in function names, use the `displayName` property. +It will be empty for anonymous functions: + +```js +function foo() {}; +foo.name === 'foo' // true + +var bar = function() {}; +bar.name === '' // true + +bar.name = 'bar' +bar.name === '' // true +``` + +### fn.displayName + +`gulp.task` names the task after the function `displayName` property +if function is anonymous and the optional `name` parameter of `gulp.task` +is not provided. + +### fn.description + +gulp-cli prints this description alongside the task name when listing tasks: + +```js +var gulp = require('gulp'); + +function test(done){ + done(); +} +test.description = 'I do nothing'; + +gulp.task(test); +``` + +```sh +$> gulp --tasks +[12:00:02] Tasks for ~/Documents/some-project/gulpfile.js +[12:00:02] └── test I do nothing +``` + +## Async support + +### Accept a callback + +```js +var del = require('del'); + +gulp.task('clean', function(done) { + del(['.build/'], done); +}); + +// use an async result in a pipe +gulp.task('somename', function(cb) { + getFilesAsync(function(err, res) { + if (err) return cb(err); + var stream = gulp.src(res) + .pipe(minify()) + .pipe(gulp.dest('build')) + .on('end', cb); + }); +}); +``` + +The callback accepts an optional `Error` object. If it receives an error, +the task will fail. + +### Return a stream + +```js +gulp.task('somename', function() { + return gulp.src('client/**/*.js') + .pipe(minify()) + .pipe(gulp.dest('build')); +}); +``` + +### Return a promise + +```js +var Promise = require('promise'); +var del = require('del'); + +gulp.task('clean', function() { + return new Promise(function (resolve, reject) { + del(['.build/'], function(err) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); +}); +``` + +or: +```js +var promisedDel = require('promised-del'); + +gulp.task('clean', function() { + return promisedDel(['.build/']); +}); +``` + +### Return a child process + +```js +gulp.task('clean', function() { + return spawn('rm', ['-rf', path.join(__dirname, 'build')]); +}); + +``` + +### Return a [RxJS] observable + +```js +var Observable = require('rx').Observable; + +gulp.task('sometask', function() { + return Observable.return(42); +}); +``` + +[Function.name]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name +[RxJS]: https://www.npmjs.com/package/rx +[async-done]: https://www.npmjs.com/package/async-done +[undertaker]: https://github.com/gulpjs/undertaker diff --git a/docs/api/tree.md b/docs/api/tree.md new file mode 100644 index 00000000..e7e43f1b --- /dev/null +++ b/docs/api/tree.md @@ -0,0 +1,155 @@ + + +# `gulp.tree(options)` + +Returns the tree of tasks. Inherited from [undertaker]. See the [undertaker docs for this function](https://github.com/phated/undertaker#treeoptions--object). + +## options +Type: `Object` + +Options to pass to [undertaker]. + +### options.deep +Type: `Boolean` + +Default: `false` + +If set to `true` whole tree should be returned. + +## Example gulpfile + +```js +gulp.task('one', function(done) { + // do stuff + done(); +}); + +gulp.task('two', function(done) { + // do stuff + done(); +}); + +gulp.task('three', function(done) { + // do stuff + done(); +}); + +gulp.task('four', gulp.series('one', 'two')); + +gulp.task('five', + gulp.series('four', + gulp.parallel('three', function(done) { + // do more stuff + done(); + }) + ) +); +``` + +## Example tree output + +```js +gulp.tree() + +// output: [ 'one', 'two', 'three', 'four', 'five' ] + +gulp.tree({ deep: true }) + +/*output: [ + { + "label":"one", + "type":"task", + "nodes":[] + }, + { + "label":"two", + "type":"task", + "nodes":[] + }, + { + "label":"three", + "type":"task", + "nodes":[] + }, + { + "label":"four", + "type":"task", + "nodes":[ + { + "label":"", + "type":"function", + "nodes":[ + { + "label":"one", + "type":"task", + "nodes":[] + }, + { + "label":"two", + "type":"task", + "nodes":[] + } + ] + } + ] + }, + { + "label":"five", + "type":"task", + "nodes":[ + { + "label":"", + "type":"function", + "nodes":[ + { + "label":"four", + "type":"task", + "nodes":[ + { + "label":"", + "type":"function", + "nodes":[ + { + "label":"one", + "type":"task", + "nodes":[] + }, + { + "label":"two", + "type":"task", + "nodes":[] + } + ] + } + ] + }, + { + "label":"", + "type":"function", + "nodes":[ + { + "label":"three", + "type":"task", + "nodes":[] + }, + { + "label":"", + "type":"function", + "nodes":[] + } + ] + } + ] + } + ] + } +] +*/ +``` + +[undertaker]: https://github.com/gulpjs/undertaker diff --git a/docs/api/watch.md b/docs/api/watch.md new file mode 100644 index 00000000..002d7a1d --- /dev/null +++ b/docs/api/watch.md @@ -0,0 +1,109 @@ + + +# `gulp.watch(globs[, opts][, fn])` + +Takes a path string, an array of path strings, a [glob][node-glob] string or an array of [glob][node-glob] strings as `globs` to watch on the filesystem. Also optionally takes `options` to configure the watcher and a `fn` to execute when a file changes. + +Returns an instance of [`chokidar`][chokidar]. + +```js +gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify')); +``` + +In the example, `gulp.watch` runs the function returned by `gulp.parallel` each +time a file with the `js` extension in `js/` is updated. + +## globs +Type: `String` or `Array` + +A path string, an array of path strings, a [glob][node-glob] string or an array of [glob][node-glob] strings that indicate which files to watch for changes. + +## opts +Type: `Object` + +* `delay` (milliseconds, default: `200`). The delay to wait before triggering the fn. Useful for waiting on many changes before doing the work on changed files, e.g. find-and-replace on many files. +* `queue` (boolean, default: `true`). Whether or not a file change should queue the fn execution if the fn is already running. Useful for a long running fn. +* `ignoreInitial` (boolean, default: `true`). If set to `false` the `fn` is called during [chokidar][chokidar] instantiation as it discovers the file paths. Useful if it is desirable to trigger the `fn` during startup. __Passed through to [chokidar][chokidar], but defaulted to `true` instead of `false`.__ + +Options that are passed to [`chokidar`][chokidar]. + +Commonly used options: + +* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition). +Defines files/paths to be excluded from being watched. +* `usePolling` (boolean, default: `false`). When `true` uses a watch method backed +by stat polling. Usually necessary when watching files on a network mount or on a +VMs file system. +* `cwd` (path string). The base directory from which watch paths are to be +derived. Paths emitted with events will be relative to this. +* `alwaysStat` (boolean, default: `false`). If relying upon the +[`fs.Stats`][fs stats] object +that may get passed as a second argument with `add`, `addDir`, and `change` events +when available, set this to `true` to ensure it is provided with every event. May +have a slight performance penalty. + +Read about the full set of options in [`chokidar`'s README][chokidar]. + +## fn +Type: `Function` + +If the `fn` is passed, it will be called when the watcher emits a `change`, `add` or `unlink` event. It is automatically debounced with a default delay of 200 milliseconds and subsequent calls will be queued and called upon completion. These defaults can be changed using the `options`. + +The `fn` is passed a single argument, `callback`, which is a function that must be called when work in the `fn` is complete. Instead of calling the `callback` function, [async completion][async-completion] can be signalled by: + * Returning a `Stream` or `EventEmitter` + * Returning a `Child Process` + * Returning a `Promise` + * Returning an `Observable` + +Once async completion is signalled, if another run is queued, it will be executed. + +`gulp.watch` returns a wrapped [chokidar] FSWatcher object. Listeners can also be set directly for any of [chokidar]'s events, such as `addDir`, `unlinkDir`, and `error`. You must set listeners directly to get +access to chokidar's callback parameters, such as `path`. + +```js +var watcher = gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify')); +watcher.on('change', function(path, stats) { + console.log('File ' + path + ' was changed'); +}); + +watcher.on('unlink', function(path) { + console.log('File ' + path + ' was removed'); +}); +``` + +### path +Type: `String` + +Path to the file. If `opts.cwd` is set, `path` is relative to it. + +### stats +Type: `Object` + +[File stats][fs stats] object when available. +Setting the `alwaysStat` option to `true` will ensure that a file stat object will be +provided. + +## watcher methods + +### watcher.close() + +Shuts down the file watcher. + +### watcher.add(glob) + +Watch additional glob (or array of globs) with an already-running watcher instance. + +### watcher.unwatch(glob) + +Stop watching a glob (or array of globs) while leaving the watcher running and +emitting events for the remaining paths it is watching. + +[chokidar]: https://github.com/paulmillr/chokidar +[node-glob]: https://github.com/isaacs/node-glob +[fs stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats +[async-completion]: https://github.com/gulpjs/async-done#completion-and-error-resolution From e447d81342a255ba9f7fac981919fd1f5a9ff495 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:16:53 -0700 Subject: [PATCH 115/225] Docs: Update dest() documentation --- docs/api/dest.md | 134 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 39 deletions(-) diff --git a/docs/api/dest.md b/docs/api/dest.md index a9b909b7..399effe5 100644 --- a/docs/api/dest.md +++ b/docs/api/dest.md @@ -5,62 +5,118 @@ hide_title: true sidebar_label: dest() --> -# `gulp.dest(path[, options])` +# dest() -Can be piped to and it will write files. Re-emits all data passed to it so you -can pipe to multiple folders. Folders that don't exist will be created. +Creates a stream for writing [Vinyl][vinyl-concepts] objects to the file system. -```javascript -gulp.src('./client/templates/*.pug') - .pipe(pug()) - .pipe(gulp.dest('./build/templates')) - .pipe(minify()) - .pipe(gulp.dest('./build/minified_templates')); +## Usage + +```js +const { src, dest } = require('gulp'); + +function copy() { + return src('input/*.js') + .pipe(dest('output/')); +} + +exports.copy = copy; +``` + +## Signature + +```js +dest(directory, [options]) ``` -The write path is calculated by appending the file relative path to the given -destination directory. In turn, relative paths are calculated against -the file base. See `gulp.src` above for more info. +### Parameters + +| parameter | type | note | +|:--------------:|:-----:|--------| +| directory
**(required)** | string
function | The path of the output directory where files will be written. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | +| options | object | Detailed in [Options][options-section] below. | + +### Returns + +A stream that can be used in the middle or at the end of a pipeline to create files on the file system. +Whenever a Vinyl object is passed through the stream, it writes the contents and other details out to the file system at the given directory. If the Vinyl object has a `symlink` property, a symbolic link will be created instead of writing the contents. After the file is created, its [metadata will be updated][metadata-updates-section] to match the Vinyl object. + +Whenever a file is created on the file system, the Vinyl object will be modified. +* The `cwd`, `base`, and `path` properties will be updated to match the created file. +* The `stat` property will be updated to match the file on the file system. +* If the `contents` property is a stream, it will be reset so it can be read again. + +### Errors -## path -Type: `String` or `Function` +When `directory` is an empty string, throws an error with the message, "Invalid dest() folder argument. Please specify a non-empty string or a function." -The path (output folder) to write files to. Or a function that returns it, -the function will be provided a [vinyl File instance]. +When `directory` is not a string or function, throws an error with the message, "Invalid dest() folder argument. Please specify a non-empty string or a function." -## options -Type: `Object` +When `directory` is a function that returns an empty string or `undefined`, emits an error with the message, "Invalid output folder". -### options.cwd -Type: `String` +### Options -Default: `process.cwd()` -`cwd` for the output folder, only has an effect if provided output folder is -relative. +**For options that accept a function, the passed function will be called with each Vinyl object and must return a value of another listed type.** -### options.mode -Type: `String` or `Number` +| name | type | default | note | +|:-------:|:------:|-----------|-------| +| cwd | string
function | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | +| mode | number
function | `stat.mode` of the Vinyl object | The mode used when creating files. If not set and `stat.mode` is missing, the process' mode will be used instead. | +| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | +| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | +| append | boolean
function | false | If true, adds contents to the end of the file, instead of replacing existing contents. | +| sourcemaps | boolean
string
function | false | If true, writes inline sourcemaps to the output file. Specifying a `string` path will write external [sourcemaps][sourcemaps-section] at the given path. | +| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | +| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | -Default: the mode of the input file (file.stat.mode) or the process mode -if the input file has no mode property. +## Metadata updates -Octal permission specifying the mode the files should be created with: e.g. -`"0744"`, `0744` or `484` (`0744` in base 10). +Whenever the `dest()` stream creates a file, the Vinyl object's `mode`, `mtime`, and `atime` are compared to the created file. If they differ, the created file will be updated to reflect the Vinyl object's metadata. If those properties are the same, or gulp doesn't have permissions to make changes, the attempt is skipped silently. + +This functionality is disabled on Windows or other operating systems that don't support Node's `process.getuid()` or `process.geteuid()` methods. This is due to Windows having unexpected results through usage of `fs.fchmod()` and `fs.futimes()`. + +**Note**: The `fs.futimes()` method internally converts `mtime` and `atime` timestamps to seconds. This division by 1000 may cause some loss of precision on 32-bit operating systems. + +## Sourcemaps + +Sourcemap support is built directly into `src()` and `dest()`, but it is disabled by default. Enable it to produce inline or external sourcemaps. + +Inline sourcemaps: +```js +const { src, dest } = require('gulp'); +const uglify = require('gulp-uglify'); + +src('input/**/*.js', { sourcemaps: true }) + .pipe(uglify()) + .pipe(dest('output/', { sourcemaps: true })); +``` + +External sourcemaps: +```js +const { src, dest } = require('gulp'); +const uglify = require('gulp-uglify'); + +src('input/**/*.js', { sourcemaps: true }) + .pipe(uglify()) + .pipe(dest('output/', { sourcemaps: '.' })); +``` -### options.dirMode -Type: `String` or `Number` +## Symbolic links on Windows -Default: Default is the process mode. +When creating symbolic links on Windows, a `type` argument is passed to Node's `fs.symlink()` method which specifies the kind of target being linked. The link type is set to: +* `'file'` when the target is a regular file +* `'junction'` when the target is a directory +* `'dir'` when the target is a directory and the user disables the `useJunctions` option -Octal permission specifying the mode the directory should be created with: e.g. -`"0755"`, `0755` or `493` (`0755` in base 10). -### options.overwrite -Type: `Boolean` +If you try to create a dangling (pointing to a non-existent target) link, the link type can't be determined automatically. In these cases, behavior will vary depending on whether the dangling link is being created via `symlink()` or via `dest()`. -Default: `true` +For dangling links created via `symlink()`, the incoming Vinyl object represents the target, so its stats will determine the desired link type. If `isDirectory()` returns false then a `'file'` link is created, otherwise a `'junction'` or a `'dir'` link is created depending on the value of the `useJunctions` option. -Specify if existing files with the same path should be overwritten or not. +For dangling links created via `dest()`, the incoming Vinyl object represents the link - typically loaded from disk via `src(..., { resolveSymlinks: false })`. In this case, the link type can't be reasonably determined and defaults to using `'file'`. This may cause unexpected behavior if you are creating a dangling link to a directory. **Avoid this scenario.** -[vinyl File instance]: https://github.com/gulpjs/vinyl +[sourcemaps-section]: #sourcemaps +[symbolic-links-section]: #symbolic-links-on-windows +[options-section]: #options +[metadata-updates-section]: #metadata-updates +[vinyl-concepts]: concepts.md#vinyl From 363df219e01f7d7ffed8c99930054c9938cecc31 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:17:59 -0700 Subject: [PATCH 116/225] Docs: Update lastRun() documentation --- docs/api/last-run.md | 83 ++++++++++++++++++++++++++++++++++++++++++++ docs/api/lastRun.md | 43 ----------------------- 2 files changed, 83 insertions(+), 43 deletions(-) create mode 100644 docs/api/last-run.md delete mode 100644 docs/api/lastRun.md diff --git a/docs/api/last-run.md b/docs/api/last-run.md new file mode 100644 index 00000000..c7c2269c --- /dev/null +++ b/docs/api/last-run.md @@ -0,0 +1,83 @@ + + +# lastRun() + +Retrieves the last time a task was successfully completed during the current running process. Most useful on subsequent task runs while a watcher is running. + +When combined with `src()`, enables incremental builds to speed up your execution times by skipping files that haven't changed since the last successful task completion. + +## Usage + +```js +const { src, dest, lastRun, watch } = require('gulp'); +const imagemin = require('gulp-imagemin'); + +function images() { + return src('src/images/**/*.jpg', { since: lastRun(images) }) + .pipe(imagemin()) + .pipe(dest('build/img/')); +} + +function watch() { + watch('src/images/**/*.jpg', images); +} + +exports.watch = watch; +``` + + +## Signature + +```js +lastRun(task, [precision]) +``` + +### Parameters + +| parameter | type | note | +|:--------------:|:------:|-------| +| task
**(required)** | function
string | The task function or the string alias of a registered task. | +| precision | number | Default: `1000` on Node v0.10, `0` on Node v0.12+. Detailed in Timestamp precision][timestamp-precision-section] section below. | + +### Returns + +A timestamp (in milliseconds), matching the last completion time of the task. If the task has not been run or has failed, returns `undefined`. + +To avoid an invalid state being cached, the returned value will be `undefined` if a task errors. + +### Errors + +When called with a value other than a string or function, throws an error with the message, "Only functions can check lastRun". + +When called on a non-extensible function and Node is missing WeakMap, throws an error with the message, "Only extensible functions can check lastRun". + +## Timestamp precision + +While there are sensible defaults for the precision of timestamps, they can be rounded using the `precision` parameter. Useful if your file system or Node version has a lossy precision on file time attributes. + +* `lastRun(someTask)` returns 1426000001111 +* `lastRun(someTask, 100)` returns 1426000001100 +* `lastRun(someTask, 1000)` returns 1426000001000 + +A file's [mtime stat][fs-stats-concepts] precision may vary depending on the node version and/or the file system used: + + +| platform | precision | +|:-----------:|:------------:| +| Node v0.10 | 1000ms | +| Node v0.12+ | 1ms | +| FAT32 file system | 2000ms | +| HFS+ or Ext3 file systems | 1000ms | +| NTFS using Node v0.10 | 1s | +| NTFS using Node 0.12+ | 100ms | +| Ext4 using Node v0.10 | 1000ms | +| Ext4 using Node 0.12+ | 1ms | + + +[timestamp-precision-section]: #timestamp-precision +[fs-stats-concepts]: concepts.md#file-system-stats diff --git a/docs/api/lastRun.md b/docs/api/lastRun.md deleted file mode 100644 index 2be1e668..00000000 --- a/docs/api/lastRun.md +++ /dev/null @@ -1,43 +0,0 @@ - - -# `gulp.lastRun(taskName, [timeResolution])` - -Returns the timestamp of the last time the task ran successfully. The time -will be the time the task started. Returns `undefined` if the task has -not run yet. - -## taskName - -Type: `String` - -The name of the registered task or of a function. - -## timeResolution - -Type: `Number`. - -Default: `1000` on node v0.10, `0` on node v0.12 (and iojs v1.5). - -Set the time resolution of the returned timestamps. Assuming -the task named "someTask" ran at `1426000004321`: - -- `gulp.lastRun('someTask', 1000)` would return `1426000004000`. -- `gulp.lastRun('someTask', 100)` would return `1426000004300`. - -`timeResolution` allows you to compare a run time to a file [mtime stat][fs stats] -attribute. This attribute time resolution may vary depending of the node version -and the file system used: - -- on node v0.10, a file [mtime stat][fs stats] time resolution of any files will be 1s at best; -- on node v0.12 and iojs v1.5, 1ms at best; -- for files on FAT32, the mtime time resolution is 2s; -- on HFS+ and Ext3, 1s; -- on NTFS, 1s on node v0.10, 100ms on node 0.12; -- on Ext4, 1s on node v0.10, 1ms on node 0.12. - -[fs stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats From dc3cba7991d94d66cc3a8b111399045a2e7d02c2 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:18:28 -0700 Subject: [PATCH 117/225] Docs: Update parallel() documentation --- docs/api/parallel.md | 113 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 20 deletions(-) diff --git a/docs/api/parallel.md b/docs/api/parallel.md index 7d15efbb..4229c845 100644 --- a/docs/api/parallel.md +++ b/docs/api/parallel.md @@ -5,36 +5,109 @@ hide_title: true sidebar_label: parallel() --> -# `gulp.parallel(...tasks)` +# parallel() -Takes a number of task names or functions and returns a function of the composed -tasks or functions. +Combines task functions and/or composed operations into larger operations that will be executed simultaneously. The composed operations from `series()` and `parallel()` can be nested to any depth. -When using task names, the task should already be registered. +## Usage -When the returned function is executed, the tasks or functions will be executed -in parallel, all being executed at the same time. If an error occurs, -all execution will complete. +```js +const { parallel } = require('gulp'); + +function javascript(cb) { + // body omitted + cb(); +} + +function css(cb) { + // body omitted + cb(); +} + +exports.build = parallel(javascript, css); +``` + +## Signature ```js -gulp.task('one', function(done) { - // do stuff - done(); +parallel(...tasks) +``` + +### Parameters + +| parameter | type | note | +|:--------------:|:------:|-------| +| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | + +### Returns + +A composed operation to be registered as a task or nested within other `series` and/or `parallel` compositions. + +When the composed operation is executed, all tasks will be run at maximum concurrency. If an error occurs in one task, other tasks nondeterministically may or may not complete. + +### Errors + +When no tasks are passed, throws an error with the message, "One or more tasks should be combined using series or parallel". + +When invalid tasks or unregistered tasks are passed, throws an error with the message, "Task never defined". + +## Forward references + +A forward reference is when you compose tasks, using string references, that haven't been registered yet. This was a common practice in older versions, but this feature was removed to achieve faster task runtime and promote the use of named functions. + +In newer versions, you'll get an error, with the message "Task never defined", if you try to use forward references. You may experience this when trying to use `exports` for task registration _and_ composing tasks by string. In this situation, use named functions instead of string references. + +During migration, you may need the [forward reference registry][undertaker-forward-reference-external]. This will add an extra closure to every task reference and dramatically slow down your build. **Don't rely on this fix for very long**. + +## Avoid duplicating tasks + +When a composed operation is run, each task will be executed every time it was supplied. + +A `clean` task referenced in two different compositions would be run twice and lead to undesired results. Instead, refactor the `clean` task to be specified in the final composition. + +If you have code like this: +```js +// This is INCORRECT +const { series, parallel } = require('gulp'); + +const clean = function(cb) { + // body omitted + cb(); +}; + +const css = series(clean, function(cb) { + // body omitted + cb(); }); -gulp.task('two', function(done) { - // do stuff - done(); +const javascript = series(clean, function(cb) { + // body omitted + cb(); }); -gulp.task('default', gulp.parallel('one', 'two', function(done) { - // do more stuff - done(); -})); +exports.build = parallel(css, javascript); ``` -## tasks -Type: `Array`, `String` or `Function` +Migrate to this: +```js +const { series, parallel } = require('gulp'); + +function clean(cb) { + // body omitted + cb(); +} -A task name, a function or an array of either. +function css(cb) { + // body omitted + cb(); +} + +function javascript(cb) { + // body omitted + cb(); +} + +exports.build = series(clean, parallel(css, javascript)); +``` +[undertaker-forward-reference-external]: https://github.com/gulpjs/undertaker-forward-reference From d6804874b14a8f55ac11a87004ac4bad7814e0b8 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:19:12 -0700 Subject: [PATCH 118/225] Docs: Update registry() documentation --- docs/api/registry.md | 81 ++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/docs/api/registry.md b/docs/api/registry.md index 2b04e9f8..cd12bc40 100644 --- a/docs/api/registry.md +++ b/docs/api/registry.md @@ -5,60 +5,59 @@ hide_title: true sidebar_label: registry() --> -# `gulp.registry([registry])` +# registry() -Get or set the underlying task registry. Inherited from [undertaker]; see the undertaker documention on [registries](https://github.com/phated/undertaker#registryregistryinstance). Using this, you can change registries that enhance gulp in different ways. Utilizing a custom registry has at least three use cases: -- [Sharing tasks](https://github.com/phated/undertaker#sharing-tasks) -- [Sharing functionality](https://github.com/phated/undertaker#sharing-functionalities) (e.g. you could override the task prototype to add some additional logging, bind task metadata or include some config settings.) -- Handling other behavior that hooks into the registry lifecycle (see [gulp-hub](https://github.com/frankwallis/gulp-hub) for an example) +Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. -To build your own custom registry see the [undertaker documentation on custom registries](https://github.com/phated/undertaker#custom-registries). +**Note:** Only tasks registered with `task()` will be provided to the custom registry. The task functions passed directly to `series()` or `parallel()` will not be provided - if you need to customize the registry behavior, compose tasks with string references. -## registry +When assigning a new registry, each task from the current registry will be transferred and the current registry will be replaced with the new one. This allows for adding multiple custom registries in sequential order. -A registry instance. When passed in, the tasks from the current registry will be transferred to the new registry and then current registry will be replaced with the new registry. +See [Creating Custom Registries][creating-custom-registries] for details. -## Example - -This example shows how to create and use a simple custom registry to add tasks. +## Usage ```js -//gulpfile.js -var gulp = require('gulp'); +const { registry, task, series } = require('gulp'); +const FwdRef = require('undertaker-forward-reference'); -var companyTasks = require('./myCompanyTasksRegistry.js'); +registry(FwdRef()); -gulp.registry(companyTasks); +task('default', series('forward-ref')); -gulp.task('one', gulp.parallel('someCompanyTask', function(done) { - console.log('in task one'); - done(); -})); +task('forward-ref', function(cb) { + // body omitted + cb(); +}); ``` +## Signature + ```js -//myCompanyTasksRegistry.js -var util = require('util'); - -var DefaultRegistry = require('undertaker-registry'); - -function MyCompanyTasksRegistry() { - DefaultRegistry.call(this); -} -util.inherits(MyCompanyTasksRegistry, DefaultRegistry); - -MyCompanyTasksRegistry.prototype.init = function(gulp) { - gulp.task('clean', function(done) { - done(); - }); - gulp.task('someCompanyTask', function(done) { - console.log('performing some company task.'); - done(); - }); -}; - -module.exports = new MyCompanyTasksRegistry(); +registry([registryInstance]) ``` -[undertaker]: https://github.com/gulpjs/undertaker +### Parameters + +| parameter | type | note | +|:--------------:|:-----:|--------| +| registryInstance | object | An instance - not the class - of a custom registry. | + +### Returns + +If a `registryInstance` is passed, nothing will be returned. If no arguments are passed, returns the current registry instance. + +### Errors + +When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message, "Custom registries must be instantiated, but it looks like you passed a constructor". + +When a registry without a `get` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `get` function". + +When a registry without a `set` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `set` function". + +When a registry without an `init` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `init` function" + +When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `tasks` function". + +[creating-custom-registries]: LINK_NEEDED From 4169cb6de2d1bab681aed6f38c00e441bb80578a Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:19:31 -0700 Subject: [PATCH 119/225] Docs: Update series() documentation --- docs/api/series.md | 114 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 20 deletions(-) diff --git a/docs/api/series.md b/docs/api/series.md index 9499ed42..fd2c4987 100644 --- a/docs/api/series.md +++ b/docs/api/series.md @@ -5,35 +5,109 @@ hide_title: true sidebar_label: series() --> -# `gulp.series(...tasks)` +# series() -Takes a number of task names or functions and returns a function of the composed -tasks or functions. +Combines task functions and/or composed operations into larger operations that will be executed one after another, in sequential order. The composed operations from `series()` and `parallel()` can be nested to any depth. -When using task names, the task should already be registered. +## Usage -When the returned function is executed, the tasks or functions will be executed -in series, each waiting for the prior to finish. If an error occurs, -execution will stop. +```js +const { series } = require('gulp'); + +function javascript(cb) { + // body omitted + cb(); +} + +function css(cb) { + // body omitted + cb(); +} + +exports.build = series(javascript, css); +``` + +## Signature + +```js +series(...tasks) +``` + +### Parameters + +| parameter | type | note | +|:--------------:|:------:|-------| +| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | + +### Returns + +A composed operation to be registered as a task or nested within other `series` and/or `parallel` compositions. + +When the composed operation is executed, all tasks will be run sequentially. If an error occurs in one task, no subsequent tasks will be run. + +### Errors + +When no tasks are passed, throws an error with the message, "One or more tasks should be combined using series or parallel". +When invalid tasks or unregistered tasks are passed, throws an error with the message, "Task never defined". + +## Forward references + +A forward reference is when you compose tasks, using string references, that haven't been registered yet. This was a common practice in older versions, but this feature was removed to achieve faster task runtime and promote the use of named functions. + +In newer versions, you'll get an error, with the message "Task never defined", if you try to use forward references. You may experience this when trying to use `exports` for your task registration *and* composing tasks by string. In this situation, use named functions instead of string references. + +During migration, you may need to use the [forward reference registry][undertaker-forward-reference-external]. This will add an extra closure to every task reference and dramatically slow down your build. **Don't rely on this fix for very long**. + +## Avoid duplicating tasks + +When a composed operation is run, each task will be executed every time it was supplied. + +A `clean` task referenced in two different compositions would be run twice and lead to undesired results. Instead, refactor the `clean` task to be specified in the final composition. + +If you have code like this: ```js -gulp.task('one', function(done) { - // do stuff - done(); +// This is INCORRECT +const { series, parallel } = require('gulp'); + +const clean = function(cb) { + // body omitted + cb(); +}; + +const css = series(clean, function(cb) { + // body omitted + cb(); }); -gulp.task('two', function(done) { - // do stuff - done(); +const javascript = series(clean, function(cb) { + // body omitted + cb(); }); -gulp.task('default', gulp.series('one', 'two', function(done) { - // do more stuff - done(); -})); +exports.build = parallel(css, javascript); ``` -## tasks -Type: `Array`, `String` or `Function` +Migrate to this: +```js +const { series, parallel } = require('gulp'); + +function clean(cb) { + // body omitted + cb(); +} + +function css(cb) { + // body omitted + cb(); +} + +function javascript(cb) { + // body omitted + cb(); +} + +exports.build = series(clean, parallel(css, javascript)); +``` -A task name, a function or an array of either. +[undertaker-forward-reference-external]: https://github.com/gulpjs/undertaker-forward-reference From d95b45733fe9dc2ce5f96d88e12b1172f22690e1 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:19:58 -0700 Subject: [PATCH 120/225] Docs: Update src() documentation --- docs/api/src.md | 210 ++++++++++++++++++++++-------------------------- 1 file changed, 97 insertions(+), 113 deletions(-) diff --git a/docs/api/src.md b/docs/api/src.md index 307d9ab6..e66a4832 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -5,135 +5,119 @@ hide_title: true sidebar_label: src() --> -# `gulp.src(globs[, options])` +# src() -Emits files matching provided glob or array of globs. -Returns a [stream] of [Vinyl files] that can be [piped] to plugins. +Creates a stream for reading [Vinyl][vinyl-concepts] objects from the file system. -```javascript -gulp.src('client/templates/*.pug') - .pipe(pug()) - .pipe(minify()) - .pipe(gulp.dest('build/minified_templates')); -``` - -`glob` refers to [node-glob syntax][node-glob] or it can be a direct file path. - -## globs -Type: `String` or `Array` - -Glob or array of globs to read. Globs use [node-glob syntax] except that negation is fully supported. +**Note:** Any UTF-8 BOMs will be removed from UTF-8 files read by `src()`, unless disabled using the `removeBOM` option. -A glob that begins with `!` excludes matching files from the glob results up to that point. For example, consider this directory structure: - - client/ - a.js - bob.js - bad.js - -The following expression matches `a.js` and `bad.js`: - - gulp.src(['client/*.js', '!client/b*.js', 'client/bad.js']) +## Usage +```javascript +const { src, dest } = require('gulp'); -Note that globs are evaluated in order, which means this is possible: +function copy() { + return src('input/*.js') + .pipe(dest('output/')); +} -```js -// exclude every JS file that starts with a b except bad.js -gulp.src(['*.js', '!b*.js', 'bad.js']) +exports.copy = copy; ``` -**Note:** glob symlink following behavior is opt-in and you must specify -`follow: true` in the options object that is passed to [node-glob]. - -## options -Type: `Object` - -Options to pass to [node-glob] through [glob-stream]. - -gulp adds some additional options in addition to the -[options supported by node-glob][node-glob documentation] and [glob-stream]: - -### options.cwd - -The working directory the folder is relative to. - -Type: `String` - -Default: `process.cwd()` - -### options.buffer -Type: `Boolean` - -Default: `true` - -Setting this to `false` will return `file.contents` as a stream and not -buffer files. This is useful when working with large files. - -**Note:** Plugins might not implement support for streams. - -### options.read -Type: `Boolean` - -Default: `true` - -Setting this to `false` will return `file.contents` as null and not read -the file at all. - -### options.base -Type: `String` - -Default: everything before a glob starts (see [glob-parent]) - -E.g., consider `somefile.js` in `client/js/somedir`: +## Signature ```js -// Matches 'client/js/somedir/somefile.js' and resolves `base` to `client/js/` -gulp.src('client/js/**/*.js') - .pipe(minify()) - .pipe(gulp.dest('build')); // Writes 'build/somedir/somefile.js' - -gulp.src('client/js/**/*.js', { base: 'client' }) - .pipe(minify()) - .pipe(gulp.dest('build')); // Writes 'build/js/somedir/somefile.js' +src(globs, [options]) ``` -### options.since -Type: `Date` or `Number` - -Setting this to a Date or a time stamp will discard any file that have not been -modified since the time specified. - -### options.passthrough -Type: `Boolean` - -Default: `false` - -If true, it will create a duplex stream which passes items through and -emits globbed files. - -### options.allowEmpty -Type: `Boolean` - -Default: `false` +### Parameters + +| parameter | type | note | +|:--------------:|:------:|-------| +| globs | string
array | [Globs][globs-concepts] to watch on the file system. | +| options | object | Detailed in [Options][options-section] below. | + +### Returns + +A stream that can be used at the beginning or in the middle of a pipeline to add files based on the given globs. + +### Errors + +When the `globs` argument can only match one file (such as `foo/bar.js`) and no match is found, throws an error with the message, "File not found with singular glob". To suppress this error, set the `allowEmpty` option to `true`. + +When an invalid glob is given in `globs`, throws an error with the message, "Invalid glob argument". + +### Options + +**For options that accept a function, the passed function will be called with each Vinyl object and must return a value of another listed type.** + + +| name | type | default | note | +|:--------:|:------:|------------|--------| +| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. Contents of large files may not be able to be buffered.
**Note:** Plugins may not implement support for streaming contents. | +| read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | +| since | date
timestamp
function | | When set, only creates Vinyl objects for files that have been modified since the specified time. | +| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM.. | +| sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | +| resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | +| cwd | string | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| base | string | | Explicitly set the `base` property on created Vinyl objects. Detailed in [API Concepts][glob-base-concepts].
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| cwdbase | boolean | false | If true, `cwd` and `base` options should be aligned.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| root | string | | The root path that `globs` are resolved against.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| allowEmpty | boolean | false | When false, `globs` which can only match one file (such as `foo/bar.js`) causes an error to be thrown if they don't find a match. If true, suppresses glob failures.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| uniqueBy | string
function | `'path'` | Remove duplicates from the stream by comparing the string property name or the result of the function.
**Note:** When using a function, the function receives the streamed data (objects containing `cwd`, `base`, `path` properties). | +| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| silent | boolean | true | When true, suppresses warnings from printing on `stderr`.
**Note:** This option is passed directly to [node-glob][node-glob-external] but defaulted to `true` instead of `false`. | +| mark | boolean | false | If true, a `/` character will be appended to directory matches. Generally not needed because paths are normalized within the pipeline.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nosort | boolean | false | If true, disables sorting the glob results.
_This option is passed directly to [node-glob][node-glob-external]._ | +| stat | boolean | false | If true, `fs.stat()` is called on all results. This adds extra overhead and generally should not be used.
_This option is passed directly to [node-glob][node-glob-external]._ | +| strict | boolean | false | If true, an error will be thrown if an unexpected problem is encountered while attempting to read a directory.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [node-glob][node-glob-external]._ | +| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [node-glob][node-glob-external]._ | +| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [node-glob][node-glob-external]._ | +| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nodir | boolean | false | If true, only matches files, not directories.
**Note:** To match only directories, end your glob with a `/`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [node-glob][node-glob-external]._ | +| follow | boolean | false | If true, symlinked directories will be traversed when expanding `**` globs.
**Note:** This can cause problems with cyclical links.
_This option is passed directly to [node-glob][node-glob-external]._ | +| realpath | boolean | false | If true, `fs.realpath()` is called on all results. This may result in dangling links.
_This option is passed directly to [node-glob][node-glob-external]._ | +| cache | object | | A previously generated cache object - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| statCache | object | | A previously generated cache of `fs.Stat` results - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| symlinks | object | | A previously generated cache of symbolic links - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nocomment | boolean | false | When false, treat a `#` character at the start of a glob as a comment.
_This option is passed directly to [node-glob][node-glob-external]._ | + +## Sourcemaps + +Sourcemap support is built directly into `src()` and `dest()`, but is disabled by default. Enable it to produce inline or external sourcemaps. + +Inline sourcemaps: +```js +const { src, dest } = require('gulp'); +const uglify = require('gulp-uglify'); -When true, will allow singular globs to fail to match. Otherwise, globs which are only supposed to match one file (such as `./foo/bar.js`) will cause an error to be thrown if they don't match. +src('input/**/*.js', { sourcemaps: true }) + .pipe(uglify()) + .pipe(dest('output/', { sourcemaps: true })); +``` +External sourcemaps: ```js -// Emits an error if app/scripts.js doesn't exist -gulp.src('app/scripts.js') - .pipe(...); +const { src, dest } = require('gulp'); +const uglify = require('gulp-uglify'); -// Won't emit an error -gulp.src('app/scripts.js', { allowEmpty: true }) - .pipe(...); +src('input/**/*.js', { sourcemaps: true }) + .pipe(uglify()) + .pipe(dest('output/', { sourcemaps: '.' })); ``` -[glob-stream]: https://github.com/gulpjs/glob-stream -[glob-parent]: https://github.com/es128/glob-parent -[node-glob documentation]: https://github.com/isaacs/node-glob#options -[node-glob]: https://github.com/isaacs/node-glob -[piped]: http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options -[stream]: http://nodejs.org/api/stream.html -[Vinyl files]: https://github.com/gulpjs/vinyl-fs +[sourcemaps-section]: #sourcemaps +[options-section]: #options +[vinyl-concepts]: concepts.md#vinyl +[glob-base-concepts]: concepts.md#glob-base +[globs-concepts]: concepts.md#globs +[extglob-docs]: LINK_NEEDED +[node-glob-external]: https://github.com/isaacs/node-glob +[glob-stream-external]: https://github.com/gulpjs/glob-stream From d580efa2b696bbcd7ee4f973eb2f56fe2a996f66 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:20:18 -0700 Subject: [PATCH 121/225] Docs: Update symlink() documentation --- docs/api/symlink.md | 89 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 18 deletions(-) diff --git a/docs/api/symlink.md b/docs/api/symlink.md index f8b00f0c..7fd1e790 100644 --- a/docs/api/symlink.md +++ b/docs/api/symlink.md @@ -5,31 +5,84 @@ hide_title: true sidebar_label: symlink() --> -# `gulp.symlink(folder[, options])` +# symlink() -Functions exactly like `gulp.dest`, but will create symlinks instead of copying -a directory. +Creates a stream for linking [Vinyl][vinyl-concepts] objects to the file system. -## folder -Type: `String` or `Function` +## Usage +' +```js +const { src, symlink } = require('gulp'); -A folder path or a function that receives in a file and returns a folder path. +function link() { + return src('input/*.js') + .pipe(symlink('output/')); +} -## options -Type: `Object` +exports.link = link; +``` -### options.cwd -Type: `String` +## Signature -Default: `process.cwd()` +```js +symlink(directory, [options]) +``` -`cwd` for the output folder, only has an effect if provided output folder is -relative. +### Parameters -### options.dirMode -Type: `String` or `Number` +| parameter | type | note | +|:--------------:|:-----:|--------| +| directory
**(required)** | string
function | The path of the output directory where symbolic links will be created. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | +| options | object | Detailed in [Options][options-section] below. | -Default: Default is the process mode. +### Returns -Octal permission specifying the mode the directory should be created with: e.g. -`"0755"`, `0755` or `493` (`0755` in base 10). +A stream that can be used in the middle or at the end of a pipeline to create symbolic links on the file system. +Whenever a Vinyl object is passed through the stream, it creates a symbolic link to the original file on the file system at the given directory. + +Whenever a symbolic link is created on the file system, the Vinyl object will be modified. +* The `cwd`, `base`, and `path` properties will be updated to match the created symbolic link. +* The `stat` property will be updated to match the symbolic link on the file system. +* The `contents` property will be set to `null`. +* The `symlink` property will be added or replaced with original path. + +**Note:** On Windows, directory links are created using junctions by default. The `useJunctions` option disables this behavior. + + +### Errors + +When `directory` is an empty string, throws an error with the message, "Invalid symlink() folder argument. Please specify a non-empty string or a function." + +When `directory` is not a string or function, throws an error with the message, "Invalid symlink() folder argument. Please specify a non-empty string or a function." + +When `directory` is a function that returns an empty string or `undefined`, emits an error with the message, "Invalid output folder". + +### Options + +**For options that accept a function, the passed function will be called with each Vinyl object and must return a value of another listed type.** + +| name | type | default | note | +|:-------:|:------:|-----------|-------| +| cwd | string
function | `process.cwd()` |The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | +| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | +| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | +| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | +| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | + +## Symbolic links on Windows + +When creating symbolic links on Windows, a `type` argument is passed to Node's `fs.symlink()` method which specifies the type of target being linked. The link type is set to: +`'file'` when the target is a regular file +`'junction'` when the target is a directory +`'dir'` when the target is a directory and the user disables the `useJunctions` option + + +If you try to create a dangling (pointing to a non-existent target) link, the link type can't be determined automatically. In these cases, behavior will vary depending on whether the dangling link is being created via `symlink()` or via `dest()`. + +For dangling links created via `symlink()`, the incoming Vinyl object represents the target, so its stats will determine the desired link type. If `isDirectory()` returns false then a `'file'` link is created, otherwise a `'junction'` or a `'dir'` link is created depending on the value of the `useJunctions` option. + +For dangling links created via `dest()`, the incoming Vinyl object represents the link - typically loaded from disk via `src(..., { resolveSymlinks: false })`. In this case, the link type can't be reasonably determined and defaults to using `'file'`. This may cause unexpected behavior when creating a dangling link to a directory. **Avoid this scenario.** + +[options-section]: #options +[symbolic-links-section]: #symbolic-links-on-windows +[vinyl-concepts]: concepts.md#vinyl From b636a9c9600137e158f0cdb9a923d526bfad6f80 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:20:46 -0700 Subject: [PATCH 122/225] Docs: Update task() documentation --- docs/api/task.md | 211 ++++++++++++++--------------------------------- 1 file changed, 63 insertions(+), 148 deletions(-) diff --git a/docs/api/task.md b/docs/api/task.md index b644de60..698cf843 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -5,190 +5,105 @@ hide_title: true sidebar_label: task() --> -# `gulp.task([name,] fn)` +# task() -Define a task exposed to gulp-cli, `gulp.series`, `gulp.parallel` and -`gulp.lastRun`; inherited from [undertaker]. +**Reminder**: This API isn't the recommended pattern anymore - export your tasks. -```js -gulp.task(function someTask() { - // Do stuff -}); -``` +Defines a task within the task system. The task can then be accessed from the command line and the `series()`, `parallel()`, and `lastRun()` APIs. -Or get a task that has been registered. +## Usage +Register a named function as a task: ```js -// someTask will be the registered task function -var someTask = gulp.task('someTask'); -``` - -## name -Type: `String` - -If the name is not provided, the task will be named after the function -`name` or `displayName` property. The name argument is required if the -`name` and `displayName` properties of `fn` are empty. +const { task } = require('gulp'); -Since the task can be run from the command line, you should avoid using -spaces in task names. - -## fn - -The function that performs the task's operations. Generally it takes this form: - -```js -function someTask() { - return gulp.src(['some/glob/**/*.ext']).pipe(someplugin()); +function build(cb) { + // body omitted + cb(); } -someTask.description = 'Does something'; -gulp.task(someTask) +task(build); ``` -Gulp tasks are asynchronous and Gulp uses [async-done] to wait for the task's -completion. Tasks are called with a callback parameter to call to signal -completion. Alternatively, Task can return a stream, a promise, a child process -or a RxJS observable to signal the end of the task. - -**Warning:** Sync tasks are not supported and your function will never complete -if the one of the above strategies is not used to signal completion. However, -thrown errors will be caught by Gulp. - -## fn properties - -### fn.name - -`gulp.task` names the task after the function `name` property -if the optional `name` parameter of `gulp.task` is not provided. - -**Note:** [Function.name] is not writable; it cannot be set or edited. If -you need to assign a function name or use characters that aren't allowed -in function names, use the `displayName` property. -It will be empty for anonymous functions: - +Register an anonymous function as a task: ```js -function foo() {}; -foo.name === 'foo' // true - -var bar = function() {}; -bar.name === '' // true +const { task } = require('gulp'); -bar.name = 'bar' -bar.name === '' // true +task('build', function(cb) { + // body omitted + cb(); +}); ``` -### fn.displayName - -`gulp.task` names the task after the function `displayName` property -if function is anonymous and the optional `name` parameter of `gulp.task` -is not provided. - -### fn.description - -gulp-cli prints this description alongside the task name when listing tasks: - +Retrieve a task that has been registered previously: ```js -var gulp = require('gulp'); - -function test(done){ - done(); -} -test.description = 'I do nothing'; +const { task } = require('gulp'); -gulp.task(test); -``` +task('build', function(cb) { + // body omitted + cb(); +}); -```sh -$> gulp --tasks -[12:00:02] Tasks for ~/Documents/some-project/gulpfile.js -[12:00:02] └── test I do nothing +const build = task('build'); ``` -## Async support - -### Accept a callback +## Signature ```js -var del = require('del'); +task([taskName], taskFunction) +``` -gulp.task('clean', function(done) { - del(['.build/'], done); -}); +### Parameters -// use an async result in a pipe -gulp.task('somename', function(cb) { - getFilesAsync(function(err, res) { - if (err) return cb(err); - var stream = gulp.src(res) - .pipe(minify()) - .pipe(gulp.dest('build')) - .on('end', cb); - }); -}); -``` +If the `taskName` is not provided, the task will be referenced by the `name` property of a named function or a user-defined `displayName` property. The `taskName` parameter must be used for anonymous functions missing a `displayName` property. -The callback accepts an optional `Error` object. If it receives an error, -the task will fail. +Since any registered task can be run from the command line, avoid using spaces in task names. -### Return a stream +| parameter | type | note | +|:--------------:|:------:|-------| +| taskName | string | An alias for the task function within the the task system. Not needed when using named functions for `taskFunction`. | +| taskFunction
**(required)** | function | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | -```js -gulp.task('somename', function() { - return gulp.src('client/**/*.js') - .pipe(minify()) - .pipe(gulp.dest('build')); -}); -``` +### Returns -### Return a promise +When registering a task, nothing is returned. -```js -var Promise = require('promise'); -var del = require('del'); - -gulp.task('clean', function() { - return new Promise(function (resolve, reject) { - del(['.build/'], function(err) { - if (err) { - reject(err); - } else { - resolve(); - } - }); - }); -}); -``` +When retrieving a task, a wrapped task (not the original function) registered as `taskName` will be returned. The wrapped task has an `unwrap()` method that will return the original function. -or: -```js -var promisedDel = require('promised-del'); +### Errors -gulp.task('clean', function() { - return promisedDel(['.build/']); -}); -``` +When registering a task where `taskName` is missing and `taskFunction` is anonymous, will throw an error with the message, "Task name must be specified". + +## Task metadata -### Return a child process +| property | type | note | +|:--------------:|:------:|-------| +| name | string | A special property of named functions. Used to register the task.
**Note:** [`name`][function-name-external] is not writable; it cannot be set or changed. | +| displayName | string | When attached to a `taskFunction` creates an alias for the task. If using characters that aren't allowed in function names, use this property. | +| description | string | When attached to a `taskFunction` provides a description to be printed by the command line when listing tasks. | +| flags | object | When attached to a `taskFunction` provides flags to be printed by the command line when listing tasks. The keys of the object represent the flags and the values are their descriptions. | ```js -gulp.task('clean', function() { - return spawn('rm', ['-rf', path.join(__dirname, 'build')]); -}); +const { task } = require('gulp'); -``` +const clean = function(cb) { + // body omitted + cb(); +}; +clean.displayName = 'clean:all'; -### Return a [RxJS] observable +task(clean); -```js -var Observable = require('rx').Observable; +function build(cb) { + // body omitted + cb(); +} +build.description = 'Build the project'; +build.flags = { '-e': 'An example flag' }; -gulp.task('sometask', function() { - return Observable.return(42); -}); +task(build); ``` -[Function.name]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name -[RxJS]: https://www.npmjs.com/package/rx -[async-done]: https://www.npmjs.com/package/async-done -[undertaker]: https://github.com/gulpjs/undertaker +[task-metadata-section]: #task-metadata +[task-concepts]: concepts.md#tasks +[function-name-external]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name From ebb9818461724d96d80a627925ea133684d43a00 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:21:07 -0700 Subject: [PATCH 123/225] Docs: Update tree() documentation --- docs/api/tree.md | 285 +++++++++++++++++++++++++---------------------- 1 file changed, 154 insertions(+), 131 deletions(-) diff --git a/docs/api/tree.md b/docs/api/tree.md index e7e43f1b..dc6464a8 100644 --- a/docs/api/tree.md +++ b/docs/api/tree.md @@ -5,151 +5,174 @@ hide_title: true sidebar_label: tree() --> -# `gulp.tree(options)` +# tree() -Returns the tree of tasks. Inherited from [undertaker]. See the [undertaker docs for this function](https://github.com/phated/undertaker#treeoptions--object). +Fetches the current task dependency tree - in the rare case that it is needed. -## options -Type: `Object` +Generally, `tree()` won't be used by gulp consumers, but it is exposed so the CLI can show the dependency graph of the tasks defined in a gulpfile. -Options to pass to [undertaker]. +## Usage -### options.deep -Type: `Boolean` +Example gulpfile: +```js -Default: `false` +const { series, parallel } = require('gulp'); -If set to `true` whole tree should be returned. +function one(cb) { + // body omitted + cb(); +} -## Example gulpfile +function two(cb) { + // body omitted + cb(); +} -```js -gulp.task('one', function(done) { - // do stuff - done(); -}); - -gulp.task('two', function(done) { - // do stuff - done(); -}); - -gulp.task('three', function(done) { - // do stuff - done(); -}); - -gulp.task('four', gulp.series('one', 'two')); - -gulp.task('five', - gulp.series('four', - gulp.parallel('three', function(done) { - // do more stuff - done(); - }) - ) +function three(cb) { + // body omitted + cb(); +} + +const four = series(one, two); + +const five = series(four, + parallel(three, function(cb) { + // Body omitted + cb(); + }) ); + +module.exports = { one, two, three, four, five }; +``` + +Output for `tree()`: +```js +{ + label: 'Tasks', + nodes: [ 'one', 'two', 'three', 'four', 'five' ] +} ``` -## Example tree output +Output for `tree({ deep: true })`: ```js -gulp.tree() - -// output: [ 'one', 'two', 'three', 'four', 'five' ] - -gulp.tree({ deep: true }) - -/*output: [ - { - "label":"one", - "type":"task", - "nodes":[] - }, - { - "label":"two", - "type":"task", - "nodes":[] - }, - { - "label":"three", - "type":"task", - "nodes":[] - }, - { - "label":"four", - "type":"task", - "nodes":[ - { - "label":"", - "type":"function", - "nodes":[ - { - "label":"one", - "type":"task", - "nodes":[] - }, - { - "label":"two", - "type":"task", - "nodes":[] - } - ] - } +{ + label: "Tasks", + nodes: [ + { + label: "one", + type: "task", + nodes: [] + }, + { + label: "two", + type: "task", + nodes: [] + }, + { + label: "three", + type: "task", + nodes: [] + }, + { + label: "four", + type: "task", + nodes: [ + { + label: "", + type: "function", + branch: true, + nodes: [ + { + label: "one", + type: "function", + nodes: [] + }, + { + label: "two", + type: "function", + nodes: [] + } + ] + } ] - }, - { - "label":"five", - "type":"task", - "nodes":[ - { - "label":"", - "type":"function", - "nodes":[ - { - "label":"four", - "type":"task", - "nodes":[ - { - "label":"", - "type":"function", - "nodes":[ - { - "label":"one", - "type":"task", - "nodes":[] - }, - { - "label":"two", - "type":"task", - "nodes":[] - } - ] - } - ] - }, - { - "label":"", - "type":"function", - "nodes":[ - { - "label":"three", - "type":"task", - "nodes":[] - }, - { - "label":"", - "type":"function", - "nodes":[] - } - ] - } - ] - } + }, + { + label: "five", + type: "task", + nodes: [ + { + label: "", + type: "function", + branch: true, + nodes: [ + { + label: "", + type: "function", + branch: true, + nodes: [ + { + label: "one", + type: "function", + nodes: [] + }, + { + label: "two", + type: "function", + nodes: [] + } + ] + }, + { + label: "", + type: "function", + branch: true, + nodes: [ + { + label: "three", + type: "function", + nodes: [] + }, + { + label: "", + type: "function", + nodes: [] + } + ] + } + ] + } ] - } -] -*/ + } + ] +} +``` + +## Signature + +```js +tree([options]) ``` -[undertaker]: https://github.com/gulpjs/undertaker +### Parameters + +| parameter | type | note | +|:--------------:|------:|--------| +| options | object | Detailed in [Options][options-section] below. | + +### Returns + +An object detailing the tree of registered tasks - containing nested objects with `'label'` and `'nodes'` properties (which is [archy][archy-external] compatible). + +Each object may have a `type` property that can be used to determine if the node is a `task` or `function`. + +Each object may have a `branch` property that - when `true` - indicates the node was created using `series()` or `parallel()`. + +### Options + +| name | type | default | note | +|:-------:|:-------:|------------|--------| +| deep | boolean | false | If true, the entire tree will be returned. When false, only top level tasks will be returned. | + +[options-section]: #options +[archy-external]: https://www.npmjs.com/package/archy From 69c22f0982b3fcede69270609292acab7cb70fee Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Tue, 21 Aug 2018 17:21:27 -0700 Subject: [PATCH 124/225] Docs: Update watch() documentation --- docs/api/watch.md | 156 +++++++++++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 64 deletions(-) diff --git a/docs/api/watch.md b/docs/api/watch.md index 002d7a1d..857d10b4 100644 --- a/docs/api/watch.md +++ b/docs/api/watch.md @@ -5,105 +5,133 @@ hide_title: true sidebar_label: watch() --> -# `gulp.watch(globs[, opts][, fn])` +# watch() -Takes a path string, an array of path strings, a [glob][node-glob] string or an array of [glob][node-glob] strings as `globs` to watch on the filesystem. Also optionally takes `options` to configure the watcher and a `fn` to execute when a file changes. +Allows watching globs and running a task when a change occurs. Tasks are handled uniformly with the rest of the task system. -Returns an instance of [`chokidar`][chokidar]. +## Usage ```js -gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify')); +const { watch } = require('gulp'); + +watch(['input/*.js', '!input/something.js'], function(cb) { + // body omitted + cb(); +}); ``` -In the example, `gulp.watch` runs the function returned by `gulp.parallel` each -time a file with the `js` extension in `js/` is updated. +## Signature + +```js +watch(globs, [options], [task]) +``` -## globs -Type: `String` or `Array` +### Parameters -A path string, an array of path strings, a [glob][node-glob] string or an array of [glob][node-glob] strings that indicate which files to watch for changes. +| parameter | type | note | +|:--------------:|:-----:|--------| +| globs
**(required)** | string
array | [Globs][globs-concepts] to watch on the file system. | +| options | object | Detailed in [Options][options-section] below. | +| task | function
string | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. | -## opts -Type: `Object` +### Returns -* `delay` (milliseconds, default: `200`). The delay to wait before triggering the fn. Useful for waiting on many changes before doing the work on changed files, e.g. find-and-replace on many files. -* `queue` (boolean, default: `true`). Whether or not a file change should queue the fn execution if the fn is already running. Useful for a long running fn. -* `ignoreInitial` (boolean, default: `true`). If set to `false` the `fn` is called during [chokidar][chokidar] instantiation as it discovers the file paths. Useful if it is desirable to trigger the `fn` during startup. __Passed through to [chokidar][chokidar], but defaulted to `true` instead of `false`.__ +An instance of [chokidar][chokidar-instance-section] for fine-grained control over your watch setup. -Options that are passed to [`chokidar`][chokidar]. +### Errors -Commonly used options: +When a non-string or array with any non-strings is passed as `globs`, throws an error with the message, "Non-string provided as watch path". -* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition). -Defines files/paths to be excluded from being watched. -* `usePolling` (boolean, default: `false`). When `true` uses a watch method backed -by stat polling. Usually necessary when watching files on a network mount or on a -VMs file system. -* `cwd` (path string). The base directory from which watch paths are to be -derived. Paths emitted with events will be relative to this. -* `alwaysStat` (boolean, default: `false`). If relying upon the -[`fs.Stats`][fs stats] object -that may get passed as a second argument with `add`, `addDir`, and `change` events -when available, set this to `true` to ensure it is provided with every event. May -have a slight performance penalty. +When a string or array is passed as `task`, throws an error with the message, "watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)". -Read about the full set of options in [`chokidar`'s README][chokidar]. +### Options -## fn -Type: `Function` -If the `fn` is passed, it will be called when the watcher emits a `change`, `add` or `unlink` event. It is automatically debounced with a default delay of 200 milliseconds and subsequent calls will be queued and called upon completion. These defaults can be changed using the `options`. +| name | type | default | note | +|:-------:|:------:|-----------|--------| +| ignoreInitial | boolean | true | If false, the task is called during instantiation as file paths are discovered. Use to trigger the task during startup.
**Note:** This option is passed to [chokidar][chokidar-external] but is defaulted to `true` instead of `false`. | +| delay | number | 200 | The millisecond delay between a file change and task execution. Allows for waiting on many changes before executing a task, e.g. find-and-replace on many files. | +| queue | boolean | true | When true and the task is already running, any file changes will queue a single task execution. Keeps long running tasks from overlapping. | +| events | string
array | [ 'add',
'change',
'unlink' ] | The events being watched to trigger task execution. Can be `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, and/or `'error'`. Additionally `'all'` is available, which represents all events other than `'ready'` and `'error'`.
_This option is passed directly to [chokidar][chokidar-external]._ | +| persistent | boolean | true | If false, the watcher will not keep the Node process running. Disabling this option is not recommended.
_This option is passed directly to [chokidar][chokidar-external]._ | +| ignored | array
string
RegExp
function | | Defines globs to be ignored. If a function is provided, it will be called twice per path - once with just the path, then with the path and the `fs.Stats` object of that file.
_This option is passed directly to [chokidar][chokidar-external]._ | +| followSymlinks | boolean | true | When true, changes to both symbolic links and the linked files trigger events. If false, only changes to the symbolic links trigger events.
_This option is passed directly to [chokidar][chokidar-external]._ | +| cwd | string | | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [chokidar][chokidar-external]._ | +| disableGlobbing | boolean | false | If true, all `globs` are treated as literal path names, even if they have special characters.
_This option is passed directly to [chokidar][chokidar-external]._ | +| usePolling | boolean | false | When false, the watcher will use `fs.watch()` (or [fsevents][fsevents-external] on Mac) for watching. If true, use `fs.watchFile()` polling instead - needed for successfully watching files over a network or other non-standard situations. Overrides the `useFsEvents` default.
_This option is passed directly to [chokidar][chokidar-external]._ | +| interval | number | 100 | Combine with `usePolling: true`. Interval of file system polling.
_This option is passed directly to [chokidar][chokidar-external]._ | +| binaryInterval | number | 300 | Combine with `usePolling: true`. Interval of file system polling for binary files.
_This option is passed directly to [chokidar][chokidar-external]._ | +| useFsEvents | boolean | true | When true, uses fsevents for watching if available. If explicitly set to true, supersedes the `usePolling` option. If set to false, automatically sets `usePolling` to true.
_This option is passed directly to [chokidar][chokidar-external]._ | +| alwaysStat | boolean | false | If true, always calls `fs.stat()` on changed files - will slow down file watcher. The `fs.Stat` object is only available if you are using the chokidar instance directly.
_This option is passed directly to [chokidar][chokidar-external]._ | +| depth | number | | Indicates how many nested levels of directories will be watched.
_This option is passed directly to [chokidar][chokidar-external]._ | +| awaitWriteFinish | boolean | false | Do not use this option, use `delay` instead.
_This option is passed directly to [chokidar][chokidar-external]._ | +| ignorePermissionErrors | boolean | false | Set to true to watch files that don't have read permissions. Then, if watching fails due to EPERM or EACCES errors, they will be skipped silently.
_This option is passed directly to [chokidar][chokidar-external]._ | +| atomic | number | 100 | Only active if `useFsEvents` and `usePolling` are false. Automatically filters out artifacts that occur from "atomic writes" by some editors. If a file is re-added within the specified milliseconds of being deleted, a change event - instead of unlink then add - will be emitted.
_This option is passed directly to [chokidar][chokidar-external]._ | -The `fn` is passed a single argument, `callback`, which is a function that must be called when work in the `fn` is complete. Instead of calling the `callback` function, [async completion][async-completion] can be signalled by: - * Returning a `Stream` or `EventEmitter` - * Returning a `Child Process` - * Returning a `Promise` - * Returning an `Observable` +## Chokidar instance -Once async completion is signalled, if another run is queued, it will be executed. +The `watch()` method returns the underlying instance of [chokidar][chokidar-external], providing fine-grained control over your watch setup. Most commonly used to register individual event handlers that provide the `path` or `stats` of the changed files. -`gulp.watch` returns a wrapped [chokidar] FSWatcher object. Listeners can also be set directly for any of [chokidar]'s events, such as `addDir`, `unlinkDir`, and `error`. You must set listeners directly to get -access to chokidar's callback parameters, such as `path`. +**When using the chokidar instance directly, you will not have access to the task system integrations, including async completion, queueing, and delay.** ```js -var watcher = gulp.watch('js/**/*.js', gulp.parallel('concat', 'uglify')); +const { watch } = require('gulp'); + +const watcher = watch(['input/*.js']); + watcher.on('change', function(path, stats) { - console.log('File ' + path + ' was changed'); + console.log(`File ${path} was changed`); +}); + +watcher.on('add', function(path, stats) { + console.log(`File ${path} was added`); }); -watcher.on('unlink', function(path) { - console.log('File ' + path + ' was removed'); +watcher.on('unlink', function(path, stats) { + console.log(`File ${path} was removed`); }); + +watcher.close(); ``` -### path -Type: `String` -Path to the file. If `opts.cwd` is set, `path` is relative to it. +`watcher.on(eventName, eventHandler)` + +Registers `eventHandler` functions to be called when the specified event occurs. + +| parameter | type | note | +|:--------------:|:-----:|--------| +| eventName | string | The events that may be watched are `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, `'error'`, or `'all'`. | +| eventHandler | function | Function to be called when the specified event occurs. Arguments detailed in the table below. | -### stats -Type: `Object` +| argument | type | note | +|:-------------:|:-----:|--------| +| path | string | The path of the file that changed. If the `cwd` option was set, the path will be made relative by removing the `cwd`. | +| stats | object | An [fs.Stat][fs-stats-concepts] object, but could be `undefined`. If the `alwaysStat` option was set to `true`, `stats` will always be provided. | -[File stats][fs stats] object when available. -Setting the `alwaysStat` option to `true` will ensure that a file stat object will be -provided. +`watcher.close()` -## watcher methods +Shuts down the file watcher. Once shut down, no more events will be emitted. -### watcher.close() +`watcher.add(globs)` -Shuts down the file watcher. +Adds additional globs to an already-running watcher instance. -### watcher.add(glob) +| parameter | type | note | +|:-------------:|:-----:|--------| +| globs | string
array | The additional globs to be watched. | -Watch additional glob (or array of globs) with an already-running watcher instance. +`watcher.unwatch(globs)` -### watcher.unwatch(glob) +Removes globs that are being watched, while the watcher continues with the remaining paths. -Stop watching a glob (or array of globs) while leaving the watcher running and -emitting events for the remaining paths it is watching. +| parameter | type | note | +|:-------------:|:-----:|--------| +| globs | string
array | The globs to be removed. | -[chokidar]: https://github.com/paulmillr/chokidar -[node-glob]: https://github.com/isaacs/node-glob -[fs stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats -[async-completion]: https://github.com/gulpjs/async-done#completion-and-error-resolution +[chokidar-instance-section]: #chokidar-instance +[tasks-concepts]: concepts.md#tasks +[globs-concepts]: concepts.md#globs +[fs-stats-concepts]: concepts.md#file-system-stats +[chokidar-external]: https://github.com/paulmillr/chokidar +[fsevents-external]: https://github.com/strongloop/fsevents From fc09067fefdea73f255c249f44a2cce48ebbf546 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Mon, 24 Sep 2018 14:39:08 -0700 Subject: [PATCH 125/225] Docs: Add Vinyl documentation --- docs/api/vinyl.md | 141 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 docs/api/vinyl.md diff --git a/docs/api/vinyl.md b/docs/api/vinyl.md new file mode 100644 index 00000000..5107fb8a --- /dev/null +++ b/docs/api/vinyl.md @@ -0,0 +1,141 @@ + + +# Vinyl + +A virtual file format. When a file is read by `src()`, a Vinyl object is generated to represent the file - including the path, contents, and other metadata. + +Vinyl objects can have transformations applied using [plugins][using-plugins-docs]. They may also be persisted to the file system using `dest()`. + +When creating your own Vinyl objects - instead of generating with `src()` - use the external `vinyl` module, as shown in Usage below. + +## Usage + +```js +const Vinyl = require('vinyl'); + +const file = new Vinyl({ + cwd: '/', + base: '/test/', + path: '/test/file.js', + contents: new Buffer('var x = 123') +}); + +file.relative === 'file.js'; + +file.dirname === '/test'; +file.dirname = '/specs'; +file.path === '/specs/file.js'; + +file.basename === 'file.js'; +file.basename = 'file.txt'; +file.path === '/specs/file.txt'; + +file.stem === 'file'; +file.stem = 'foo'; +file.path === '/specs/foo.txt'; +file.extname === '.txt'; +file.extname = '.js'; +file.path === '/specs/file.js'; +``` + +## Signature + +```js +new Vinyl([options]) +``` + +### Parameters + +| parameter | type | note | +|:--------------:|:------:|-------| +| options | object | Detailed in [Options][options-section] below. | + +### Returns + +An instance of the Vinyl class representing a single virtual file, detailed in [Vinyl instance][vinyl-instance-section] below. + +### Errors + +When any passed options don't conform to the [instance property definitions][instance-properties-section] (like if `path` is set to a number) throws as defined in the table. + +### Options + +| name | type | default | note | +|:-------:|:------:|-----------|--------| +| cwd | string | `process.cwd()` | The directory from which relative paths will be derived. Will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | +| base | string | | Used to calculate the `relative` instance property. Falls back to the value of `cwd` if not set. Typically set to the [glob base][glob-base-concepts]. Will be [normalized][normalization-and-concatenation-section] and have trailing separators removed.| +| path | string | | The full, absolute file path. Will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | +| history | array | `[ ]` | An array of paths to pre-populate the `history` of a Vinyl instance. Usually comes from deriving a new Vinyl object from a previous Vinyl object. If `path` and `history` are both passed, `path` is appended to `history`. Each item will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | +| stat | object | | An instance of `fs.Stats`, usually the result of calling `fs.stat()` on a file. Used to determine if a Vinyl object represents a directory or symbolic link. | +| contents | ReadableStream
Buffer
null | null | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | + +Any other properties on `options` will be directly assigned to the Vinyl instance. + +```js +const Vinyl = require('vinyl'); + +const file = new Vinyl({ foo: 'bar' }); +file.foo === 'bar'; +``` + +## Vinyl instance + +Each instance of a Vinyl object will have properties and methods to access and/or modify information about the virtual file. + +### Instance properties + +All internally managed paths - any instance property except `contents` and `stat` - are normalized and have trailing separators removed. See [Normalization and concatenation][normalization-and-concatenation-section] for more information. + +| property | type | description | throws | +|:-----------:|:------:|----------------|----------| +| contents | ReadableStream
Buffer
`null` | Gets and sets the contents of the virtual file. If set to a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-docs] stream. | If set to any value other than a ReadableStream, a Buffer, or `null`. | +| stat | object | Gets and sets an instance of [`fs.Stats`][fs-stats-concepts]. Used when determining if a Vinyl object represents a directory or symbolic link. | | +| cwd | string | Gets and sets the current working directory. Used for deriving relative paths. | If set to an empty string or any non-string value. | +| base | string | Gets and sets the base directory. Used to calculate the `relative` instance property. On a Vinyl object generated by `src()` will be set to the [glob base][glob-base-concepts]. If set to `null` or `undefined`, falls back to the value of the `cwd` instance property. | If set to an empty string or any non-string value (except `null` or `undefined`). | +| path | string | Gets and sets the full, absolute file path. Setting to a value different from the current `path` appends the new path to the `history` instance property. | If set to any non-string value. | +| history | array | Array of all `path` values the Vinyl object has been assigned. The first element (`history[0]`) is the original path and the last element (`history[file.history.length - 1]`) is the current path. This property and its elements should be treated as read-only and only altered indirectly by setting the `path` instance property. | | +| relative | string | Gets the relative path segment between the `base` and the `path` instance properties. | If set to any value. If accessed when `path` is not available. | +| dirname | string | Gets and sets the directory of the `path` instance property. | If accessed when `path` is not available. | +| stem | string | Gets and sets the stem (filename without extension) of the `path` instance property. | If accessed when `path` is not available. | +| extname | string | Gets and sets the extension of the `path` instance property. | If accessed when `path` is not available. | +| basename | string | Gets and sets the filename (`stem + extname`) of the `path` instance property. | If accessed when `path` is not available. | +| symlink | string | Gets and sets the reference path of a symbolic link. | If set to any non-string value. | + +### Instance methods + +| method | return type | returns | +|:----------:|:--------------:|--------| +| `isBuffer()` | boolean | If the `contents` instance property is a Buffer, returns true. | +| `isStream()` | boolean | If the `contents` instance property is a Stream, returns true. | +| `isNull()` | boolean | If the `contents` instance property is `null`, returns true. | +| `isDirectory()` | boolean | If the instance represents a directory, returns true. An instance is considered a directory when `isNull()` returns true, the `stat` instance property is an object, and `stat.isDirectory()` returns true. This assumes a Vinyl object was constructed with a valid (or properly mocked) `fs.Stats` object. | +| `isSymbolic()` | boolean | If the instance represents a symbolic link, returns true. An instance is considered symbolic when `isNull()` returns true, the `stat` instance property is an object, and `stat.isSymbolicLink()` returns true. This assumes a Vinyl object was constructed with a valid (or properly mocked) `fs.Stats` object. | +| `clone([options])` | object | A new Vinyl object with all properties cloned. By default custom properties are deep cloned. If the `deep` option is false, custom attributes will be shallow cloned. If the `contents` option is false and the `contents` instance property is a Buffer, the Buffer will be reused instead of cloned. | +| `inspect()` | string | Returns a formatted interpretation of the Vinyl object. Automatically called by Node's console.log. | + +## Normalization and concatenation + +All path properties are normalized by their setters. Concatenate paths with `/`, instead of using `path.join()`, and normalization will occur properly on all platforms. Never concatenate with `\` - it is a valid filename character on posix system. + +```js +const file = new File(); +file.path = '/' + 'test' + '/' + 'foo.bar'; + +console.log(file.path); +// posix => /test/foo.bar +// win32 => \\test\\foo.bar +``` + +[options-section]: #options +[vinyl-instance-section]: #vinyl-instance +[instance-properties-section]: #instance-properties +[normalization-and-concatenation-section]: #normalization-and-concatenation +[glob-base-concepts]: concepts.md#glob-base +[fs-stats-concepts]: concepts.md#file-system-stats +[using-plugins-docs]: ../getting-started/7-using-plugins.md +[cloneable-readable-external]: https://github.com/mcollina/cloneable-readable From 25a22bf571c66cbbe279155a1f2f2876b3571162 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Mon, 24 Sep 2018 14:39:37 -0700 Subject: [PATCH 126/225] Docs: Add Vinyl.isVinyl() documentation --- docs/api/vinyl-isvinyl.md | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 docs/api/vinyl-isvinyl.md diff --git a/docs/api/vinyl-isvinyl.md b/docs/api/vinyl-isvinyl.md new file mode 100644 index 00000000..ab9bf2d0 --- /dev/null +++ b/docs/api/vinyl-isvinyl.md @@ -0,0 +1,41 @@ + + +# Vinyl.isVinyl() + +Determines if an object is a Vinyl instance. Use this method instead of `instanceof`. + +**Note**: This method uses an internal property that some older versions of Vinyl didn't expose resulting in a false negative if using an outdated version. + +## Usage + +```js +const Vinyl = require('vinyl'); + +const file = new Vinyl(); +const notAFile = {}; + +Vinyl.isVinyl(file) === true; +Vinyl.isVinyl(notAFile) === false; +``` + +## Signature + +```js +Vinyl.isVinyl(file); +``` + +### Parameters + +| parameter | type | note | +|:--------------:|:------:|-------| +| file | object | The object to check. | + +### Returns + +True if the `file` object is a Vinyl instance. + From 40ee80163cf952f129e6704d98db496c06f03aab Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Mon, 24 Sep 2018 14:40:04 -0700 Subject: [PATCH 127/225] Docs: Add Vinyl.isCustomProp() documentation --- docs/api/vinyl-iscustomprop.md | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 docs/api/vinyl-iscustomprop.md diff --git a/docs/api/vinyl-iscustomprop.md b/docs/api/vinyl-iscustomprop.md new file mode 100644 index 00000000..d72154d2 --- /dev/null +++ b/docs/api/vinyl-iscustomprop.md @@ -0,0 +1,68 @@ + + +# Vinyl.isCustomProp() + +Determines if a property is internally managed by Vinyl. Used by Vinyl when setting values inside the constructor or when copying properties in the `clone()` instance method. + +This method is useful when extending the Vinyl class. Detailed in [Extending Vinyl][extending-vinyl-section] below. + +## Usage + +```js +const Vinyl = require('vinyl'); + +Vinyl.isCustomProp('sourceMap') === true; +Vinyl.isCustomProp('path') === false; +``` + +## Signature + +```js +Vinyl.isCustomProp(property) +``` + +### Parameters + +| parameter | type | note | +|:--------------:|:------:|-------| +| property | string | The property name to check. | + +### Returns + +True if the property is not internally managed. + +## Extending Vinyl + +When custom properties are managed internally, the static `isCustomProp` method must be extended and return false when one of the custom properties is queried. + +```js +const Vinyl = require('vinyl'); + +const builtInProps = ['foo', '_foo']; + +class SuperFile extends Vinyl { + constructor(options) { + super(options); + this._foo = 'example internal read-only value'; + } + + get foo() { + return this._foo; + } + + static isCustomProp(name) { + return super.isCustomProp(name) && builtInProps.indexOf(name) === -1; + } +} +``` + +In the example above, `foo` and `_foo` will not be assigned to the new object when cloning or passed in `options` to `new SuperFile(options)`. + +If your custom properties or logic require special handling during cloning, override the `clone` method while extending Vinyl. + +[extending-vinyl-section]: #extending-vinyl From 8dd336184f41d13a1d08f75c4f0b944404a73176 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Mon, 24 Sep 2018 14:41:16 -0700 Subject: [PATCH 128/225] Docs: Add API Concepts documentation --- docs/api/concepts.md | 82 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 docs/api/concepts.md diff --git a/docs/api/concepts.md b/docs/api/concepts.md new file mode 100644 index 00000000..666b9b90 --- /dev/null +++ b/docs/api/concepts.md @@ -0,0 +1,82 @@ + + +# Concepts + +The following concepts are prerequisites to understanding the API docs. They will be referenced throughout, refer back to this page for detailed explanations. + +If you're new here, begin with the [Getting Started Guide][quick-start-docs]. + +## Vinyl + +Vinyl is a metadata object that describes a file. The main properties of a Vinyl instance are `path` and `contents` - core aspects of a file on your file system. Vinyl objects can be used to describe files from many sources - on a local file system or any remote storage option. + +## Vinyl adapters + +While Vinyl provides a way to describe a file, a way to access these files is needed. Each file source is accessed using a Vinyl adapter. + +An adapter exposes: +* A method with the signature `src(globs, [options])` and returns a stream that produces Vinyl objects. +* A method with the signature `dest(folder, [options])` and returns a stream that consumes Vinyl objects. +* Any extra methods specific to their input/output medium - such as the `symlink` method `vinyl-fs` provides. They should always return streams that produce and/or consume Vinyl objects. + +## Tasks + +Each gulp task is an asynchronous JavaScript function that either accepts an error-first callback or returns a stream, promise, event emitter, child process, or observable. Due to some platform limitations, synchronous tasks aren't supported. + +For a more detailed explanation, see [Creating Tasks][creating-tasks-doc]. + +## Globs + +A glob is a string of literal and/or wildcard characters, like `*`, `**`, `!`, used to match filepaths. Globbing is the act of locating files on a file system using one or more globs. + +If you don't have experience with globs, see [Explaining Globs][explaining-globs-docs]. + +## Glob base + +A glob base - sometimes called glob parent - is the path segment before any special characters in a glob string. As such, the glob base of `/src/js/**.js` is `/src/js/`. All paths that match the glob are guaranteed to share the glob base since that path segment can't be variable. + +Vinyl instances generated by `src()` are constructed with the glob base set as their `base` property. When written to the file system with `dest()`, the `base` will be removed from the output path so directory structures will be preserved. + +For more in depth information, see the [glob-parent][glob-parent-external] repository. + +## File system stats + +File metadata is provided as an instance of Node's [`fs.Stats`][fs-stats-external]. It is available as the `stat` property on your Vinyl instances and used internally to determine if a Vinyl object represents a directory or symbolic link. When written to the file system, permissions and time values are synchronized from the Vinyl object's `stat` property. + +## File system modes + +File system modes determine what permissions exist for a file. Most files and directories on your file system will have a fairly permissive mode, allowing gulp to read/write/update files on your behalf. By default, gulp will create files with the same permissions as the running process, but you can configure the modes through options in `src()`, `dest()`, etc. If you're experiencing permission (EPERM) issues, check the modes on your files. + +## Modules + +Gulp is made up of many small modules that are pulled together to work cohesively. By utilizing [semver][semver-external] within the small modules, we can release bug fixes and features without publishing new versions of gulp. If you encounter an issue related to one of these modules, open an issue on the individual project repository. + +* [undertaker][undertaker-external] - the task registration system +* [vinyl][vinyl-external] - the virtual file objects +* [vinyl-fs][vinyl-fs-external] - a vinyl adapter to your local file system +* [glob-watcher][glob-watcher-external] - the file watcher +* [bach][bach-external] - task orchestration using `series()` and `parallel()` +* [last-run][last-run-external] - tracks the last run time of a task +* [vinyl-sourcemap][vinyl-sourcemap-external] - built-in sourcemap support +* [gulp-cli][gulp-cli-external] - the command line interface for interacting with gulp + + +[quick-start-docs]: ../getting-started/1-quick-start.md +[creating-tasks-doc]: ../getting-started/3-creating-tasks.md +[explaining-globs-docs]: ../getting-started/6-explaining-globs.md +[undertaker-external]: https://github.com/gulpjs/undertaker +[vinyl-external]: https://github.com/gulpjs/vinyl +[vinyl-fs-external]: https://github.com/gulpjs/vinyl-fs +[glob-watcher-external]: https://github.com/gulpjs/glob-watcher +[bach-external]: https://github.com/gulpjs/bach +[last-run-external]: https://github.com/gulpjs/last-run +[vinyl-sourcemap-external]: https://github.com/gulpjs/vinyl-sourcemap +[gulp-cli-external]: https://github.com/gulpjs/gulp-cli +[semver-external]: https://semver.org +[fs-stats-external]: https://nodejs.org/api/fs.html#fs_class_fs_stats +[glob-parent-external]: https://github.com/es128/glob-parent From d6dd4388ee4bec71c0fe2f78e82d537efd7b0902 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 24 Sep 2018 14:56:11 -0700 Subject: [PATCH 129/225] Docs: Update API Table of Contents --- docs/api/README.md | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/docs/api/README.md b/docs/api/README.md index 387e2787..fe0d498d 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -1,19 +1,16 @@ - +## Table of Contents -## gulp API docs - -* [gulp.src](src.md) - Emit files matching one or more globs -* [gulp.dest](dest.md) - Write files to directories -* [gulp.symlink](symlink.md) - Write files to symlinks -* [gulp.task](task.md) - Define tasks -* [gulp.lastRun](lastRun.md) - Get timestamp of last successful run -* [gulp.parallel](parallel.md) - Run tasks in parallel -* [gulp.series](series.md) - Run tasks in series -* [gulp.watch](watch.md) - Do something when a file changes -* [gulp.tree](tree.md) - Get the tree of tasks -* [gulp.registry](registry.md) - Get or set the task registry +* [API Concepts](concepts.md) +* [src()](src.md) +* [dest()](dest.md) +* [symlink()](symlink.md) +* [lastRun()](lastRun.md) +* [series()](series.md) +* [parallel()](parallel.md) +* [watch()](watch.md) +* [task()](task.md) +* [registry()](registry.md) +* [tree()](tree.md) +* [Vinyl](vinyl.md) +* [Vinyl.isVinyl()](vinyl-isvinyl.md) +* [Vinyl.isCustomProp()](vinyl-iscustomprop.md) From 0a687105507215758e6b05d06d1803d1b3b789a8 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 Oct 2018 11:47:44 -0700 Subject: [PATCH 130/225] Docs: API documentation improvements based on feedback --- docs/api/concepts.md | 4 +++- docs/api/parallel.md | 2 +- docs/api/series.md | 2 +- docs/api/src.md | 4 ++-- docs/api/symlink.md | 2 +- docs/api/task.md | 3 ++- docs/api/vinyl.md | 2 +- 7 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/api/concepts.md b/docs/api/concepts.md index 666b9b90..5c554605 100644 --- a/docs/api/concepts.md +++ b/docs/api/concepts.md @@ -54,7 +54,9 @@ File system modes determine what permissions exist for a file. Most files and di ## Modules -Gulp is made up of many small modules that are pulled together to work cohesively. By utilizing [semver][semver-external] within the small modules, we can release bug fixes and features without publishing new versions of gulp. If you encounter an issue related to one of these modules, open an issue on the individual project repository. +Gulp is made up of many small modules that are pulled together to work cohesively. By utilizing [semver][semver-external] within the small modules, we can release bug fixes and features without publishing new versions of gulp. Often, when you don't see progress on the main repository, work is being done in one of these modules. + +If you're having trouble, ensure your current modules are updated - using the `npm update` command. If the problem persists, open an issue on the individual project repository. * [undertaker][undertaker-external] - the task registration system * [vinyl][vinyl-external] - the virtual file objects diff --git a/docs/api/parallel.md b/docs/api/parallel.md index 4229c845..def9138b 100644 --- a/docs/api/parallel.md +++ b/docs/api/parallel.md @@ -7,7 +7,7 @@ sidebar_label: parallel() # parallel() -Combines task functions and/or composed operations into larger operations that will be executed simultaneously. The composed operations from `series()` and `parallel()` can be nested to any depth. +Combines task functions and/or composed operations into larger operations that will be executed simultaneously. There are no imposed limits on the nesting depth of composed operations using `series()` and `parallel()`. ## Usage diff --git a/docs/api/series.md b/docs/api/series.md index fd2c4987..1f5f71ed 100644 --- a/docs/api/series.md +++ b/docs/api/series.md @@ -7,7 +7,7 @@ sidebar_label: series() # series() -Combines task functions and/or composed operations into larger operations that will be executed one after another, in sequential order. The composed operations from `series()` and `parallel()` can be nested to any depth. +Combines task functions and/or composed operations into larger operations that will be executed one after another, in sequential order. There are no imposed limits on the nesting depth of composed operations using `series()` and `parallel()`. ## Usage diff --git a/docs/api/src.md b/docs/api/src.md index e66a4832..923ee6fd 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -9,7 +9,7 @@ sidebar_label: src() Creates a stream for reading [Vinyl][vinyl-concepts] objects from the file system. -**Note:** Any UTF-8 BOMs will be removed from UTF-8 files read by `src()`, unless disabled using the `removeBOM` option. +**Note:** BOMs (byte order marks) have no purpose in UTF-8 and will be removed from UTF-8 files read by `src()`, unless disabled using the `removeBOM` option. ## Usage @@ -58,7 +58,7 @@ When an invalid glob is given in `globs`, throws an error with the message, "Inv | buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. Contents of large files may not be able to be buffered.
**Note:** Plugins may not implement support for streaming contents. | | read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | | since | date
timestamp
function | | When set, only creates Vinyl objects for files that have been modified since the specified time. | -| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM.. | +| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM. | | sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | | resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | | cwd | string | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [glob-stream][glob-stream-external]._ | diff --git a/docs/api/symlink.md b/docs/api/symlink.md index 7fd1e790..14e3ebd9 100644 --- a/docs/api/symlink.md +++ b/docs/api/symlink.md @@ -10,7 +10,7 @@ sidebar_label: symlink() Creates a stream for linking [Vinyl][vinyl-concepts] objects to the file system. ## Usage -' + ```js const { src, symlink } = require('gulp'); diff --git a/docs/api/task.md b/docs/api/task.md index 698cf843..1eded9fa 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -7,7 +7,7 @@ sidebar_label: task() # task() -**Reminder**: This API isn't the recommended pattern anymore - export your tasks. +**Reminder**: This API isn't the recommended pattern anymore - [export your tasks][creating-tasks-docs]. Defines a task within the task system. The task can then be accessed from the command line and the `series()`, `parallel()`, and `lastRun()` APIs. @@ -106,4 +106,5 @@ task(build); [task-metadata-section]: #task-metadata [task-concepts]: concepts.md#tasks +[creating-tasks-docs]: ../getting-started/3-creating-tasks.md [function-name-external]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name diff --git a/docs/api/vinyl.md b/docs/api/vinyl.md index 5107fb8a..204bf5e3 100644 --- a/docs/api/vinyl.md +++ b/docs/api/vinyl.md @@ -120,7 +120,7 @@ All internally managed paths - any instance property except `contents` and `stat ## Normalization and concatenation -All path properties are normalized by their setters. Concatenate paths with `/`, instead of using `path.join()`, and normalization will occur properly on all platforms. Never concatenate with `\` - it is a valid filename character on posix system. +All path properties are normalized by their setters. Concatenate paths with `/`, instead of using `path.join()`, and normalization will occur properly on all platforms. Never concatenate with `\` - it is a valid filename character on POSIX system. ```js const file = new File(); From df7cdcbec2303c923b3a94c9acf6071c0d1e27c3 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 Oct 2018 13:47:52 -0700 Subject: [PATCH 131/225] Docs: Temporarily point LINK_NEEDED references to documentation-missing.md --- docs/api/registry.md | 2 +- docs/api/src.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/registry.md b/docs/api/registry.md index cd12bc40..9f4b687f 100644 --- a/docs/api/registry.md +++ b/docs/api/registry.md @@ -60,4 +60,4 @@ When a registry without an `init` method is passed as `registryInstance`, throws When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `tasks` function". -[creating-custom-registries]: LINK_NEEDED +[creating-custom-registries]: ../documentation-missing.md diff --git a/docs/api/src.md b/docs/api/src.md index 923ee6fd..ff9912ef 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -118,6 +118,6 @@ src('input/**/*.js', { sourcemaps: true }) [vinyl-concepts]: concepts.md#vinyl [glob-base-concepts]: concepts.md#glob-base [globs-concepts]: concepts.md#globs -[extglob-docs]: LINK_NEEDED +[extglob-docs]: ../documentation-missing.md [node-glob-external]: https://github.com/isaacs/node-glob [glob-stream-external]: https://github.com/gulpjs/glob-stream From 6a8fd8f0c5a8cf30f7521957808ef69bdcdb84db Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 Oct 2018 15:39:18 -0700 Subject: [PATCH 132/225] Docs: Add some more cleanup for Docusaurus --- docs/api/concepts.md | 2 +- docs/api/dest.md | 2 +- docs/api/last-run.md | 2 +- docs/api/parallel.md | 2 +- docs/api/registry.md | 2 +- docs/api/series.md | 2 +- docs/api/src.md | 2 +- docs/api/symlink.md | 2 +- docs/api/task.md | 2 +- docs/api/tree.md | 2 +- docs/api/vinyl-iscustomprop.md | 2 +- docs/api/vinyl-isvinyl.md | 2 +- docs/api/vinyl.md | 6 +++--- docs/api/watch.md | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/api/concepts.md b/docs/api/concepts.md index 5c554605..e0c6f926 100644 --- a/docs/api/concepts.md +++ b/docs/api/concepts.md @@ -1,5 +1,5 @@ -We're in the process of rewriting **all** our documentation and some of the links we've added to completed docs haven't been written yet. You've likely clicked on one of those to end up here. We're sorry about that but please check back later on the topic you're interested in. +# Excuse our dust! + +We're in the process of rewriting **all** our documentation and some of the links we've added to completed docs haven't been written yet. You've likely clicked on one of those to end up here. We're sorry about that but please check back later on the topic you're interested in. If you want to help out, we'll happily accept a Pull Request for this missing documentation. -The Gulp Team From d35653e4270f31490f9e4e1343d6412b0f8fb74b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 Oct 2018 16:20:41 -0700 Subject: [PATCH 135/225] Docs: Fix broken link in lastRun --- docs/api/last-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/last-run.md b/docs/api/last-run.md index e8d0ce5b..e9350bc3 100644 --- a/docs/api/last-run.md +++ b/docs/api/last-run.md @@ -42,7 +42,7 @@ lastRun(task, [precision]) | parameter | type | note | |:--------------:|:------:|-------| | task
**(required)** | function
string | The task function or the string alias of a registered task. | -| precision | number | Default: `1000` on Node v0.10, `0` on Node v0.12+. Detailed in Timestamp precision][timestamp-precision-section] section below. | +| precision | number | Default: `1000` on Node v0.10, `0` on Node v0.12+. Detailed in [Timestamp precision][timestamp-precision-section] section below. | ### Returns From cb673193a25726208b9c8d3177f36872742e2c5a Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 18 Oct 2018 16:55:50 -0700 Subject: [PATCH 136/225] Docs: Added code ticks to "null" where missing (#2243) --- docs/api/vinyl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/vinyl.md b/docs/api/vinyl.md index 84368f16..9fd724cd 100644 --- a/docs/api/vinyl.md +++ b/docs/api/vinyl.md @@ -72,7 +72,7 @@ When any passed options don't conform to the [instance property definitions][ins | path | string | | The full, absolute file path. Will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | | history | array | `[ ]` | An array of paths to pre-populate the `history` of a Vinyl instance. Usually comes from deriving a new Vinyl object from a previous Vinyl object. If `path` and `history` are both passed, `path` is appended to `history`. Each item will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | | stat | object | | An instance of `fs.Stats`, usually the result of calling `fs.stat()` on a file. Used to determine if a Vinyl object represents a directory or symbolic link. | -| contents | ReadableStream
Buffer
null | null | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | +| contents | ReadableStream
Buffer
`null` | `null` | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | Any other properties on `options` will be directly assigned to the Vinyl instance. From 01cfcc5224ee8dac426521d9cfea50ba862e717c Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Wed, 24 Oct 2018 15:13:47 -0700 Subject: [PATCH 137/225] Docs: Improve grammar on Concepts (#2247) --- docs/api/concepts.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api/concepts.md b/docs/api/concepts.md index e0c6f926..3f152905 100644 --- a/docs/api/concepts.md +++ b/docs/api/concepts.md @@ -32,15 +32,15 @@ For a more detailed explanation, see [Creating Tasks][creating-tasks-doc]. ## Globs -A glob is a string of literal and/or wildcard characters, like `*`, `**`, `!`, used to match filepaths. Globbing is the act of locating files on a file system using one or more globs. +A glob is a string of literal and/or wildcard characters, like `*`, `**`, or `!`, used to match filepaths. Globbing is the act of locating files on a file system using one or more globs. If you don't have experience with globs, see [Explaining Globs][explaining-globs-docs]. ## Glob base -A glob base - sometimes called glob parent - is the path segment before any special characters in a glob string. As such, the glob base of `/src/js/**.js` is `/src/js/`. All paths that match the glob are guaranteed to share the glob base since that path segment can't be variable. +A glob base - sometimes called glob parent - is the path segment before any special characters in a glob string. As such, the glob base of `/src/js/**.js` is `/src/js/`. All paths that match the glob are guaranteed to share the glob base - that path segment can't be variable. -Vinyl instances generated by `src()` are constructed with the glob base set as their `base` property. When written to the file system with `dest()`, the `base` will be removed from the output path so directory structures will be preserved. +Vinyl instances generated by `src()` are constructed with the glob base set as their `base` property. When written to the file system with `dest()`, the `base` will be removed from the output path to preserve directory structures. For more in depth information, see the [glob-parent][glob-parent-external] repository. @@ -56,7 +56,7 @@ File system modes determine what permissions exist for a file. Most files and di Gulp is made up of many small modules that are pulled together to work cohesively. By utilizing [semver][semver-external] within the small modules, we can release bug fixes and features without publishing new versions of gulp. Often, when you don't see progress on the main repository, work is being done in one of these modules. -If you're having trouble, ensure your current modules are updated - using the `npm update` command. If the problem persists, open an issue on the individual project repository. +If you're having trouble, ensure your current modules are updated using the `npm update` command. If the problem persists, open an issue on the individual project repository. * [undertaker][undertaker-external] - the task registration system * [vinyl][vinyl-external] - the virtual file objects From eb493a21874b4866f1fe656522d733db1508d6b9 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Wed, 24 Oct 2018 15:31:05 -0700 Subject: [PATCH 138/225] Docs: Improve grammar in src() (#2248) --- docs/api/src.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/src.md b/docs/api/src.md index 8521aeb9..57f249ff 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -55,9 +55,9 @@ When an invalid glob is given in `globs`, throws an error with the message, "Inv | name | type | default | note | |:--------:|:------:|------------|--------| -| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. Contents of large files may not be able to be buffered.
**Note:** Plugins may not implement support for streaming contents. | +| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. It may not be possible to buffer the contents of large files.
**Note:** Plugins may not implement support for streaming contents. | | read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | -| since | date
timestamp
function | | When set, only creates Vinyl objects for files that have been modified since the specified time. | +| since | date
timestamp
function | | When set, only creates Vinyl objects for files modified since the specified time. | | removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM. | | sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | | resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | From c960c1db8db1c2dea8ed1ba5357bc563ff1cd727 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 24 Oct 2018 15:36:28 -0700 Subject: [PATCH 139/225] Docs: Remove spaces around
--- docs/api/dest.md | 18 ++++++------ docs/api/last-run.md | 2 +- docs/api/parallel.md | 2 +- docs/api/series.md | 2 +- docs/api/src.md | 68 ++++++++++++++++++++++---------------------- docs/api/symlink.md | 12 ++++---- docs/api/task.md | 4 +-- docs/api/vinyl.md | 4 +-- docs/api/watch.md | 40 +++++++++++++------------- 9 files changed, 76 insertions(+), 76 deletions(-) diff --git a/docs/api/dest.md b/docs/api/dest.md index 2a29c2e6..d4b6fe42 100644 --- a/docs/api/dest.md +++ b/docs/api/dest.md @@ -32,7 +32,7 @@ dest(directory, [options]) | parameter | type | note | |:--------------:|:-----:|--------| -| directory
**(required)** | string
function | The path of the output directory where files will be written. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | +| directory
**(required)** | string
function | The path of the output directory where files will be written. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -60,14 +60,14 @@ When `directory` is a function that returns an empty string or `undefined`, emit | name | type | default | note | |:-------:|:------:|-----------|-------| -| cwd | string
function | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | -| mode | number
function | `stat.mode` of the Vinyl object | The mode used when creating files. If not set and `stat.mode` is missing, the process' mode will be used instead. | -| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | -| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | -| append | boolean
function | false | If true, adds contents to the end of the file, instead of replacing existing contents. | -| sourcemaps | boolean
string
function | false | If true, writes inline sourcemaps to the output file. Specifying a `string` path will write external [sourcemaps][sourcemaps-section] at the given path. | -| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | -| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | +| cwd | string
function | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | +| mode | number
function | `stat.mode` of the Vinyl object | The mode used when creating files. If not set and `stat.mode` is missing, the process' mode will be used instead. | +| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | +| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | +| append | boolean
function | false | If true, adds contents to the end of the file, instead of replacing existing contents. | +| sourcemaps | boolean
string
function | false | If true, writes inline sourcemaps to the output file. Specifying a `string` path will write external [sourcemaps][sourcemaps-section] at the given path. | +| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | +| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | ## Metadata updates diff --git a/docs/api/last-run.md b/docs/api/last-run.md index e9350bc3..cf61b31a 100644 --- a/docs/api/last-run.md +++ b/docs/api/last-run.md @@ -41,7 +41,7 @@ lastRun(task, [precision]) | parameter | type | note | |:--------------:|:------:|-------| -| task
**(required)** | function
string | The task function or the string alias of a registered task. | +| task
**(required)** | function
string | The task function or the string alias of a registered task. | | precision | number | Default: `1000` on Node v0.10, `0` on Node v0.12+. Detailed in [Timestamp precision][timestamp-precision-section] section below. | ### Returns diff --git a/docs/api/parallel.md b/docs/api/parallel.md index bb7d67cd..c349a880 100644 --- a/docs/api/parallel.md +++ b/docs/api/parallel.md @@ -37,7 +37,7 @@ parallel(...tasks) | parameter | type | note | |:--------------:|:------:|-------| -| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | +| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | ### Returns diff --git a/docs/api/series.md b/docs/api/series.md index 49609d42..0d59a8ca 100644 --- a/docs/api/series.md +++ b/docs/api/series.md @@ -37,7 +37,7 @@ series(...tasks) | parameter | type | note | |:--------------:|:------:|-------| -| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | +| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | ### Returns diff --git a/docs/api/src.md b/docs/api/src.md index 57f249ff..243fd9fd 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -35,7 +35,7 @@ src(globs, [options]) | parameter | type | note | |:--------------:|:------:|-------| -| globs | string
array | [Globs][globs-concepts] to watch on the file system. | +| globs | string
array | [Globs][globs-concepts] to watch on the file system. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -55,39 +55,39 @@ When an invalid glob is given in `globs`, throws an error with the message, "Inv | name | type | default | note | |:--------:|:------:|------------|--------| -| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. It may not be possible to buffer the contents of large files.
**Note:** Plugins may not implement support for streaming contents. | -| read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | -| since | date
timestamp
function | | When set, only creates Vinyl objects for files modified since the specified time. | -| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM. | -| sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | -| resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | -| cwd | string | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| base | string | | Explicitly set the `base` property on created Vinyl objects. Detailed in [API Concepts][glob-base-concepts].
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| cwdbase | boolean | false | If true, `cwd` and `base` options should be aligned.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| root | string | | The root path that `globs` are resolved against.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| allowEmpty | boolean | false | When false, `globs` which can only match one file (such as `foo/bar.js`) causes an error to be thrown if they don't find a match. If true, suppresses glob failures.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| uniqueBy | string
function | `'path'` | Remove duplicates from the stream by comparing the string property name or the result of the function.
**Note:** When using a function, the function receives the streamed data (objects containing `cwd`, `base`, `path` properties). | -| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| silent | boolean | true | When true, suppresses warnings from printing on `stderr`.
**Note:** This option is passed directly to [node-glob][node-glob-external] but defaulted to `true` instead of `false`. | -| mark | boolean | false | If true, a `/` character will be appended to directory matches. Generally not needed because paths are normalized within the pipeline.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nosort | boolean | false | If true, disables sorting the glob results.
_This option is passed directly to [node-glob][node-glob-external]._ | -| stat | boolean | false | If true, `fs.stat()` is called on all results. This adds extra overhead and generally should not be used.
_This option is passed directly to [node-glob][node-glob-external]._ | -| strict | boolean | false | If true, an error will be thrown if an unexpected problem is encountered while attempting to read a directory.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [node-glob][node-glob-external]._ | -| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [node-glob][node-glob-external]._ | -| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [node-glob][node-glob-external]._ | -| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nodir | boolean | false | If true, only matches files, not directories.
**Note:** To match only directories, end your glob with a `/`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [node-glob][node-glob-external]._ | -| follow | boolean | false | If true, symlinked directories will be traversed when expanding `**` globs.
**Note:** This can cause problems with cyclical links.
_This option is passed directly to [node-glob][node-glob-external]._ | -| realpath | boolean | false | If true, `fs.realpath()` is called on all results. This may result in dangling links.
_This option is passed directly to [node-glob][node-glob-external]._ | -| cache | object | | A previously generated cache object - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| statCache | object | | A previously generated cache of `fs.Stat` results - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| symlinks | object | | A previously generated cache of symbolic links - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nocomment | boolean | false | When false, treat a `#` character at the start of a glob as a comment.
_This option is passed directly to [node-glob][node-glob-external]._ | +| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. It may not be possible to buffer the contents of large files.
**Note:** Plugins may not implement support for streaming contents. | +| read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | +| since | date
timestamp
function | | When set, only creates Vinyl objects for files modified since the specified time. | +| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM. | +| sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | +| resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | +| cwd | string | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| base | string | | Explicitly set the `base` property on created Vinyl objects. Detailed in [API Concepts][glob-base-concepts].
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| cwdbase | boolean | false | If true, `cwd` and `base` options should be aligned.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| root | string | | The root path that `globs` are resolved against.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| allowEmpty | boolean | false | When false, `globs` which can only match one file (such as `foo/bar.js`) causes an error to be thrown if they don't find a match. If true, suppresses glob failures.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| uniqueBy | string
function | `'path'` | Remove duplicates from the stream by comparing the string property name or the result of the function.
**Note:** When using a function, the function receives the streamed data (objects containing `cwd`, `base`, `path` properties). | +| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| silent | boolean | true | When true, suppresses warnings from printing on `stderr`.
**Note:** This option is passed directly to [node-glob][node-glob-external] but defaulted to `true` instead of `false`. | +| mark | boolean | false | If true, a `/` character will be appended to directory matches. Generally not needed because paths are normalized within the pipeline.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nosort | boolean | false | If true, disables sorting the glob results.
_This option is passed directly to [node-glob][node-glob-external]._ | +| stat | boolean | false | If true, `fs.stat()` is called on all results. This adds extra overhead and generally should not be used.
_This option is passed directly to [node-glob][node-glob-external]._ | +| strict | boolean | false | If true, an error will be thrown if an unexpected problem is encountered while attempting to read a directory.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [node-glob][node-glob-external]._ | +| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [node-glob][node-glob-external]._ | +| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [node-glob][node-glob-external]._ | +| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nodir | boolean | false | If true, only matches files, not directories.
**Note:** To match only directories, end your glob with a `/`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [node-glob][node-glob-external]._ | +| follow | boolean | false | If true, symlinked directories will be traversed when expanding `**` globs.
**Note:** This can cause problems with cyclical links.
_This option is passed directly to [node-glob][node-glob-external]._ | +| realpath | boolean | false | If true, `fs.realpath()` is called on all results. This may result in dangling links.
_This option is passed directly to [node-glob][node-glob-external]._ | +| cache | object | | A previously generated cache object - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| statCache | object | | A previously generated cache of `fs.Stat` results - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| symlinks | object | | A previously generated cache of symbolic links - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nocomment | boolean | false | When false, treat a `#` character at the start of a glob as a comment.
_This option is passed directly to [node-glob][node-glob-external]._ | ## Sourcemaps diff --git a/docs/api/symlink.md b/docs/api/symlink.md index 7042295c..fcdee880 100644 --- a/docs/api/symlink.md +++ b/docs/api/symlink.md @@ -32,7 +32,7 @@ symlink(directory, [options]) | parameter | type | note | |:--------------:|:-----:|--------| -| directory
**(required)** | string
function | The path of the output directory where symbolic links will be created. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | +| directory
**(required)** | string
function | The path of the output directory where symbolic links will be created. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -63,11 +63,11 @@ When `directory` is a function that returns an empty string or `undefined`, emit | name | type | default | note | |:-------:|:------:|-----------|-------| -| cwd | string
function | `process.cwd()` |The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | -| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | -| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | -| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | -| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | +| cwd | string
function | `process.cwd()` |The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | +| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | +| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | +| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | +| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | ## Symbolic links on Windows diff --git a/docs/api/task.md b/docs/api/task.md index 27e95cd0..0fb2ecb4 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -62,7 +62,7 @@ Since any registered task can be run from the command line, avoid using spaces i | parameter | type | note | |:--------------:|:------:|-------| | taskName | string | An alias for the task function within the the task system. Not needed when using named functions for `taskFunction`. | -| taskFunction
**(required)** | function | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | +| taskFunction
**(required)** | function | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | ### Returns @@ -78,7 +78,7 @@ When registering a task where `taskName` is missing and `taskFunction` is anonym | property | type | note | |:--------------:|:------:|-------| -| name | string | A special property of named functions. Used to register the task.
**Note:** [`name`][function-name-external] is not writable; it cannot be set or changed. | +| name | string | A special property of named functions. Used to register the task.
**Note:** [`name`][function-name-external] is not writable; it cannot be set or changed. | | displayName | string | When attached to a `taskFunction` creates an alias for the task. If using characters that aren't allowed in function names, use this property. | | description | string | When attached to a `taskFunction` provides a description to be printed by the command line when listing tasks. | | flags | object | When attached to a `taskFunction` provides flags to be printed by the command line when listing tasks. The keys of the object represent the flags and the values are their descriptions. | diff --git a/docs/api/vinyl.md b/docs/api/vinyl.md index 9fd724cd..771a6c2e 100644 --- a/docs/api/vinyl.md +++ b/docs/api/vinyl.md @@ -72,7 +72,7 @@ When any passed options don't conform to the [instance property definitions][ins | path | string | | The full, absolute file path. Will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | | history | array | `[ ]` | An array of paths to pre-populate the `history` of a Vinyl instance. Usually comes from deriving a new Vinyl object from a previous Vinyl object. If `path` and `history` are both passed, `path` is appended to `history`. Each item will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | | stat | object | | An instance of `fs.Stats`, usually the result of calling `fs.stat()` on a file. Used to determine if a Vinyl object represents a directory or symbolic link. | -| contents | ReadableStream
Buffer
`null` | `null` | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | +| contents | ReadableStream
Buffer
`null` | `null` | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | Any other properties on `options` will be directly assigned to the Vinyl instance. @@ -93,7 +93,7 @@ All internally managed paths - any instance property except `contents` and `stat | property | type | description | throws | |:-----------:|:------:|----------------|----------| -| contents | ReadableStream
Buffer
`null` | Gets and sets the contents of the virtual file. If set to a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | If set to any value other than a ReadableStream, a Buffer, or `null`. | +| contents | ReadableStream
Buffer
`null` | Gets and sets the contents of the virtual file. If set to a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | If set to any value other than a ReadableStream, a Buffer, or `null`. | | stat | object | Gets and sets an instance of [`fs.Stats`][fs-stats-concepts]. Used when determining if a Vinyl object represents a directory or symbolic link. | | | cwd | string | Gets and sets the current working directory. Used for deriving relative paths. | If set to an empty string or any non-string value. | | base | string | Gets and sets the base directory. Used to calculate the `relative` instance property. On a Vinyl object generated by `src()` will be set to the [glob base][glob-base-concepts]. If set to `null` or `undefined`, falls back to the value of the `cwd` instance property. | If set to an empty string or any non-string value (except `null` or `undefined`). | diff --git a/docs/api/watch.md b/docs/api/watch.md index 348396b4..3c0fce72 100644 --- a/docs/api/watch.md +++ b/docs/api/watch.md @@ -30,9 +30,9 @@ watch(globs, [options], [task]) | parameter | type | note | |:--------------:|:-----:|--------| -| globs
**(required)** | string
array | [Globs][globs-concepts] to watch on the file system. | +| globs
**(required)** | string
array | [Globs][globs-concepts] to watch on the file system. | | options | object | Detailed in [Options][options-section] below. | -| task | function
string | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. | +| task | function
string | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. | ### Returns @@ -49,24 +49,24 @@ When a string or array is passed as `task`, throws an error with the message, "w | name | type | default | note | |:-------:|:------:|-----------|--------| -| ignoreInitial | boolean | true | If false, the task is called during instantiation as file paths are discovered. Use to trigger the task during startup.
**Note:** This option is passed to [chokidar][chokidar-external] but is defaulted to `true` instead of `false`. | +| ignoreInitial | boolean | true | If false, the task is called during instantiation as file paths are discovered. Use to trigger the task during startup.
**Note:** This option is passed to [chokidar][chokidar-external] but is defaulted to `true` instead of `false`. | | delay | number | 200 | The millisecond delay between a file change and task execution. Allows for waiting on many changes before executing a task, e.g. find-and-replace on many files. | | queue | boolean | true | When true and the task is already running, any file changes will queue a single task execution. Keeps long running tasks from overlapping. | -| events | string
array | [ 'add',
'change',
'unlink' ] | The events being watched to trigger task execution. Can be `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, and/or `'error'`. Additionally `'all'` is available, which represents all events other than `'ready'` and `'error'`.
_This option is passed directly to [chokidar][chokidar-external]._ | -| persistent | boolean | true | If false, the watcher will not keep the Node process running. Disabling this option is not recommended.
_This option is passed directly to [chokidar][chokidar-external]._ | -| ignored | array
string
RegExp
function | | Defines globs to be ignored. If a function is provided, it will be called twice per path - once with just the path, then with the path and the `fs.Stats` object of that file.
_This option is passed directly to [chokidar][chokidar-external]._ | -| followSymlinks | boolean | true | When true, changes to both symbolic links and the linked files trigger events. If false, only changes to the symbolic links trigger events.
_This option is passed directly to [chokidar][chokidar-external]._ | -| cwd | string | | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [chokidar][chokidar-external]._ | -| disableGlobbing | boolean | false | If true, all `globs` are treated as literal path names, even if they have special characters.
_This option is passed directly to [chokidar][chokidar-external]._ | -| usePolling | boolean | false | When false, the watcher will use `fs.watch()` (or [fsevents][fsevents-external] on Mac) for watching. If true, use `fs.watchFile()` polling instead - needed for successfully watching files over a network or other non-standard situations. Overrides the `useFsEvents` default.
_This option is passed directly to [chokidar][chokidar-external]._ | -| interval | number | 100 | Combine with `usePolling: true`. Interval of file system polling.
_This option is passed directly to [chokidar][chokidar-external]._ | -| binaryInterval | number | 300 | Combine with `usePolling: true`. Interval of file system polling for binary files.
_This option is passed directly to [chokidar][chokidar-external]._ | -| useFsEvents | boolean | true | When true, uses fsevents for watching if available. If explicitly set to true, supersedes the `usePolling` option. If set to false, automatically sets `usePolling` to true.
_This option is passed directly to [chokidar][chokidar-external]._ | -| alwaysStat | boolean | false | If true, always calls `fs.stat()` on changed files - will slow down file watcher. The `fs.Stat` object is only available if you are using the chokidar instance directly.
_This option is passed directly to [chokidar][chokidar-external]._ | -| depth | number | | Indicates how many nested levels of directories will be watched.
_This option is passed directly to [chokidar][chokidar-external]._ | -| awaitWriteFinish | boolean | false | Do not use this option, use `delay` instead.
_This option is passed directly to [chokidar][chokidar-external]._ | -| ignorePermissionErrors | boolean | false | Set to true to watch files that don't have read permissions. Then, if watching fails due to EPERM or EACCES errors, they will be skipped silently.
_This option is passed directly to [chokidar][chokidar-external]._ | -| atomic | number | 100 | Only active if `useFsEvents` and `usePolling` are false. Automatically filters out artifacts that occur from "atomic writes" by some editors. If a file is re-added within the specified milliseconds of being deleted, a change event - instead of unlink then add - will be emitted.
_This option is passed directly to [chokidar][chokidar-external]._ | +| events | string
array | [ 'add',
'change',
'unlink' ] | The events being watched to trigger task execution. Can be `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, and/or `'error'`. Additionally `'all'` is available, which represents all events other than `'ready'` and `'error'`.
_This option is passed directly to [chokidar][chokidar-external]._ | +| persistent | boolean | true | If false, the watcher will not keep the Node process running. Disabling this option is not recommended.
_This option is passed directly to [chokidar][chokidar-external]._ | +| ignored | array
string
RegExp
function | | Defines globs to be ignored. If a function is provided, it will be called twice per path - once with just the path, then with the path and the `fs.Stats` object of that file.
_This option is passed directly to [chokidar][chokidar-external]._ | +| followSymlinks | boolean | true | When true, changes to both symbolic links and the linked files trigger events. If false, only changes to the symbolic links trigger events.
_This option is passed directly to [chokidar][chokidar-external]._ | +| cwd | string | | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [chokidar][chokidar-external]._ | +| disableGlobbing | boolean | false | If true, all `globs` are treated as literal path names, even if they have special characters.
_This option is passed directly to [chokidar][chokidar-external]._ | +| usePolling | boolean | false | When false, the watcher will use `fs.watch()` (or [fsevents][fsevents-external] on Mac) for watching. If true, use `fs.watchFile()` polling instead - needed for successfully watching files over a network or other non-standard situations. Overrides the `useFsEvents` default.
_This option is passed directly to [chokidar][chokidar-external]._ | +| interval | number | 100 | Combine with `usePolling: true`. Interval of file system polling.
_This option is passed directly to [chokidar][chokidar-external]._ | +| binaryInterval | number | 300 | Combine with `usePolling: true`. Interval of file system polling for binary files.
_This option is passed directly to [chokidar][chokidar-external]._ | +| useFsEvents | boolean | true | When true, uses fsevents for watching if available. If explicitly set to true, supersedes the `usePolling` option. If set to false, automatically sets `usePolling` to true.
_This option is passed directly to [chokidar][chokidar-external]._ | +| alwaysStat | boolean | false | If true, always calls `fs.stat()` on changed files - will slow down file watcher. The `fs.Stat` object is only available if you are using the chokidar instance directly.
_This option is passed directly to [chokidar][chokidar-external]._ | +| depth | number | | Indicates how many nested levels of directories will be watched.
_This option is passed directly to [chokidar][chokidar-external]._ | +| awaitWriteFinish | boolean | false | Do not use this option, use `delay` instead.
_This option is passed directly to [chokidar][chokidar-external]._ | +| ignorePermissionErrors | boolean | false | Set to true to watch files that don't have read permissions. Then, if watching fails due to EPERM or EACCES errors, they will be skipped silently.
_This option is passed directly to [chokidar][chokidar-external]._ | +| atomic | number | 100 | Only active if `useFsEvents` and `usePolling` are false. Automatically filters out artifacts that occur from "atomic writes" by some editors. If a file is re-added within the specified milliseconds of being deleted, a change event - instead of unlink then add - will be emitted.
_This option is passed directly to [chokidar][chokidar-external]._ | ## Chokidar instance @@ -119,7 +119,7 @@ Adds additional globs to an already-running watcher instance. | parameter | type | note | |:-------------:|:-----:|--------| -| globs | string
array | The additional globs to be watched. | +| globs | string
array | The additional globs to be watched. | `watcher.unwatch(globs)` @@ -127,7 +127,7 @@ Removes globs that are being watched, while the watcher continues with the remai | parameter | type | note | |:-------------:|:-----:|--------| -| globs | string
array | The globs to be removed. | +| globs | string
array | The globs to be removed. | [chokidar-instance-section]: #chokidar-instance [tasks-concepts]: ../api/concepts.md#tasks From ca6ba3559603ad2c3d7e63a1d98d88ef442d7c0c Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 25 Oct 2018 10:44:51 -0700 Subject: [PATCH 140/225] Docs: Fix formatting error (#2250) --- docs/api/symlink.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/api/symlink.md b/docs/api/symlink.md index fcdee880..a84665ed 100644 --- a/docs/api/symlink.md +++ b/docs/api/symlink.md @@ -71,15 +71,15 @@ When `directory` is a function that returns an empty string or `undefined`, emit ## Symbolic links on Windows -When creating symbolic links on Windows, a `type` argument is passed to Node's `fs.symlink()` method which specifies the type of target being linked. The link type is set to: -`'file'` when the target is a regular file -`'junction'` when the target is a directory -`'dir'` when the target is a directory and the user disables the `useJunctions` option +When creating symbolic links on Windows, a `type` argument is passed to Node's `fs.symlink()` method which specifies the type of target being linked. The link type is set to: +* `'file'` when the target is a regular file +* `'junction'` when the target is a directory +* `'dir'` when the target is a directory and the user disables the `useJunctions` option If you try to create a dangling (pointing to a non-existent target) link, the link type can't be determined automatically. In these cases, behavior will vary depending on whether the dangling link is being created via `symlink()` or via `dest()`. -For dangling links created via `symlink()`, the incoming Vinyl object represents the target, so its stats will determine the desired link type. If `isDirectory()` returns false then a `'file'` link is created, otherwise a `'junction'` or a `'dir'` link is created depending on the value of the `useJunctions` option. +For dangling links created via `symlink()`, the incoming Vinyl object represents the target, so its stats will determine the desired link type. If `isDirectory()` returns false then a `'file'` link is created, otherwise a `'junction'` or `'dir'` link is created depending on the value of the `useJunctions` option. For dangling links created via `dest()`, the incoming Vinyl object represents the link - typically loaded from disk via `src(..., { resolveSymlinks: false })`. In this case, the link type can't be reasonably determined and defaults to using `'file'`. This may cause unexpected behavior when creating a dangling link to a directory. **Avoid this scenario.** From 8569f85d9e5c84779fe35621a82a2ff00a81186f Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 25 Oct 2018 11:04:30 -0700 Subject: [PATCH 141/225] Docs: Fix formatting of lastRun (#2251) --- docs/api/last-run.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/last-run.md b/docs/api/last-run.md index cf61b31a..4daa2abf 100644 --- a/docs/api/last-run.md +++ b/docs/api/last-run.md @@ -9,7 +9,7 @@ sidebar_label: lastRun() Retrieves the last time a task was successfully completed during the current running process. Most useful on subsequent task runs while a watcher is running. -When combined with `src()`, enables incremental builds to speed up your execution times by skipping files that haven't changed since the last successful task completion. +When combined with `src()`, enables incremental builds to speed up execution times by skipping files that haven't changed since the last successful task completion. ## Usage @@ -64,7 +64,7 @@ While there are sensible defaults for the precision of timestamps, they can be r * `lastRun(someTask, 100)` returns 1426000001100 * `lastRun(someTask, 1000)` returns 1426000001000 -A file's [mtime stat][fs-stats-concepts] precision may vary depending on the node version and/or the file system used: +A file's [mtime stat][fs-stats-concepts] precision may vary depending on the node version and/or the file system used. | platform | precision | From e35bdac100d20bfd700a3565961d86a3d077f11c Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 25 Oct 2018 13:10:23 -0700 Subject: [PATCH 142/225] Docs: Add missing link in watch (#2252) --- docs/api/watch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/watch.md b/docs/api/watch.md index 3c0fce72..2b9dde27 100644 --- a/docs/api/watch.md +++ b/docs/api/watch.md @@ -46,7 +46,6 @@ When a string or array is passed as `task`, throws an error with the message, "w ### Options - | name | type | default | note | |:-------:|:------:|-----------|--------| | ignoreInitial | boolean | true | If false, the task is called during instantiation as file paths are discovered. Use to trigger the task during startup.
**Note:** This option is passed to [chokidar][chokidar-external] but is defaulted to `true` instead of `false`. | @@ -130,6 +129,7 @@ Removes globs that are being watched, while the watcher continues with the remai | globs | string
array | The globs to be removed. | [chokidar-instance-section]: #chokidar-instance +[options-section]: #options [tasks-concepts]: ../api/concepts.md#tasks [globs-concepts]: ../api/concepts.md#globs [fs-stats-concepts]: ../api/concepts.md#file-system-stats From 6d43750a62f324870d81361c933e3b882f7e3980 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 25 Oct 2018 14:03:04 -0700 Subject: [PATCH 143/225] Docs: Fix broken link in tasks (#2253) --- docs/api/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/task.md b/docs/api/task.md index 0fb2ecb4..12919b06 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -62,7 +62,7 @@ Since any registered task can be run from the command line, avoid using spaces i | parameter | type | note | |:--------------:|:------:|-------| | taskName | string | An alias for the task function within the the task system. Not needed when using named functions for `taskFunction`. | -| taskFunction
**(required)** | function | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | +| taskFunction
**(required)** | function | A [task function][task-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | ### Returns From 8e9fd70e17d0bfc3cb68f22610b813097f249ef3 Mon Sep 17 00:00:00 2001 From: Janice Niemeir Date: Thu, 25 Oct 2018 14:04:08 -0700 Subject: [PATCH 144/225] Docs: Improve punctuation in tree (#2254) --- docs/api/tree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/tree.md b/docs/api/tree.md index e106009f..1dcfed6d 100644 --- a/docs/api/tree.md +++ b/docs/api/tree.md @@ -166,7 +166,7 @@ An object detailing the tree of registered tasks - containing nested objects wit Each object may have a `type` property that can be used to determine if the node is a `task` or `function`. -Each object may have a `branch` property that - when `true` - indicates the node was created using `series()` or `parallel()`. +Each object may have a `branch` property that, when `true`, indicates the node was created using `series()` or `parallel()`. ### Options From 96c353d082b340f6b32fdfd354437940869241af Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 25 Oct 2018 17:43:12 -0700 Subject: [PATCH 145/225] Docs: Fix mistake in "Splitting a gulpfile" (fixes #2255) --- docs/getting-started/2-javascript-and-gulpfiles.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/getting-started/2-javascript-and-gulpfiles.md b/docs/getting-started/2-javascript-and-gulpfiles.md index b82193f3..6ccc8161 100644 --- a/docs/getting-started/2-javascript-and-gulpfiles.md +++ b/docs/getting-started/2-javascript-and-gulpfiles.md @@ -28,8 +28,7 @@ Many users start by adding all logic to a gulpfile. If it ever grows too big, it Each task can be split into its own file, then imported into your gulpfile for composition. Not only does this keep things organized, but it allows you to test each task independently or vary composition based on conditions. -Node's module resolution allows you to replace your `gulpfile.js` with a directory called `gulpfile` that contains an `index.js` file which is treated as a `gulpfile.js`. This directory could then contain your individual modules for tasks. - +Node's module resolution allows you to replace your `gulpfile.js` file with a directory named `gulpfile.js` that contains an `index.js` file which is treated as a `gulpfile.js`. This directory could then contain your individual modules for tasks. [gulpfile-transpilation-advanced]: ../documentation-missing.md [ts-node-module]: https://www.npmjs.com/package/ts-node From c5af6f18f5532628e20a3c187db9a99a96043c05 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 2 Nov 2018 20:56:05 -0700 Subject: [PATCH 146/225] Docs: Remove front-matter from outdated pages --- docs/CLI.md | 7 ------- docs/FAQ.md | 7 ------- docs/README.md | 7 ------- docs/recipes/README.md | 7 ------- docs/recipes/automate-release-workflow.md | 7 ------- docs/recipes/browserify-multiple-destination.md | 7 ------- docs/recipes/browserify-transforms.md | 7 ------- docs/recipes/browserify-uglify-sourcemap.md | 7 ------- docs/recipes/browserify-with-globs.md | 7 ------- docs/recipes/combining-streams-to-handle-errors.md | 7 ------- docs/recipes/cron-task.md | 7 ------- docs/recipes/delete-files-folder.md | 7 ------- docs/recipes/exports-as-tasks.md | 7 ------- docs/recipes/fast-browserify-builds-with-watchify.md | 7 ------- docs/recipes/handling-the-delete-event-on-watch.md | 7 ------- docs/recipes/incremental-builds-with-concatenate.md | 7 ------- .../maintain-directory-structure-while-globbing.md | 7 ------- docs/recipes/make-stream-from-buffer.md | 7 ------- docs/recipes/minified-and-non-minified.md | 7 ------- docs/recipes/minimal-browsersync-setup-with-gulp4.md | 7 ------- docs/recipes/mocha-test-runner-with-gulp.md | 7 ------- docs/recipes/only-pass-through-changed-files.md | 7 ------- docs/recipes/pass-arguments-from-cli.md | 7 ------- docs/recipes/rebuild-only-files-that-change.md | 7 ------- docs/recipes/rollup-with-rollup-stream.md | 7 ------- docs/recipes/run-grunt-tasks-from-gulp.md | 7 ------- docs/recipes/running-shell-commands.md | 7 ------- docs/recipes/running-task-steps-per-folder.md | 11 ++--------- docs/recipes/running-tasks-in-series.md | 7 ------- .../server-with-livereload-and-css-injection.md | 7 ------- docs/recipes/sharing-streams-with-stream-factories.md | 7 ------- docs/recipes/specifying-a-cwd.md | 7 ------- docs/recipes/split-tasks-across-multiple-files.md | 7 ------- .../templating-with-swig-and-yaml-front-matter.md | 7 ------- docs/recipes/using-external-config-file.md | 7 ------- docs/recipes/using-multiple-sources-in-one-task.md | 7 ------- docs/why-use-pump/README.md | 7 ------- docs/writing-a-plugin/README.md | 7 ------- docs/writing-a-plugin/dealing-with-streams.md | 7 ------- docs/writing-a-plugin/guidelines.md | 7 ------- docs/writing-a-plugin/recommended-modules.md | 7 ------- docs/writing-a-plugin/testing.md | 7 ------- docs/writing-a-plugin/using-buffers.md | 7 ------- 43 files changed, 2 insertions(+), 303 deletions(-) diff --git a/docs/CLI.md b/docs/CLI.md index daa3f5d0..68510412 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -1,10 +1,3 @@ - - ## gulp CLI docs ### Flags diff --git a/docs/FAQ.md b/docs/FAQ.md index 9c89c143..f8a649ea 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -1,10 +1,3 @@ - - # FAQ ## Why gulp? Why not ____? diff --git a/docs/README.md b/docs/README.md index c783b710..9b5955ac 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,10 +1,3 @@ - - # gulp documentation * [Getting Started](getting-started/) - Get started with gulp diff --git a/docs/recipes/README.md b/docs/recipes/README.md index e1ec3721..3e822432 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -1,10 +1,3 @@ - - # Recipes * [Automate release workflow](automate-release-workflow.md) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-release-workflow.md index 3b929866..0f18006a 100644 --- a/docs/recipes/automate-release-workflow.md +++ b/docs/recipes/automate-release-workflow.md @@ -1,10 +1,3 @@ - - # Automate release workflow If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release. diff --git a/docs/recipes/browserify-multiple-destination.md b/docs/recipes/browserify-multiple-destination.md index fa1b65ce..474f5828 100644 --- a/docs/recipes/browserify-multiple-destination.md +++ b/docs/recipes/browserify-multiple-destination.md @@ -1,10 +1,3 @@ - - # Browserify + Globs (multiple destination) This example shows how to set up a task of bundling multiple entry points into multiple destinations using browserify. diff --git a/docs/recipes/browserify-transforms.md b/docs/recipes/browserify-transforms.md index 8659614f..47a0d4d5 100644 --- a/docs/recipes/browserify-transforms.md +++ b/docs/recipes/browserify-transforms.md @@ -1,10 +1,3 @@ - - # Browserify + Transforms [Browserify](https://github.com/browserify/browserify) has become an important and indispensable diff --git a/docs/recipes/browserify-uglify-sourcemap.md b/docs/recipes/browserify-uglify-sourcemap.md index 99800ed5..58e62229 100644 --- a/docs/recipes/browserify-uglify-sourcemap.md +++ b/docs/recipes/browserify-uglify-sourcemap.md @@ -1,10 +1,3 @@ - - # Browserify + Uglify2 with sourcemaps [Browserify](https://github.com/browserify/browserify) has become an important and indispensable diff --git a/docs/recipes/browserify-with-globs.md b/docs/recipes/browserify-with-globs.md index d9396f1b..72695fb6 100644 --- a/docs/recipes/browserify-with-globs.md +++ b/docs/recipes/browserify-with-globs.md @@ -1,10 +1,3 @@ - - # Browserify + Globs [Browserify + Uglify2](https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-uglify-sourcemap.md) shows how to setup a basic gulp task to bundle a JavaScript file with its dependencies, and minify the bundle with UglifyJS while preserving source maps. diff --git a/docs/recipes/combining-streams-to-handle-errors.md b/docs/recipes/combining-streams-to-handle-errors.md index 16b56166..7c38654a 100644 --- a/docs/recipes/combining-streams-to-handle-errors.md +++ b/docs/recipes/combining-streams-to-handle-errors.md @@ -1,10 +1,3 @@ - - # Combining streams to handle errors By default, emitting an error on a stream will cause it to be thrown unless it already has a listener attached to the `error` event. This gets a bit tricky when you're working with longer pipelines of streams. diff --git a/docs/recipes/cron-task.md b/docs/recipes/cron-task.md index ad90a6f0..316e0c9b 100644 --- a/docs/recipes/cron-task.md +++ b/docs/recipes/cron-task.md @@ -1,10 +1,3 @@ - - # Run gulp task via cron job While logged in via a user that has privileges to run `gulp`, run the following: diff --git a/docs/recipes/delete-files-folder.md b/docs/recipes/delete-files-folder.md index 731ae4f9..59e9cc93 100644 --- a/docs/recipes/delete-files-folder.md +++ b/docs/recipes/delete-files-folder.md @@ -1,10 +1,3 @@ - - # Delete files and folders You might want to delete some files before running your build. Since deleting files doesn't work on the file contents, there's no reason to use a gulp plugin. An excellent opportunity to use a vanilla node module. diff --git a/docs/recipes/exports-as-tasks.md b/docs/recipes/exports-as-tasks.md index 892c6bbf..2eaea490 100644 --- a/docs/recipes/exports-as-tasks.md +++ b/docs/recipes/exports-as-tasks.md @@ -1,10 +1,3 @@ - - # Exports as Tasks Using the ES2015 module syntax you can use your exports as tasks. diff --git a/docs/recipes/fast-browserify-builds-with-watchify.md b/docs/recipes/fast-browserify-builds-with-watchify.md index aa07f1a9..5513068c 100644 --- a/docs/recipes/fast-browserify-builds-with-watchify.md +++ b/docs/recipes/fast-browserify-builds-with-watchify.md @@ -1,10 +1,3 @@ - - # Fast browserify builds with watchify As a [browserify](https://github.com/browserify/browserify) project begins to expand, the time to bundle it slowly gets longer and longer. While it might start at 1 second, it's possible to be waiting 30 seconds for your project to build on particularly large projects. diff --git a/docs/recipes/handling-the-delete-event-on-watch.md b/docs/recipes/handling-the-delete-event-on-watch.md index ba7a77cd..05bd683a 100644 --- a/docs/recipes/handling-the-delete-event-on-watch.md +++ b/docs/recipes/handling-the-delete-event-on-watch.md @@ -1,10 +1,3 @@ - - # Handling the Delete Event on Watch You can listen for `'unlink'` events to fire on the watcher returned from `gulp.watch`. diff --git a/docs/recipes/incremental-builds-with-concatenate.md b/docs/recipes/incremental-builds-with-concatenate.md index 797bd0ca..c9fdaa0d 100644 --- a/docs/recipes/incremental-builds-with-concatenate.md +++ b/docs/recipes/incremental-builds-with-concatenate.md @@ -1,10 +1,3 @@ - - # Incremental rebuilding, including operating on full file sets The trouble with incremental rebuilds is you often want to operate on _all_ processed files, not just single files. For example, you may want to lint and module-wrap just the file(s) that have changed, then concatenate it with all other linted and module-wrapped files. This is difficult without the use of temp files. diff --git a/docs/recipes/maintain-directory-structure-while-globbing.md b/docs/recipes/maintain-directory-structure-while-globbing.md index 279eac11..431d30b3 100644 --- a/docs/recipes/maintain-directory-structure-while-globbing.md +++ b/docs/recipes/maintain-directory-structure-while-globbing.md @@ -1,10 +1,3 @@ - - # Maintain Directory Structure while Globbing If you are planning to read a few files/folders from a directory and maintain their relative path, you need to pass `{base: '.'}` as the second argument to `gulp.src()`. diff --git a/docs/recipes/make-stream-from-buffer.md b/docs/recipes/make-stream-from-buffer.md index b376eafc..b7e44b95 100644 --- a/docs/recipes/make-stream-from-buffer.md +++ b/docs/recipes/make-stream-from-buffer.md @@ -1,10 +1,3 @@ - - # Make stream from buffer (memory contents) Sometimes you may need to start a stream with files that their contents are in a variable and not in a physical file. In other words, how to start a 'gulp' stream without using `gulp.src()`. diff --git a/docs/recipes/minified-and-non-minified.md b/docs/recipes/minified-and-non-minified.md index 3cc603a9..e1a6a429 100644 --- a/docs/recipes/minified-and-non-minified.md +++ b/docs/recipes/minified-and-non-minified.md @@ -1,10 +1,3 @@ - - # Output both a minified and non-minified version Outputting both a minified and non-minified version of your combined JavaScript files can be achieved by using `gulp-rename` and piping to `dest` twice (once before minifying and once after minifying): diff --git a/docs/recipes/minimal-browsersync-setup-with-gulp4.md b/docs/recipes/minimal-browsersync-setup-with-gulp4.md index 55a5ac38..ec22c071 100644 --- a/docs/recipes/minimal-browsersync-setup-with-gulp4.md +++ b/docs/recipes/minimal-browsersync-setup-with-gulp4.md @@ -1,10 +1,3 @@ - - # Minimal BrowserSync setup with Gulp 4 [BrowserSync](https://www.browsersync.io/) is a great tool to streamline diff --git a/docs/recipes/mocha-test-runner-with-gulp.md b/docs/recipes/mocha-test-runner-with-gulp.md index eab0725c..c6ca3873 100644 --- a/docs/recipes/mocha-test-runner-with-gulp.md +++ b/docs/recipes/mocha-test-runner-with-gulp.md @@ -1,10 +1,3 @@ - - # Mocha test-runner with gulp ### Passing shared module in all tests diff --git a/docs/recipes/only-pass-through-changed-files.md b/docs/recipes/only-pass-through-changed-files.md index 64d16dbe..1b0a3449 100644 --- a/docs/recipes/only-pass-through-changed-files.md +++ b/docs/recipes/only-pass-through-changed-files.md @@ -1,10 +1,3 @@ - - # Only pass through changed files Files are passed through the whole pipe chain on every run by default. By using [gulp-changed](https://github.com/sindresorhus/gulp-changed) only changed files will be passed through. This can speed up consecutive runs considerably. diff --git a/docs/recipes/pass-arguments-from-cli.md b/docs/recipes/pass-arguments-from-cli.md index 40c44bc1..1f9c74b1 100644 --- a/docs/recipes/pass-arguments-from-cli.md +++ b/docs/recipes/pass-arguments-from-cli.md @@ -1,10 +1,3 @@ - - # Pass arguments from the command line ```js diff --git a/docs/recipes/rebuild-only-files-that-change.md b/docs/recipes/rebuild-only-files-that-change.md index d60a8025..245ddc4f 100644 --- a/docs/recipes/rebuild-only-files-that-change.md +++ b/docs/recipes/rebuild-only-files-that-change.md @@ -1,10 +1,3 @@ - - # Rebuild only files that change With [`gulp-watch`](https://github.com/floatdrop/gulp-watch): diff --git a/docs/recipes/rollup-with-rollup-stream.md b/docs/recipes/rollup-with-rollup-stream.md index 4c77aacc..24679d55 100644 --- a/docs/recipes/rollup-with-rollup-stream.md +++ b/docs/recipes/rollup-with-rollup-stream.md @@ -1,10 +1,3 @@ - - # Rollup with rollup-stream Like Browserify, [Rollup](https://rollupjs.org/) is a bundler and thus only fits naturally into gulp if it's at the start of the pipeline. Unlike Browserify, Rollup doesn't natively produce a stream as output and needs to be wrapped before it can take this position. [rollup-stream](https://github.com/Permutatrix/rollup-stream) does this for you, producing output just like that of Browserify's `bundle()` method—as a result, most of the Browserify recipes here will also work with rollup-stream. diff --git a/docs/recipes/run-grunt-tasks-from-gulp.md b/docs/recipes/run-grunt-tasks-from-gulp.md index ee633125..51e95e5f 100644 --- a/docs/recipes/run-grunt-tasks-from-gulp.md +++ b/docs/recipes/run-grunt-tasks-from-gulp.md @@ -1,10 +1,3 @@ - - # Run Grunt Tasks from Gulp It is possible to run Grunt tasks / Grunt plugins from within Gulp. This can be useful during a gradual migration from Grunt to Gulp or if there's a specific plugin that you need. With the described approach no Grunt CLI and no Gruntfile is required. diff --git a/docs/recipes/running-shell-commands.md b/docs/recipes/running-shell-commands.md index 7bc4eb1f..5d344747 100644 --- a/docs/recipes/running-shell-commands.md +++ b/docs/recipes/running-shell-commands.md @@ -1,10 +1,3 @@ - - # Running Shell Commands Sometimes it is helpful to be able to call existing command line tools from gulp. diff --git a/docs/recipes/running-task-steps-per-folder.md b/docs/recipes/running-task-steps-per-folder.md index 5ee3b649..03ff5007 100644 --- a/docs/recipes/running-task-steps-per-folder.md +++ b/docs/recipes/running-task-steps-per-folder.md @@ -1,10 +1,3 @@ - - # Generating a file per folder If you have a set of folders, and wish to perform a set of tasks on each, for instance... @@ -53,11 +46,11 @@ gulp.task('scripts', function(done) { // write to output .pipe(gulp.dest(scriptsPath)) // minify - .pipe(uglify()) + .pipe(uglify()) // rename to folder.min.js .pipe(rename(folder + '.min.js')) // write to output again - .pipe(gulp.dest(scriptsPath)); + .pipe(gulp.dest(scriptsPath)); }); // process all remaining files in scriptsPath root into main.js and main.min.js files diff --git a/docs/recipes/running-tasks-in-series.md b/docs/recipes/running-tasks-in-series.md index be60816f..b28e692a 100644 --- a/docs/recipes/running-tasks-in-series.md +++ b/docs/recipes/running-tasks-in-series.md @@ -1,10 +1,3 @@ - - # Running tasks in series By default, gulp CLI run tasks with maximum concurrency - e.g. it launches diff --git a/docs/recipes/server-with-livereload-and-css-injection.md b/docs/recipes/server-with-livereload-and-css-injection.md index 51b65226..a23cc239 100644 --- a/docs/recipes/server-with-livereload-and-css-injection.md +++ b/docs/recipes/server-with-livereload-and-css-injection.md @@ -1,10 +1,3 @@ - - # Server with live-reloading and CSS injection With [BrowserSync](https://browsersync.io) and gulp, you can easily create a development server that is accessible to any device on the same WiFi network. BrowserSync also has live-reload built in, so there's nothing else to configure. diff --git a/docs/recipes/sharing-streams-with-stream-factories.md b/docs/recipes/sharing-streams-with-stream-factories.md index 93208523..16c110a0 100644 --- a/docs/recipes/sharing-streams-with-stream-factories.md +++ b/docs/recipes/sharing-streams-with-stream-factories.md @@ -1,10 +1,3 @@ - - # Sharing streams with stream factories If you use the same plugins in multiple tasks you might find yourself getting that itch to DRY things up. This method will allow you to create factories to split out your commonly used stream chains. diff --git a/docs/recipes/specifying-a-cwd.md b/docs/recipes/specifying-a-cwd.md index b6306d6a..eba0ceca 100644 --- a/docs/recipes/specifying-a-cwd.md +++ b/docs/recipes/specifying-a-cwd.md @@ -1,10 +1,3 @@ - - # Specifying a new cwd (current working directory) This is helpful for projects using a nested directory structure, such as: diff --git a/docs/recipes/split-tasks-across-multiple-files.md b/docs/recipes/split-tasks-across-multiple-files.md index efdd942f..afee1be1 100644 --- a/docs/recipes/split-tasks-across-multiple-files.md +++ b/docs/recipes/split-tasks-across-multiple-files.md @@ -1,10 +1,3 @@ - - # Split tasks across multiple files If your `gulpfile.js` is starting to grow too large, you can split the tasks diff --git a/docs/recipes/templating-with-swig-and-yaml-front-matter.md b/docs/recipes/templating-with-swig-and-yaml-front-matter.md index dbda0ad1..50c98e5f 100644 --- a/docs/recipes/templating-with-swig-and-yaml-front-matter.md +++ b/docs/recipes/templating-with-swig-and-yaml-front-matter.md @@ -1,10 +1,3 @@ - - # Templating with Swig and YAML front-matter Templating can be setup using `gulp-swig` and `gulp-front-matter`: diff --git a/docs/recipes/using-external-config-file.md b/docs/recipes/using-external-config-file.md index 4a2215d4..b073f1df 100644 --- a/docs/recipes/using-external-config-file.md +++ b/docs/recipes/using-external-config-file.md @@ -1,10 +1,3 @@ - - # Using external config file Beneficial because it's keeping tasks DRY and config.json can be used by another task runner, like `grunt`. diff --git a/docs/recipes/using-multiple-sources-in-one-task.md b/docs/recipes/using-multiple-sources-in-one-task.md index 6e5622ec..39e3e3b2 100644 --- a/docs/recipes/using-multiple-sources-in-one-task.md +++ b/docs/recipes/using-multiple-sources-in-one-task.md @@ -1,10 +1,3 @@ - - # Using multiple sources in one task ```js diff --git a/docs/why-use-pump/README.md b/docs/why-use-pump/README.md index c4810725..de6ebc85 100644 --- a/docs/why-use-pump/README.md +++ b/docs/why-use-pump/README.md @@ -1,10 +1,3 @@ - - # Why Use Pump? When using `pipe` from the Node.js streams, errors are not propagated forward diff --git a/docs/writing-a-plugin/README.md b/docs/writing-a-plugin/README.md index d876250c..bcd70835 100644 --- a/docs/writing-a-plugin/README.md +++ b/docs/writing-a-plugin/README.md @@ -1,10 +1,3 @@ - - # Writing a plugin If you plan to create your own Gulp plugin, you will save time by reading the full documentation. diff --git a/docs/writing-a-plugin/dealing-with-streams.md b/docs/writing-a-plugin/dealing-with-streams.md index d1ad36a8..777b11bf 100644 --- a/docs/writing-a-plugin/dealing-with-streams.md +++ b/docs/writing-a-plugin/dealing-with-streams.md @@ -1,10 +1,3 @@ - - # Dealing with streams > It is highly recommended to write plugins supporting streams. Here is some information on creating a gulp plugin that supports streams. diff --git a/docs/writing-a-plugin/guidelines.md b/docs/writing-a-plugin/guidelines.md index a1d626c9..b810ad8a 100644 --- a/docs/writing-a-plugin/guidelines.md +++ b/docs/writing-a-plugin/guidelines.md @@ -1,10 +1,3 @@ - - # Guidelines > While these guidelines are totally optional, we **HIGHLY** recommend that everyone follows them. Nobody wants to use a bad plugin. These guidelines will actually help make your life easier by giving you assurance that your plugin fits well within gulp. diff --git a/docs/writing-a-plugin/recommended-modules.md b/docs/writing-a-plugin/recommended-modules.md index a2faa94c..0b49b39d 100644 --- a/docs/writing-a-plugin/recommended-modules.md +++ b/docs/writing-a-plugin/recommended-modules.md @@ -1,10 +1,3 @@ - - # Recommended Modules > Sticking to this curated list of recommended modules will make sure you don't violate the plugin guidelines and ensure consistency across plugins. diff --git a/docs/writing-a-plugin/testing.md b/docs/writing-a-plugin/testing.md index cc9f9846..487a87f9 100644 --- a/docs/writing-a-plugin/testing.md +++ b/docs/writing-a-plugin/testing.md @@ -1,10 +1,3 @@ - - # Testing > Testing your plugin is the only way to ensure quality. It brings confidence to your users and makes your life easier. diff --git a/docs/writing-a-plugin/using-buffers.md b/docs/writing-a-plugin/using-buffers.md index b7ea0554..e35e41b5 100644 --- a/docs/writing-a-plugin/using-buffers.md +++ b/docs/writing-a-plugin/using-buffers.md @@ -1,10 +1,3 @@ - - # Using buffers > Here is some information on creating gulp plugin that manipulates buffers. From 9819957a11a1137f3b62bf7476ad26634c635975 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 14 Nov 2018 12:00:01 -0700 Subject: [PATCH 147/225] Scaffold: Add new expense policy --- EXPENSE_POLICY.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 EXPENSE_POLICY.md diff --git a/EXPENSE_POLICY.md b/EXPENSE_POLICY.md new file mode 100644 index 00000000..93308aa0 --- /dev/null +++ b/EXPENSE_POLICY.md @@ -0,0 +1,16 @@ +# Expense Policy + +## Funding can be requested for significant changes made by Core Members. +* Discuss the changes in the private gulp team forum. +* Include a cost estimation with either a fixed price or hours + rate (suggested $50 per hour). +* Notify the team before you exceed an estimate. + +## Bug bounties may be assigned at the Core Members’ discretion to issues of significant importance - usually issues outstanding for at least 6 months. +* Issues with bug bounties will be labeled “Bug Bounty: $x”. +* In order to claim a bug bounty, create a Pull Request that fixes an issue with a “Bug Bounty” label. +* The Pull Request must be reviewed and merged by a Core Member. If competing submissions exist, the best solution will be chosen by a Core Member. All else equal, the first submission will be chosen. +* Once your Pull Request is merged, you can submit an expense to our [Open Collective](https://opencollective.com/gulpjs/expenses/new) which includes the link to your submission in the description (e.g. $100 bug bounty claim for https://github.com/gulpjs/gulp/pull/2226). You will also need to provide an invoice, see the [Open Collective Expense FAQ](https://opencollective.com/faq/expenses) for more details and to get a Google Docs template that you can use. +* Then, add a comment on your Pull Request, noting that you’ve claimed the money, with a link to your Open Collective expense. This is to ensure the same person who fixed the issue is claiming the money. +* Your expense will be validated by a Core Member and then your payment will be dispersed by Open Collective the following Friday. + +## If you're doing other good things for gulp that end up costing you real money, feel free to reach out and we can discuss helping with those expenses! From c6413693a5957b609eeb23ecd7eebfa6fb2dcbe6 Mon Sep 17 00:00:00 2001 From: Takuya Fukuju Date: Thu, 15 Nov 2018 04:56:28 +0900 Subject: [PATCH 148/225] Docs: Fix broken link in Table of Contents (#2260) --- docs/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/README.md b/docs/api/README.md index fe0d498d..7f2cc0cb 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -4,7 +4,7 @@ * [src()](src.md) * [dest()](dest.md) * [symlink()](symlink.md) -* [lastRun()](lastRun.md) +* [lastRun()](last-run.md) * [series()](series.md) * [parallel()](parallel.md) * [watch()](watch.md) From 7239cf197ba69f4ae729da792013794faec6a90f Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 19 Nov 2018 12:44:18 -0700 Subject: [PATCH 149/225] Docs: Update the babel dependencies to install & configuration needed (closes #2136) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1d6e35c7..7c3e20a2 100644 --- a/README.md +++ b/README.md @@ -119,21 +119,21 @@ gulp.task('default', build); ## Use latest JavaScript version in your gulpfile -Node already supports a lot of **ES2015**, to avoid compatibility problem we suggest to install Babel and rename your `gulpfile.js` as `gulpfile.babel.js`. +Node already supports a lot of __ES2015+__ features, but to avoid compatibility problems we suggest to install Babel and rename your `gulpfile.js` as `gulpfile.babel.js`. ```sh -npm install --save-dev babel-register babel-preset-es2015 +npm install --save-dev @babel/register @babel/core @babel/preset-env ``` Then create a **.babelrc** file with the preset configuration. ```js { - "presets": [ "es2015" ] + "presets": [ "@babel/preset-env" ] } ``` -And here's the same sample from above written in **ES2015**. +And here's the same sample from above written in **ES2015+**. ```js import gulp from 'gulp'; From 9078c4902358866f8240276ed55b0d58e8a2ecfe Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 19 Nov 2018 15:53:49 -0700 Subject: [PATCH 150/225] Scaffold: Add support-bot template --- .github/support.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/support.yml diff --git a/.github/support.yml b/.github/support.yml new file mode 100644 index 00000000..cd6325e3 --- /dev/null +++ b/.github/support.yml @@ -0,0 +1,13 @@ +# Configuration for support-requests - https://github.com/dessant/support-requests +supportLabel: support +supportComment: > + Issues are reserved for bugs and features. Here are a few places to find answers to your question: + + * For community support, use the `gulp` tag on [StackOverflow](https://stackoverflow.com/questions/tagged/gulp). + + * Participate in community chat on [Gitter](https://gitter.im/gulpjs/gulp). + + * To get paid support directly from the maintainers, sign up for [Tidelift](https://tidelift.com/subscription/pkg/npm-gulp?utm_source=npm-gulp&utm_medium=referral&utm_campaign=support). Subscribers should email support@tidelift.com, mention that it's a question for Gulp, and describe your question. Straightforward questions are answered as part of your subscription. Additional consulting hours are available for more complex help. +close: true +lock: false +setLockReason: false From 75ea6344c2fcd5017fb74375aa81bca6f1e6b041 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 6 Dec 2018 15:59:27 -0700 Subject: [PATCH 151/225] Docs: Add "What's new in 4.0" section (closes #2089) (#2267) --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 7c3e20a2..6b856bb6 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,17 @@ - **Strong Ecosystem** - Use npm modules to do anything you want + over 2000 curated plugins for streaming file transformations - **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use +## What's new in 4.0?! + +* The task system was rewritten from the ground-up, allowing task composition using `series()` and `parallel()` methods +* The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system +* First-class support was added for incremental builds using `lastRun()` +* A `symlink()` method was exposed to create symlinks instead of copying files +* Built-in support for sourcemaps was added - the gulp-sourcemaps plugin is no longer necessary! +* Task registration of exported functions - using node or ES exports - is now recommended +* Custom registries were designed, allowing for shared tasks or augmented functionality +* Stream implementations were improved, allowing for better conditional and phased builds + ## Installation There are a few ways to install: From 24e202b3a3dc9e1eecd3fc1e4b69e2b5379928ea Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 10 Dec 2018 10:13:09 -0700 Subject: [PATCH 152/225] Docs: Cleanup README for "latest" bump (#2268) --- README.md | 79 +++++++++++-------------------------------------------- 1 file changed, 16 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 6b856bb6..7991f348 100644 --- a/README.md +++ b/README.md @@ -28,18 +28,17 @@ ## Installation -There are a few ways to install: +Follow our [Quick Start guide][quick-start]. -* gulp v4.0.0 - `npm install gulp@next` -* gulp v4.0.0-alpha.3 - `npm install gulpjs/gulp#v4.0.0-alpha.3` -* gulp v3.9.1 - `npm install gulp` +## Roadmap + +Find out about all our work-in-progress and outstanding issues at https://github.com/orgs/gulpjs/projects. ## Documentation -For a Getting started guide, API docs, recipes, making a plugin, etc. check out our docs! +Check out the [Getting Started guide][getting-started-guide] and [API docs][api-docs] on our website! -- Check out the [documentation for v4.0.0](/docs/README.md)! __Excuse our dust; these docs might be behind while we get everything updated. Please open an issue if something isn't working.__ -- Using the older v3.9.1? Check out the [documentation at the v3.9.1 tag](https://github.com/gulpjs/gulp/tree/v3.9.1/docs)! +__Excuse our dust! All other docs will be behind until we get everything updated. Please open an issue if something isn't working.__ ## Sample `gulpfile.js` @@ -104,28 +103,23 @@ function watch() { gulp.watch(paths.styles.src, styles); } -/* - * You can use CommonJS `exports` module notation to declare tasks - */ -exports.clean = clean; -exports.styles = styles; -exports.scripts = scripts; -exports.watch = watch; - /* * Specify if tasks run in series or parallel using `gulp.series` and `gulp.parallel` */ var build = gulp.series(clean, gulp.parallel(styles, scripts)); /* - * You can still use `gulp.task` to expose tasks + * You can use CommonJS `exports` module notation to declare tasks */ -gulp.task('build', build); - +exports.clean = clean; +exports.styles = styles; +exports.scripts = scripts; +exports.watch = watch; +exports.build = build; /* * Define default task that can be called by just running `gulp` from cli */ -gulp.task('default', build); +exports.default = build; ``` ## Use latest JavaScript version in your gulpfile @@ -204,13 +198,7 @@ function watchFiles() { } export { watchFiles as watch }; -/* - * You can still use `gulp.task` - * for example to set task names that would otherwise be invalid - */ const build = gulp.series(clean, gulp.parallel(styles, scripts)); -gulp.task('build', build); - /* * Export a default task */ @@ -244,40 +232,6 @@ Task run times are saved in memory and are lost when gulp exits. It will only save time during the `watch` task when running the `images` task for a second time. -If you want to compare modification time between files instead, we recommend these plugins: -- [gulp-changed]; -- or [gulp-newer] - supports many:1 source:dest. - -[gulp-newer] example: -```js -function images() { - var dest = 'build/img'; - return gulp.src(paths.images) - .pipe(newer(dest)) // pass through newer images only - .pipe(imagemin({optimizationLevel: 5})) - .pipe(gulp.dest(dest)); -} -``` - -If you can't simply filter out unchanged files, but need them in a later phase -of the stream, we recommend these plugins: -- [gulp-cached] - in-memory file cache, not for operation on sets of files -- [gulp-remember] - pairs nicely with gulp-cached - -[gulp-remember] example: -```js -function scripts() { - return gulp.src(scriptsGlob) - .pipe(cache('scripts')) // only pass through changed files - .pipe(header('(function () {')) // do special things to the changed files... - .pipe(footer('})();')) // for example, - // add a simple module wrap to each file - .pipe(remember('scripts')) // add back all files to the stream - .pipe(concat('app.js')) // do things that require all files - .pipe(gulp.dest('public/')) -} -``` - ## Want to contribute? Anyone can help make this project better - check out our [Contributing guide](/CONTRIBUTING.md)! @@ -320,7 +274,6 @@ Become a sponsor to get your logo on our README on Github. [backers-image]: https://opencollective.com/gulpjs/backers.svg [sponsors-image]: https://opencollective.com/gulpjs/sponsors.svg -[gulp-cached]: https://github.com/contra/gulp-cached -[gulp-remember]: https://github.com/ahaurw01/gulp-remember -[gulp-changed]: https://github.com/sindresorhus/gulp-changed -[gulp-newer]: https://github.com/tschaub/gulp-newer +[quick-start]: https://gulpjs.com/docs/en/getting-started/quick-start +[getting-started-guide]: https://gulpjs.com/docs/en/getting-started/quick-start +[api-docs]: https://gulpjs.com/docs/en/api/concepts From ed27cbeb576111641a72a9a89b8c3e1eb443172b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 10 Dec 2018 10:26:31 -0700 Subject: [PATCH 153/225] Docs: Revert "next" reference now that 4.0 is latest --- docs/getting-started/1-quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/1-quick-start.md b/docs/getting-started/1-quick-start.md index c3210274..6953e7f5 100644 --- a/docs/getting-started/1-quick-start.md +++ b/docs/getting-started/1-quick-start.md @@ -48,7 +48,7 @@ This will guide you through giving your project a name, version, description, et ## Install the gulp package in your devDependencies ```sh -npm install --save-dev gulp@next +npm install --save-dev gulp ``` ## Verify your gulp versions From b2c6c7e4c6cc85e6f7579b3c32081590d9517728 Mon Sep 17 00:00:00 2001 From: Danny McCormick Date: Wed, 20 Mar 2019 15:06:50 -0400 Subject: [PATCH 154/225] Build: Add Azure Pipelines CI (#2299) --- .ci/.azure-pipelines-steps.yml | 38 +++++++++++++++ .ci/.azure-pipelines.yml | 84 ++++++++++++++++++++++++++++++++++ .gitignore | 4 ++ package.json | 10 ++-- 4 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 .ci/.azure-pipelines-steps.yml create mode 100644 .ci/.azure-pipelines.yml diff --git a/.ci/.azure-pipelines-steps.yml b/.ci/.azure-pipelines-steps.yml new file mode 100644 index 00000000..ef26e4e6 --- /dev/null +++ b/.ci/.azure-pipelines-steps.yml @@ -0,0 +1,38 @@ +steps: +- script: npm i -g npm@$(npm_version) + displayName: Use legacy npm version $(npm_version) + condition: ne(variables['npm_version'], '') + +- task: NodeTool@0 + inputs: + versionSpec: '$(node_version)' + displayName: Use Node $(node_version) + +- script: npm install + displayName: npm install + +- script: npm test + displayName: Run tests + +- script: npm run coveralls + displayName: Run coveralls + env: + # Pretend to be AppVeyor for now + APPVEYOR: true + APPVEYOR_BUILD_NUMBER: $(Build.BuildNumber) + APPVEYOR_BUILD_ID: $(Agent.OS)_$(node_version) + APPVEYOR_REPO_COMMIT: $(Build.SourceVersion) + APPVEYOR_REPO_BRANCH: $(Build.SourceBranchName) + # Overwrite the GitLab Service Name + COVERALLS_SERVICE_NAME: Azure Pipelines + COVERALLS_REPO_TOKEN: $(COVERALLS_REPO_TOKEN_SECRET) + COVERALLS_PARALLEL: true + CI_PULL_REQUEST: $(System.PullRequest.PullRequestNumber) + +- script: npm run azure-pipelines + displayName: Write tests to xml + +- task: PublishTestResults@2 + inputs: + testResultsFiles: '**/test.xunit' + condition: succeededOrFailed() diff --git a/.ci/.azure-pipelines.yml b/.ci/.azure-pipelines.yml new file mode 100644 index 00000000..dcdd68e6 --- /dev/null +++ b/.ci/.azure-pipelines.yml @@ -0,0 +1,84 @@ +trigger: +- master +- releases/* + +jobs: + - job: Test_Linux + displayName: Run Tests on Linux + pool: + vmImage: "Ubuntu 16.04" + strategy: + matrix: + Node_v10: + node_version: 10 + Node_v8: + node_version: 8 + Node_v6: + node_version: 6 + Node_v4: + node_version: 4 + Node_v0_12: + node_version: 0.12 + Node_v0_10: + node_version: 0.10 + steps: + - template: .azure-pipelines-steps.yml + + - job: Test_Windows + displayName: Run Tests on Windows + pool: + vmImage: vs2017-win2016 + strategy: + matrix: + Node_v10: + node_version: 10 + Node_v8: + node_version: 8 + Node_v6: + node_version: 6 + Node_v4: + node_version: 4 + npm_version: 2 + Node_v0_12: + node_version: 0.12 + npm_version: 2 + Node_v0_10: + node_version: 0.10 + npm_version: 2 + steps: + - template: .azure-pipelines-steps.yml + + - job: Test_MacOS + displayName: Run Tests on MacOS + pool: + vmImage: macos-10.13 + strategy: + matrix: + Node_v10: + node_version: 10 + Node_v8: + node_version: 8 + Node_v6: + node_version: 6 + Node_v4: + node_version: 4 + Node_v0_12: + node_version: 0.12 + Node_v0_10: + node_version: 0.10 + steps: + - template: .azure-pipelines-steps.yml + + - job: Notify_Coveralls + displayName: Notify Coveralls that the parallel report is done + pool: + vmImage: "Ubuntu 16.04" + dependsOn: + - Test_Linux + - Test_Windows + - Test_MacOS + steps: + - script: curl -k https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN -d "payload[build_num]=$BUILD_NAME&payload[status]=done" + env: + COVERALLS_REPO_TOKEN: $(COVERALLS_REPO_TOKEN_SECRET) + BUILD_NAME: $(Build.BuildNumber) diff --git a/.gitignore b/.gitignore index ac88dd1f..466085e1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ lib-cov # Coverage directory used by tools like istanbul coverage +.nyc_output # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt @@ -29,3 +30,6 @@ node_modules # Garbage files .DS_Store + +# Test results +test.xunit diff --git a/package.json b/package.json index a4ce8bca..38b855cf 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ "scripts": { "lint": "eslint .", "pretest": "npm run lint", - "test": "mocha --async-only", - "cover": "istanbul cover _mocha --report lcovonly", - "coveralls": "npm run cover && istanbul-coveralls" + "test": "nyc mocha --async-only", + "azure-pipelines": "nyc mocha --async-only --reporter xunit -O output=test.xunit", + "coveralls": "nyc report --reporter=text-lcov | coveralls" }, "dependencies": { "glob-watcher": "^5.0.0", @@ -36,13 +36,13 @@ "vinyl-fs": "^3.0.0" }, "devDependencies": { + "coveralls": "github:phated/node-coveralls#2.x", "eslint": "^2.13.1", "eslint-config-gulp": "^3.0.1", "expect": "^1.20.2", - "istanbul": "^0.4.3", - "istanbul-coveralls": "^1.0.3", "mkdirp": "^0.5.1", "mocha": "^3.0.0", + "nyc": "^10.3.2", "rimraf": "^2.2.5" }, "keywords": [ From 34a6d53e85cba8e00d75391fc15a50dca6f9d26a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 23 Mar 2019 19:47:18 -0700 Subject: [PATCH 155/225] Build: Fix Azure comment (#2307) --- .ci/.azure-pipelines-steps.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/.azure-pipelines-steps.yml b/.ci/.azure-pipelines-steps.yml index ef26e4e6..894c21ee 100644 --- a/.ci/.azure-pipelines-steps.yml +++ b/.ci/.azure-pipelines-steps.yml @@ -23,7 +23,7 @@ steps: APPVEYOR_BUILD_ID: $(Agent.OS)_$(node_version) APPVEYOR_REPO_COMMIT: $(Build.SourceVersion) APPVEYOR_REPO_BRANCH: $(Build.SourceBranchName) - # Overwrite the GitLab Service Name + # Overwrite the AppVeyor Service Name COVERALLS_SERVICE_NAME: Azure Pipelines COVERALLS_REPO_TOKEN: $(COVERALLS_REPO_TOKEN_SECRET) COVERALLS_PARALLEL: true From f3f05486b872a85bc810492469d4b0e3d6da2fb4 Mon Sep 17 00:00:00 2001 From: Danny McCormick Date: Mon, 25 Mar 2019 22:51:06 -0400 Subject: [PATCH 156/225] Docs: Add Azure Pipelines badge (#2310) --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7991f348..129b778d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

The streaming build system

-[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![OpenCollective Backers][backer-badge]][backer-url] [![OpenCollective Sponsors][sponsor-badge]][sponsor-url] [![Gitter chat][gitter-image]][gitter-url] +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Azure Pipelines Build Status][azure-pipelines-image]][azure-pipelines-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![OpenCollective Backers][backer-badge]][backer-url] [![OpenCollective Sponsors][sponsor-badge]][sponsor-url] [![Gitter chat][gitter-image]][gitter-url] ## What is gulp? @@ -252,6 +252,9 @@ Become a sponsor to get your logo on our README on Github. [npm-url]: https://www.npmjs.com/package/gulp [npm-image]: https://img.shields.io/npm/v/gulp.svg +[azure-pipelines-url]: https://dev.azure.com/gulpjs/gulp/_build/latest?definitionId=1&branchName=master +[azure-pipelines-image]: https://dev.azure.com/gulpjs/gulp/_apis/build/status/gulp?branchName=master + [travis-url]: https://travis-ci.org/gulpjs/gulp [travis-image]: https://img.shields.io/travis/gulpjs/gulp.svg?label=travis-ci From 53b9037a08807f0fb5a8837f3550f501af36f05d Mon Sep 17 00:00:00 2001 From: Tony Hallett Date: Thu, 28 Mar 2019 18:04:36 +0000 Subject: [PATCH 157/225] Docs: Add note about transpilation to "Splitting a Gulpfile" section (closes #2311) (#2312) --- docs/getting-started/2-javascript-and-gulpfiles.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/2-javascript-and-gulpfiles.md b/docs/getting-started/2-javascript-and-gulpfiles.md index 6ccc8161..82573a13 100644 --- a/docs/getting-started/2-javascript-and-gulpfiles.md +++ b/docs/getting-started/2-javascript-and-gulpfiles.md @@ -28,7 +28,7 @@ Many users start by adding all logic to a gulpfile. If it ever grows too big, it Each task can be split into its own file, then imported into your gulpfile for composition. Not only does this keep things organized, but it allows you to test each task independently or vary composition based on conditions. -Node's module resolution allows you to replace your `gulpfile.js` file with a directory named `gulpfile.js` that contains an `index.js` file which is treated as a `gulpfile.js`. This directory could then contain your individual modules for tasks. +Node's module resolution allows you to replace your `gulpfile.js` file with a directory named `gulpfile.js` that contains an `index.js` file which is treated as a `gulpfile.js`. This directory could then contain your individual modules for tasks. If you are using a transpiler, name the folder and file accordingly. [gulpfile-transpilation-advanced]: ../documentation-missing.md [ts-node-module]: https://www.npmjs.com/package/ts-node From 88437f2b71f13c44061f6af6b231adbc4a56842a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=AD=90=20B3none?= Date: Sat, 30 Mar 2019 19:55:26 +0000 Subject: [PATCH 158/225] Docs: Improve wording of file rename (#2314) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 129b778d..013c4077 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ exports.default = build; ## Use latest JavaScript version in your gulpfile -Node already supports a lot of __ES2015+__ features, but to avoid compatibility problems we suggest to install Babel and rename your `gulpfile.js` as `gulpfile.babel.js`. +Node already supports a lot of __ES2015+__ features, but to avoid compatibility problems we suggest to install Babel and rename your `gulpfile.js` to `gulpfile.babel.js`. ```sh npm install --save-dev @babel/register @babel/core @babel/preset-env From d3734d34288c63d9c80af4d2cb0457e0db5b9c51 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 21 Apr 2019 18:45:51 +0200 Subject: [PATCH 159/225] Upgrade: Update glob-watcher, gulp-cli, and undertaker dependencies & rimraf devDep --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 38b855cf..a0be8efc 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,9 @@ "coveralls": "nyc report --reporter=text-lcov | coveralls" }, "dependencies": { - "glob-watcher": "^5.0.0", - "gulp-cli": "^2.0.0", - "undertaker": "^1.0.0", + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", "vinyl-fs": "^3.0.0" }, "devDependencies": { @@ -43,7 +43,7 @@ "mkdirp": "^0.5.1", "mocha": "^3.0.0", "nyc": "^10.3.2", - "rimraf": "^2.2.5" + "rimraf": "^2.6.3" }, "keywords": [ "build", From ea3bba4fdf9f2b508699f69569d0191b8c5bc10c Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 21 Apr 2019 18:55:44 +0200 Subject: [PATCH 160/225] Release: 4.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a0be8efc..a67c7d2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gulp", - "version": "4.0.0", + "version": "4.0.1", "description": "The streaming build system.", "homepage": "https://gulpjs.com", "author": "Gulp Team (https://gulpjs.com/)", From 5d81f42f9ddc4aa0a0721057eff8b8e24b65861c Mon Sep 17 00:00:00 2001 From: Rafael <37901937+ralomach@users.noreply.github.com> Date: Sat, 27 Apr 2019 10:23:25 -0300 Subject: [PATCH 161/225] Docs: Fix typo in Explaining Globs (#2326) --- docs/getting-started/6-explaining-globs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/6-explaining-globs.md b/docs/getting-started/6-explaining-globs.md index de524d84..d362c28c 100644 --- a/docs/getting-started/6-explaining-globs.md +++ b/docs/getting-started/6-explaining-globs.md @@ -52,13 +52,13 @@ Here, the glob is appropriately restricted to the `scripts/` directory. It will Since globs are matched in array order, a negative glob must follow at least one non-negative glob in an array. The first finds a set of matches, then the negative glob removes a portion of those results. These are most performant when they only include literal characters. ```js -['script/**/*.js', '!scripts/vendor/'] +['scripts/**/*.js', '!scripts/vendor/'] ``` If any non-negative globs follow a negative, nothing will be removed from the later set of matches. ```js -['script/**/*.js', '!scripts/vendor/', 'scripts/vendor/react.js'] +['scripts/**/*.js', '!scripts/vendor/', 'scripts/vendor/react.js'] ``` Negative globs can be used as an alternative for restricting double-star globs. From ea52a927843ff0e84f142f85813572bd5144a656 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 27 Apr 2019 15:30:09 +0200 Subject: [PATCH 162/225] Docs: Fix syntax error in lastRun API docs (closes #2315) --- docs/api/last-run.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/api/last-run.md b/docs/api/last-run.md index 4daa2abf..f1bb581e 100644 --- a/docs/api/last-run.md +++ b/docs/api/last-run.md @@ -23,11 +23,9 @@ function images() { .pipe(dest('build/img/')); } -function watch() { +exports.default = function() { watch('src/images/**/*.jpg', images); -} - -exports.watch = watch; +}; ``` From d9162761f276fce5fe54bc0a60c7eb9efcd5e249 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 27 Apr 2019 15:35:23 +0200 Subject: [PATCH 163/225] Docs: Add default task wrappers to Watching Files examples to make runnable (ref #2322) --- docs/getting-started/8-watching-files.md | 58 ++++++++++++++---------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/docs/getting-started/8-watching-files.md b/docs/getting-started/8-watching-files.md index 9b8268eb..bb3bf994 100644 --- a/docs/getting-started/8-watching-files.md +++ b/docs/getting-started/8-watching-files.md @@ -29,10 +29,12 @@ function css(cb) { cb(); } -// You can use a single task -watch('src/*.css', css); -// Or a composed task -watch('src/*.js', series(clean, javascript)); +exports.default = function() { + // You can use a single task + watch('src/*.css', css); + // Or a composed task + watch('src/*.js', series(clean, javascript)); +}; ``` ## Warning: avoid synchronous @@ -49,11 +51,13 @@ If you need to use different events, you can use the `events` option when callin ```js const { watch } = require('gulp'); -// All events will be watched -watch('src/*.js', { events: 'all' }, function(cb) { - // body omitted - cb(); -}); +exports.default = function() { + // All events will be watched + watch('src/*.js', { events: 'all' }, function(cb) { + // body omitted + cb(); + }); +}; ``` ## Initial execution @@ -65,11 +69,13 @@ To execute tasks before the first file change, set the `ignoreInitial` option to ```js const { watch } = require('gulp'); -// The task will be executed upon startup -watch('src/*.js', { ignoreInitial: false }, function(cb) { - // body omitted - cb(); -}); +exports.default = function() { + // The task will be executed upon startup + watch('src/*.js', { ignoreInitial: false }, function(cb) { + // body omitted + cb(); + }); +}; ``` ## Queueing @@ -81,11 +87,13 @@ To disable queueing, set the `queue` option to `false`. ```js const { watch } = require('gulp'); -// The task will be run (concurrently) for every change made -watch('src/*.js', { queue: false }, function(cb) { - // body omitted - cb(); -}); +exports.default = function() { + // The task will be run (concurrently) for every change made + watch('src/*.js', { queue: false }, function(cb) { + // body omitted + cb(); + }); +}; ``` ## Delay @@ -97,11 +105,13 @@ To adjust the delay duration, set the `delay` option to a positive integer. ```js const { watch } = require('gulp'); -// The task won't be run until 500ms have elapsed since the first change -watch('src/*.js', { delay: 500 }, function(cb) { - // body omitted - cb(); -}); +exports.default = function() { + // The task won't be run until 500ms have elapsed since the first change + watch('src/*.js', { delay: 500 }, function(cb) { + // body omitted + cb(); + }); +}; ``` ## Using the watcher instance From 1693a1127116a6804a892a4b931c232b1bec9162 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 27 Apr 2019 15:50:17 +0200 Subject: [PATCH 164/225] Docs: Remove next tag from recipes (closes #2277) --- docs/recipes/delete-files-folder.md | 4 ++-- docs/recipes/mocha-test-runner-with-gulp.md | 4 ++-- docs/recipes/only-pass-through-changed-files.md | 2 +- docs/recipes/pass-arguments-from-cli.md | 2 +- docs/recipes/rollup-with-rollup-stream.md | 4 ++-- docs/recipes/run-grunt-tasks-from-gulp.md | 2 +- docs/recipes/server-with-livereload-and-css-injection.md | 2 +- docs/recipes/split-tasks-across-multiple-files.md | 2 +- docs/recipes/using-external-config-file.md | 2 +- docs/recipes/using-multiple-sources-in-one-task.md | 4 ++-- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/recipes/delete-files-folder.md b/docs/recipes/delete-files-folder.md index 59e9cc93..d974c628 100644 --- a/docs/recipes/delete-files-folder.md +++ b/docs/recipes/delete-files-folder.md @@ -5,7 +5,7 @@ You might want to delete some files before running your build. Since deleting fi Let's use the [`del`](https://github.com/sindresorhus/del) module for this example as it supports multiple files and [globbing](https://github.com/sindresorhus/multimatch#globbing-patterns): ```sh -$ npm install --save-dev gulp@next del +$ npm install --save-dev gulp del ``` Imagine the following file structure: @@ -49,7 +49,7 @@ You might want to delete some files after processing them in a pipeline. We'll use [vinyl-paths](https://github.com/sindresorhus/vinyl-paths) to easily get the file path of files in the stream and pass it to the `del` method. ```sh -$ npm install --save-dev gulp@next del vinyl-paths +$ npm install --save-dev gulp del vinyl-paths ``` Imagine the following file structure: diff --git a/docs/recipes/mocha-test-runner-with-gulp.md b/docs/recipes/mocha-test-runner-with-gulp.md index c6ca3873..4a6b2179 100644 --- a/docs/recipes/mocha-test-runner-with-gulp.md +++ b/docs/recipes/mocha-test-runner-with-gulp.md @@ -3,7 +3,7 @@ ### Passing shared module in all tests ```js -// npm install gulp@next gulp-mocha +// npm install gulp gulp-mocha var gulp = require('gulp'); var mocha = require('gulp-mocha'); @@ -22,7 +22,7 @@ gulp.task('default', function() { ### Running mocha tests when files change ```js -// npm install gulp@next gulp-mocha gulplog +// npm install gulp gulp-mocha gulplog var gulp = require('gulp'); var mocha = require('gulp-mocha'); diff --git a/docs/recipes/only-pass-through-changed-files.md b/docs/recipes/only-pass-through-changed-files.md index 1b0a3449..f2db5972 100644 --- a/docs/recipes/only-pass-through-changed-files.md +++ b/docs/recipes/only-pass-through-changed-files.md @@ -4,7 +4,7 @@ Files are passed through the whole pipe chain on every run by default. By using ```js -// npm install --save-dev gulp@next gulp-changed gulp-jscs gulp-uglify +// npm install --save-dev gulp gulp-changed gulp-jscs gulp-uglify var gulp = require('gulp'); var changed = require('gulp-changed'); diff --git a/docs/recipes/pass-arguments-from-cli.md b/docs/recipes/pass-arguments-from-cli.md index 1f9c74b1..48185b6b 100644 --- a/docs/recipes/pass-arguments-from-cli.md +++ b/docs/recipes/pass-arguments-from-cli.md @@ -1,7 +1,7 @@ # Pass arguments from the command line ```js -// npm install --save-dev gulp@next gulp-if gulp-uglify minimist +// npm install --save-dev gulp gulp-if gulp-uglify minimist var gulp = require('gulp'); var gulpif = require('gulp-if'); diff --git a/docs/recipes/rollup-with-rollup-stream.md b/docs/recipes/rollup-with-rollup-stream.md index 24679d55..2a8840f2 100644 --- a/docs/recipes/rollup-with-rollup-stream.md +++ b/docs/recipes/rollup-with-rollup-stream.md @@ -4,7 +4,7 @@ Like Browserify, [Rollup](https://rollupjs.org/) is a bundler and thus only fits ## Basic usage ```js -// npm install --save-dev gulp@next rollup-stream vinyl-source-stream +// npm install --save-dev gulp rollup-stream vinyl-source-stream var gulp = require('gulp'); var rollup = require('rollup-stream'); var source = require('vinyl-source-stream'); @@ -24,7 +24,7 @@ gulp.task('rollup', function() { ## Usage with sourcemaps ```js -// npm install --save-dev gulp@next rollup-stream gulp-sourcemaps vinyl-source-stream vinyl-buffer +// npm install --save-dev gulp rollup-stream gulp-sourcemaps vinyl-source-stream vinyl-buffer // optional: npm install --save-dev gulp-rename var gulp = require('gulp'); var rollup = require('rollup-stream'); diff --git a/docs/recipes/run-grunt-tasks-from-gulp.md b/docs/recipes/run-grunt-tasks-from-gulp.md index 51e95e5f..df2ca177 100644 --- a/docs/recipes/run-grunt-tasks-from-gulp.md +++ b/docs/recipes/run-grunt-tasks-from-gulp.md @@ -7,7 +7,7 @@ It is possible to run Grunt tasks / Grunt plugins from within Gulp. This can be very simple example `gulpfile.js`: ```js -// npm install gulp@next grunt grunt-contrib-copy --save-dev +// npm install gulp grunt grunt-contrib-copy --save-dev var gulp = require('gulp'); var grunt = require('grunt'); diff --git a/docs/recipes/server-with-livereload-and-css-injection.md b/docs/recipes/server-with-livereload-and-css-injection.md index a23cc239..ee400b8f 100644 --- a/docs/recipes/server-with-livereload-and-css-injection.md +++ b/docs/recipes/server-with-livereload-and-css-injection.md @@ -5,7 +5,7 @@ With [BrowserSync](https://browsersync.io) and gulp, you can easily create a dev First install the modules: ```sh -$ npm install --save-dev gulp@next browser-sync +$ npm install --save-dev gulp browser-sync ``` Then, considering the following file structure... diff --git a/docs/recipes/split-tasks-across-multiple-files.md b/docs/recipes/split-tasks-across-multiple-files.md index afee1be1..a93217a9 100644 --- a/docs/recipes/split-tasks-across-multiple-files.md +++ b/docs/recipes/split-tasks-across-multiple-files.md @@ -17,7 +17,7 @@ tasks/ Install the `gulp-hub` module: ```sh -npm install --save-dev gulp@next gulp-hub +npm install --save-dev gulp gulp-hub ``` Add the following lines to your `gulpfile.js` file: diff --git a/docs/recipes/using-external-config-file.md b/docs/recipes/using-external-config-file.md index b073f1df..6c740761 100644 --- a/docs/recipes/using-external-config-file.md +++ b/docs/recipes/using-external-config-file.md @@ -30,7 +30,7 @@ Beneficial because it's keeping tasks DRY and config.json can be used by another ###### `gulpfile.js` ```js -// npm install --save-dev gulp@next gulp-uglify merge-stream +// npm install --save-dev gulp gulp-uglify merge-stream var gulp = require('gulp'); var uglify = require('gulp-uglify'); var merge = require('merge-stream'); diff --git a/docs/recipes/using-multiple-sources-in-one-task.md b/docs/recipes/using-multiple-sources-in-one-task.md index 39e3e3b2..42279378 100644 --- a/docs/recipes/using-multiple-sources-in-one-task.md +++ b/docs/recipes/using-multiple-sources-in-one-task.md @@ -1,7 +1,7 @@ # Using multiple sources in one task ```js -// npm install --save-dev gulp@next merge-stream +// npm install --save-dev gulp merge-stream var gulp = require('gulp'); var merge = require('merge-stream'); @@ -20,7 +20,7 @@ gulp.task('test', function() { `gulp.src` will emit files in the order they were added: ```js -// npm install gulp@next gulp-concat +// npm install gulp gulp-concat var gulp = require('gulp'); var concat = require('gulp-concat'); From 3c66d95f014b99f79e0375c43cfa17a7269732a2 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 27 Apr 2019 16:10:39 +0200 Subject: [PATCH 165/225] Docs: Fix the Negative Globs section & examples (closes #2297) --- docs/getting-started/6-explaining-globs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/6-explaining-globs.md b/docs/getting-started/6-explaining-globs.md index d362c28c..11f34fae 100644 --- a/docs/getting-started/6-explaining-globs.md +++ b/docs/getting-started/6-explaining-globs.md @@ -49,25 +49,25 @@ Here, the glob is appropriately restricted to the `scripts/` directory. It will ## Special character: ! (negative) -Since globs are matched in array order, a negative glob must follow at least one non-negative glob in an array. The first finds a set of matches, then the negative glob removes a portion of those results. These are most performant when they only include literal characters. +Since globs are matched in array order, a negative glob must follow at least one non-negative glob in an array. The first finds a set of matches, then the negative glob removes a portion of those results. When excluding all files within a directory, you must add `/**` after the directory name, which the globbing library optimizes internally. ```js -['scripts/**/*.js', '!scripts/vendor/'] +['scripts/**/*.js', '!scripts/vendor/**'] ``` If any non-negative globs follow a negative, nothing will be removed from the later set of matches. ```js -['scripts/**/*.js', '!scripts/vendor/', 'scripts/vendor/react.js'] +['scripts/**/*.js', '!scripts/vendor/**', 'scripts/vendor/react.js'] ``` Negative globs can be used as an alternative for restricting double-star globs. ```js -['**/*.js', '!node_modules/'] +['**/*.js', '!node_modules/**'] ``` -In the previous example, if the negative glob was `!node_modules/**/*.js`, every match would have to be compared against the negative glob, which would be extremely slow. +In the previous example, if the negative glob was `!node_modules/**/*.js`, the globbing library wouldn't optimize the negation and every match would have to be compared against the negative glob, which would be extremely slow. To ignore all files in a directory, only add the `/**` glob after the directory name. ## Overlapping globs From 4091bd3aff08801625c6128eec079af4a7b5dccb Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 27 Apr 2019 16:24:54 +0200 Subject: [PATCH 166/225] Docs: Add notes about esm support (closes #2278) --- README.md | 2 ++ docs/getting-started/2-javascript-and-gulpfiles.md | 3 +++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index 013c4077..aac4230e 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,8 @@ exports.default = build; ## Use latest JavaScript version in your gulpfile +__Most new versions of node support most features that Babel provides, except the `import`/`export` syntax. When only that syntax is desired, rename to `gulpfile.esm.js`, install the [esm][esm-module] module, and skip the Babel portion below.__ + Node already supports a lot of __ES2015+__ features, but to avoid compatibility problems we suggest to install Babel and rename your `gulpfile.js` to `gulpfile.babel.js`. ```sh diff --git a/docs/getting-started/2-javascript-and-gulpfiles.md b/docs/getting-started/2-javascript-and-gulpfiles.md index 82573a13..a15fad11 100644 --- a/docs/getting-started/2-javascript-and-gulpfiles.md +++ b/docs/getting-started/2-javascript-and-gulpfiles.md @@ -20,6 +20,8 @@ You can write a gulpfile using a language that requires transpilation, like Type * For TypeScript, rename to `gulpfile.ts` and install the [ts-node][ts-node-module] module. * For Babel, rename to `gulpfile.babel.js` and install the [@babel/register][babel-register-module] module. +__Most new versions of node support most features that TypeScript or Babel provide, except the `import`/`export` syntax. When only that syntax is desired, rename to `gulpfile.esm.js` and install the [esm][esm-module] module.__ + For a more advanced dive into this topic and the full list of supported extensions, see our [gulpfile transpilation][gulpfile-transpilation-advanced] documentation. ## Splitting a gulpfile @@ -33,3 +35,4 @@ Node's module resolution allows you to replace your `gulpfile.js` file with a di [gulpfile-transpilation-advanced]: ../documentation-missing.md [ts-node-module]: https://www.npmjs.com/package/ts-node [babel-register-module]: https://www.npmjs.com/package/@babel/register +[esm-module]: https://www.npmjs.com/package/esm From 5667666ffae15c169f99c7096ca59c05f9440272 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 6 May 2019 19:09:08 +0200 Subject: [PATCH 167/225] Fix: Bind src/dest/symlink to the gulp instance to support esm exports (ref standard-things/esm#797) --- index.js | 3 +++ test/index.test.js | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 test/index.test.js diff --git a/index.js b/index.js index cddf7eb6..8b735212 100644 --- a/index.js +++ b/index.js @@ -16,6 +16,9 @@ function Gulp() { this.registry = this.registry.bind(this); this.tree = this.tree.bind(this); this.lastRun = this.lastRun.bind(this); + this.src = this.src.bind(this); + this.dest = this.dest.bind(this); + this.symlink = this.symlink.bind(this); } util.inherits(Gulp, Undertaker); diff --git a/test/index.test.js b/test/index.test.js new file mode 100644 index 00000000..8921084d --- /dev/null +++ b/test/index.test.js @@ -0,0 +1,60 @@ +'use strict'; + +var expect = require('expect'); + +var gulp = require('../'); + +describe('gulp', function() { + + describe('hasOwnProperty', function() { + it('src', function(done) { + expect(gulp.hasOwnProperty('src')).toEqual(true); + done(); + }); + + it('dest', function(done) { + expect(gulp.hasOwnProperty('dest')).toEqual(true); + done(); + }); + + it('symlink', function(done) { + expect(gulp.hasOwnProperty('symlink')).toEqual(true); + done(); + }); + + it('watch', function(done) { + expect(gulp.hasOwnProperty('watch')).toEqual(true); + done(); + }); + + it('task', function(done) { + expect(gulp.hasOwnProperty('task')).toEqual(true); + done(); + }); + + it('series', function(done) { + expect(gulp.hasOwnProperty('series')).toEqual(true); + done(); + }); + + it('parallel', function(done) { + expect(gulp.hasOwnProperty('parallel')).toEqual(true); + done(); + }); + + it('tree', function(done) { + expect(gulp.hasOwnProperty('tree')).toEqual(true); + done(); + }); + + it('lastRun', function(done) { + expect(gulp.hasOwnProperty('lastRun')).toEqual(true); + done(); + }); + + it('registry', function(done) { + expect(gulp.hasOwnProperty('registry')).toEqual(true); + done(); + }); + }); +}); From b4b5a68373b4c58d6b92321cea64a6ffcc3ff042 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 6 May 2019 19:15:33 +0200 Subject: [PATCH 168/225] Build: Add node 12 to Travis & Azure --- .ci/.azure-pipelines.yml | 6 ++++++ .travis.yml | 1 + 2 files changed, 7 insertions(+) diff --git a/.ci/.azure-pipelines.yml b/.ci/.azure-pipelines.yml index dcdd68e6..2d717af1 100644 --- a/.ci/.azure-pipelines.yml +++ b/.ci/.azure-pipelines.yml @@ -9,6 +9,8 @@ jobs: vmImage: "Ubuntu 16.04" strategy: matrix: + Node_v12: + node_version: 12 Node_v10: node_version: 10 Node_v8: @@ -30,6 +32,8 @@ jobs: vmImage: vs2017-win2016 strategy: matrix: + Node_v12: + node_version: 12 Node_v10: node_version: 10 Node_v8: @@ -54,6 +58,8 @@ jobs: vmImage: macos-10.13 strategy: matrix: + Node_v12: + node_version: 12 Node_v10: node_version: 10 Node_v8: diff --git a/.travis.yml b/.travis.yml index 7e14b195..eda5b000 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ sudo: false language: node_js node_js: + - '12' - '10' - '8' - '6' From 069350a5febf65adc27bc816a7805471b7d96f03 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 6 May 2019 19:23:08 +0200 Subject: [PATCH 169/225] Release: 4.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a67c7d2b..256684af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gulp", - "version": "4.0.1", + "version": "4.0.2", "description": "The streaming build system.", "homepage": "https://gulpjs.com", "author": "Gulp Team (https://gulpjs.com/)", From e408d6f6d0d12711c8c3b3c873ec6b6937e5b430 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 23 May 2019 10:40:35 +0200 Subject: [PATCH 170/225] Scaffold: Add FUNDING.yml with Tidelift integration --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..b77a5a01 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +tidelift: npm/gulp From 3bb4ddcf3a86f69c70e98ce3de645db9c104ec98 Mon Sep 17 00:00:00 2001 From: contra Date: Mon, 3 Jun 2019 03:32:37 -0400 Subject: [PATCH 171/225] Docs: Update README plugin count (#2336) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aac4230e..2139f8f0 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - **Automation** - gulp is a toolkit that helps you automate painful or time-consuming tasks in your development workflow. - **Platform-agnostic** - Integrations are built into all major IDEs and people are using gulp with PHP, .NET, Node.js, Java, and other platforms. -- **Strong Ecosystem** - Use npm modules to do anything you want + over 2000 curated plugins for streaming file transformations +- **Strong Ecosystem** - Use npm modules to do anything you want + over 3000 curated plugins for streaming file transformations - **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use ## What's new in 4.0?! From 876fed9d8efd4acda88274aedd6a566e8de352f2 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 14 Jun 2019 15:21:14 +0900 Subject: [PATCH 172/225] Scaffold: Add security disclosure policy --- .github/SECURITY.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000..1a362ffa --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 4.x.x | :white_check_mark: | +| < 4.0 | :x: | + +## Reporting a Vulnerability + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. From 2a844299c45b15896fd70de83e6a63886895e648 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 14 Jun 2019 15:26:44 +0900 Subject: [PATCH 173/225] Scaffold: Add OpenCollective to funding platforms --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index b77a5a01..9ff36c3d 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ tidelift: npm/gulp +open_collective: gulpjs From dff3c1e5161d09c1fb4f553ed75c60c5463f9486 Mon Sep 17 00:00:00 2001 From: Bryan Stoner Date: Sun, 25 Aug 2019 15:09:02 -0400 Subject: [PATCH 174/225] Docs: Ensure "Inline plugins" example is runnable (#2365) --- docs/getting-started/7-using-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/7-using-plugins.md b/docs/getting-started/7-using-plugins.md index fda30553..5f009217 100644 --- a/docs/getting-started/7-using-plugins.md +++ b/docs/getting-started/7-using-plugins.md @@ -101,7 +101,7 @@ exports.default = function() { .pipe(through2.obj(function(file, _, cb) { if (file.isBuffer()) { const code = uglify.minify(file.contents.toString()) - file.contents = Buffer.from(code) + file.contents = Buffer.from(code.code) } cb(null, file); })) From 467530f4596dd3f3d7d35f76de307a8709085728 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 4 Sep 2019 09:17:59 -0700 Subject: [PATCH 175/225] Docs: Help users understand fake values better --- docs/recipes/automate-release-workflow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-release-workflow.md index 0f18006a..e12646c7 100644 --- a/docs/recipes/automate-release-workflow.md +++ b/docs/recipes/automate-release-workflow.md @@ -26,7 +26,7 @@ gulp.task('changelog', function () { gulp.task('github-release', function(done) { conventionalGithubReleaser({ type: "oauth", - token: '0126af95c0e2d9b0a7c78738c4c00a860b04acc8' // change this to your own GitHub token or use an environment variable + token: 'abcdefghijklmnopqrstuvwxyz1234567890' // change this to your own GitHub token or use an environment variable }, { preset: 'angular' // Or to any other commit message convention you use. }, done); From 6b92e9225d20584a4ea3b7fea6b2d9d3fe159e5e Mon Sep 17 00:00:00 2001 From: Robert Ninness Date: Tue, 1 Oct 2019 14:10:29 +1000 Subject: [PATCH 176/225] Docs: Fix typo in last line of Vinyl usage example (#2382) --- docs/api/vinyl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/vinyl.md b/docs/api/vinyl.md index 771a6c2e..a11ad0f0 100644 --- a/docs/api/vinyl.md +++ b/docs/api/vinyl.md @@ -40,7 +40,7 @@ file.stem = 'foo'; file.path === '/specs/foo.txt'; file.extname === '.txt'; file.extname = '.js'; -file.path === '/specs/file.js'; +file.path === '/specs/foo.js'; ``` ## Signature From be5906b5a20b967e4508aa426223cef4dbc1683d Mon Sep 17 00:00:00 2001 From: Takayuki Sato Date: Sat, 23 Nov 2019 13:39:20 +0900 Subject: [PATCH 177/225] Docs: Add enterprise language --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 2139f8f0..1a039d6c 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,14 @@ * Custom registries were designed, allowing for shared tasks or augmented functionality * Stream implementations were improved, allowing for better conditional and phased builds + +## gulp for enterprise + +Available as part of the Tidelift Subscription + +The maintainers of gulp and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-gulp?utm_source=npm-gulp&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) + + ## Installation Follow our [Quick Start guide][quick-start]. From 7672b045a651ab582cb6a0cbbf392481bfaebf80 Mon Sep 17 00:00:00 2001 From: Aaron Hooper Date: Mon, 20 Jan 2020 18:39:51 +0000 Subject: [PATCH 178/225] Docs: Correct typo in rollup example (#2406) Rollup is imported by name, so it should be called like `rollup()`. --- docs/getting-started/7-using-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/7-using-plugins.md b/docs/getting-started/7-using-plugins.md index 5f009217..20864827 100644 --- a/docs/getting-started/7-using-plugins.md +++ b/docs/getting-started/7-using-plugins.md @@ -37,7 +37,7 @@ const { rollup } = require('rollup'); // Rollup's promise API works great in an `async` task exports.default = async function() { - const bundle = await rollup.rollup({ + const bundle = await rollup({ input: 'src/index.js' }); From 25c1a28b19c174bef10d24e3e8fd3992364d28b0 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 7 Mar 2020 12:05:04 -0700 Subject: [PATCH 179/225] Docs: Fix ESM link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1a039d6c..eaa0250d 100644 --- a/README.md +++ b/README.md @@ -290,3 +290,4 @@ Become a sponsor to get your logo on our README on Github. [quick-start]: https://gulpjs.com/docs/en/getting-started/quick-start [getting-started-guide]: https://gulpjs.com/docs/en/getting-started/quick-start [api-docs]: https://gulpjs.com/docs/en/api/concepts +[esm-module]: https://github.com/standard-things/esm From f15e9de2d302cc167ff936b15a22cb9872cfa2de Mon Sep 17 00:00:00 2001 From: Chinh Do Date: Thu, 2 Apr 2020 18:02:35 -0400 Subject: [PATCH 180/225] Docs: Fix "Async Completion" code example [ci skip] (#2428) --- docs/getting-started/4-async-completion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/4-async-completion.md b/docs/getting-started/4-async-completion.md index 908fcc06..0fa262cd 100644 --- a/docs/getting-started/4-async-completion.md +++ b/docs/getting-started/4-async-completion.md @@ -127,7 +127,7 @@ When not using any of the previous options, you can define your task as an [`asy const fs = require('fs'); async function asyncAwaitTask() { - const { version } = fs.readFileSync('package.json'); + const { version } = JSON.parse(fs.readFileSync('package.json', 'utf8')); console.log(version); await Promise.resolve('some result'); } From 29cb96917824bc47349bbf68d458a2bd00716f8e Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 4 Apr 2020 19:25:39 -0700 Subject: [PATCH 181/225] Docs: Fix MDX compatibility --- docs/api/dest.md | 18 ++++++------ docs/api/last-run.md | 2 +- docs/api/parallel.md | 2 +- docs/api/series.md | 2 +- docs/api/src.md | 68 ++++++++++++++++++++++---------------------- docs/api/symlink.md | 14 ++++----- docs/api/task.md | 4 +-- docs/api/vinyl.md | 4 +-- docs/api/watch.md | 40 +++++++++++++------------- 9 files changed, 77 insertions(+), 77 deletions(-) diff --git a/docs/api/dest.md b/docs/api/dest.md index d4b6fe42..e9d8bb35 100644 --- a/docs/api/dest.md +++ b/docs/api/dest.md @@ -32,7 +32,7 @@ dest(directory, [options]) | parameter | type | note | |:--------------:|:-----:|--------| -| directory
**(required)** | string
function | The path of the output directory where files will be written. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | +| directory
**(required)** | string
function | The path of the output directory where files will be written. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -60,14 +60,14 @@ When `directory` is a function that returns an empty string or `undefined`, emit | name | type | default | note | |:-------:|:------:|-----------|-------| -| cwd | string
function | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | -| mode | number
function | `stat.mode` of the Vinyl object | The mode used when creating files. If not set and `stat.mode` is missing, the process' mode will be used instead. | -| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | -| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | -| append | boolean
function | false | If true, adds contents to the end of the file, instead of replacing existing contents. | -| sourcemaps | boolean
string
function | false | If true, writes inline sourcemaps to the output file. Specifying a `string` path will write external [sourcemaps][sourcemaps-section] at the given path. | -| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | -| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | +| cwd | string
function | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | +| mode | number
function | `stat.mode` of the Vinyl object | The mode used when creating files. If not set and `stat.mode` is missing, the process' mode will be used instead. | +| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | +| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | +| append | boolean
function | false | If true, adds contents to the end of the file, instead of replacing existing contents. | +| sourcemaps | boolean
string
function | false | If true, writes inline sourcemaps to the output file. Specifying a `string` path will write external [sourcemaps][sourcemaps-section] at the given path. | +| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | +| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | ## Metadata updates diff --git a/docs/api/last-run.md b/docs/api/last-run.md index f1bb581e..4e970721 100644 --- a/docs/api/last-run.md +++ b/docs/api/last-run.md @@ -39,7 +39,7 @@ lastRun(task, [precision]) | parameter | type | note | |:--------------:|:------:|-------| -| task
**(required)** | function
string | The task function or the string alias of a registered task. | +| task
**(required)** | function
string | The task function or the string alias of a registered task. | | precision | number | Default: `1000` on Node v0.10, `0` on Node v0.12+. Detailed in [Timestamp precision][timestamp-precision-section] section below. | ### Returns diff --git a/docs/api/parallel.md b/docs/api/parallel.md index c349a880..2df31640 100644 --- a/docs/api/parallel.md +++ b/docs/api/parallel.md @@ -37,7 +37,7 @@ parallel(...tasks) | parameter | type | note | |:--------------:|:------:|-------| -| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | +| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | ### Returns diff --git a/docs/api/series.md b/docs/api/series.md index 0d59a8ca..a0495175 100644 --- a/docs/api/series.md +++ b/docs/api/series.md @@ -37,7 +37,7 @@ series(...tasks) | parameter | type | note | |:--------------:|:------:|-------| -| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | +| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | ### Returns diff --git a/docs/api/src.md b/docs/api/src.md index 243fd9fd..b6c69009 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -35,7 +35,7 @@ src(globs, [options]) | parameter | type | note | |:--------------:|:------:|-------| -| globs | string
array | [Globs][globs-concepts] to watch on the file system. | +| globs | string
array | [Globs][globs-concepts] to watch on the file system. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -55,39 +55,39 @@ When an invalid glob is given in `globs`, throws an error with the message, "Inv | name | type | default | note | |:--------:|:------:|------------|--------| -| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. It may not be possible to buffer the contents of large files.
**Note:** Plugins may not implement support for streaming contents. | -| read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | -| since | date
timestamp
function | | When set, only creates Vinyl objects for files modified since the specified time. | -| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM. | -| sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | -| resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | -| cwd | string | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| base | string | | Explicitly set the `base` property on created Vinyl objects. Detailed in [API Concepts][glob-base-concepts].
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| cwdbase | boolean | false | If true, `cwd` and `base` options should be aligned.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| root | string | | The root path that `globs` are resolved against.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| allowEmpty | boolean | false | When false, `globs` which can only match one file (such as `foo/bar.js`) causes an error to be thrown if they don't find a match. If true, suppresses glob failures.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| uniqueBy | string
function | `'path'` | Remove duplicates from the stream by comparing the string property name or the result of the function.
**Note:** When using a function, the function receives the streamed data (objects containing `cwd`, `base`, `path` properties). | -| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| silent | boolean | true | When true, suppresses warnings from printing on `stderr`.
**Note:** This option is passed directly to [node-glob][node-glob-external] but defaulted to `true` instead of `false`. | -| mark | boolean | false | If true, a `/` character will be appended to directory matches. Generally not needed because paths are normalized within the pipeline.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nosort | boolean | false | If true, disables sorting the glob results.
_This option is passed directly to [node-glob][node-glob-external]._ | -| stat | boolean | false | If true, `fs.stat()` is called on all results. This adds extra overhead and generally should not be used.
_This option is passed directly to [node-glob][node-glob-external]._ | -| strict | boolean | false | If true, an error will be thrown if an unexpected problem is encountered while attempting to read a directory.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [node-glob][node-glob-external]._ | -| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [node-glob][node-glob-external]._ | -| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [node-glob][node-glob-external]._ | -| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nodir | boolean | false | If true, only matches files, not directories.
**Note:** To match only directories, end your glob with a `/`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [node-glob][node-glob-external]._ | -| follow | boolean | false | If true, symlinked directories will be traversed when expanding `**` globs.
**Note:** This can cause problems with cyclical links.
_This option is passed directly to [node-glob][node-glob-external]._ | -| realpath | boolean | false | If true, `fs.realpath()` is called on all results. This may result in dangling links.
_This option is passed directly to [node-glob][node-glob-external]._ | -| cache | object | | A previously generated cache object - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| statCache | object | | A previously generated cache of `fs.Stat` results - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| symlinks | object | | A previously generated cache of symbolic links - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nocomment | boolean | false | When false, treat a `#` character at the start of a glob as a comment.
_This option is passed directly to [node-glob][node-glob-external]._ | +| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. It may not be possible to buffer the contents of large files.
**Note:** Plugins may not implement support for streaming contents. | +| read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | +| since | date
timestamp
function | | When set, only creates Vinyl objects for files modified since the specified time. | +| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM. | +| sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | +| resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | +| cwd | string | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| base | string | | Explicitly set the `base` property on created Vinyl objects. Detailed in [API Concepts][glob-base-concepts].
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| cwdbase | boolean | false | If true, `cwd` and `base` options should be aligned.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| root | string | | The root path that `globs` are resolved against.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| allowEmpty | boolean | false | When false, `globs` which can only match one file (such as `foo/bar.js`) causes an error to be thrown if they don't find a match. If true, suppresses glob failures.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| uniqueBy | string
function | `'path'` | Remove duplicates from the stream by comparing the string property name or the result of the function.
**Note:** When using a function, the function receives the streamed data (objects containing `cwd`, `base`, `path` properties). | +| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| silent | boolean | true | When true, suppresses warnings from printing on `stderr`.
**Note:** This option is passed directly to [node-glob][node-glob-external] but defaulted to `true` instead of `false`. | +| mark | boolean | false | If true, a `/` character will be appended to directory matches. Generally not needed because paths are normalized within the pipeline.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nosort | boolean | false | If true, disables sorting the glob results.
_This option is passed directly to [node-glob][node-glob-external]._ | +| stat | boolean | false | If true, `fs.stat()` is called on all results. This adds extra overhead and generally should not be used.
_This option is passed directly to [node-glob][node-glob-external]._ | +| strict | boolean | false | If true, an error will be thrown if an unexpected problem is encountered while attempting to read a directory.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [node-glob][node-glob-external]._ | +| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [node-glob][node-glob-external]._ | +| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [node-glob][node-glob-external]._ | +| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nodir | boolean | false | If true, only matches files, not directories.
**Note:** To match only directories, end your glob with a `/`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [node-glob][node-glob-external]._ | +| follow | boolean | false | If true, symlinked directories will be traversed when expanding `**` globs.
**Note:** This can cause problems with cyclical links.
_This option is passed directly to [node-glob][node-glob-external]._ | +| realpath | boolean | false | If true, `fs.realpath()` is called on all results. This may result in dangling links.
_This option is passed directly to [node-glob][node-glob-external]._ | +| cache | object | | A previously generated cache object - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| statCache | object | | A previously generated cache of `fs.Stat` results - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| symlinks | object | | A previously generated cache of symbolic links - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nocomment | boolean | false | When false, treat a `#` character at the start of a glob as a comment.
_This option is passed directly to [node-glob][node-glob-external]._ | ## Sourcemaps diff --git a/docs/api/symlink.md b/docs/api/symlink.md index a84665ed..4080a344 100644 --- a/docs/api/symlink.md +++ b/docs/api/symlink.md @@ -32,7 +32,7 @@ symlink(directory, [options]) | parameter | type | note | |:--------------:|:-----:|--------| -| directory
**(required)** | string
function | The path of the output directory where symbolic links will be created. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | +| directory
**(required)** | string
function | The path of the output directory where symbolic links will be created. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -63,15 +63,15 @@ When `directory` is a function that returns an empty string or `undefined`, emit | name | type | default | note | |:-------:|:------:|-----------|-------| -| cwd | string
function | `process.cwd()` |The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | -| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | -| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | -| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | -| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | +| cwd | string
function | `process.cwd()` |The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | +| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | +| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | +| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | +| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | ## Symbolic links on Windows -When creating symbolic links on Windows, a `type` argument is passed to Node's `fs.symlink()` method which specifies the type of target being linked. The link type is set to: +When creating symbolic links on Windows, a `type` argument is passed to Node's `fs.symlink()` method which specifies the type of target being linked. The link type is set to: * `'file'` when the target is a regular file * `'junction'` when the target is a directory * `'dir'` when the target is a directory and the user disables the `useJunctions` option diff --git a/docs/api/task.md b/docs/api/task.md index 12919b06..21aaec40 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -62,7 +62,7 @@ Since any registered task can be run from the command line, avoid using spaces i | parameter | type | note | |:--------------:|:------:|-------| | taskName | string | An alias for the task function within the the task system. Not needed when using named functions for `taskFunction`. | -| taskFunction
**(required)** | function | A [task function][task-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | +| taskFunction
**(required)** | function | A [task function][task-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | ### Returns @@ -78,7 +78,7 @@ When registering a task where `taskName` is missing and `taskFunction` is anonym | property | type | note | |:--------------:|:------:|-------| -| name | string | A special property of named functions. Used to register the task.
**Note:** [`name`][function-name-external] is not writable; it cannot be set or changed. | +| name | string | A special property of named functions. Used to register the task.
**Note:** [`name`][function-name-external] is not writable; it cannot be set or changed. | | displayName | string | When attached to a `taskFunction` creates an alias for the task. If using characters that aren't allowed in function names, use this property. | | description | string | When attached to a `taskFunction` provides a description to be printed by the command line when listing tasks. | | flags | object | When attached to a `taskFunction` provides flags to be printed by the command line when listing tasks. The keys of the object represent the flags and the values are their descriptions. | diff --git a/docs/api/vinyl.md b/docs/api/vinyl.md index a11ad0f0..da8418f7 100644 --- a/docs/api/vinyl.md +++ b/docs/api/vinyl.md @@ -72,7 +72,7 @@ When any passed options don't conform to the [instance property definitions][ins | path | string | | The full, absolute file path. Will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | | history | array | `[ ]` | An array of paths to pre-populate the `history` of a Vinyl instance. Usually comes from deriving a new Vinyl object from a previous Vinyl object. If `path` and `history` are both passed, `path` is appended to `history`. Each item will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | | stat | object | | An instance of `fs.Stats`, usually the result of calling `fs.stat()` on a file. Used to determine if a Vinyl object represents a directory or symbolic link. | -| contents | ReadableStream
Buffer
`null` | `null` | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | +| contents | ReadableStream
Buffer
`null` | `null` | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | Any other properties on `options` will be directly assigned to the Vinyl instance. @@ -93,7 +93,7 @@ All internally managed paths - any instance property except `contents` and `stat | property | type | description | throws | |:-----------:|:------:|----------------|----------| -| contents | ReadableStream
Buffer
`null` | Gets and sets the contents of the virtual file. If set to a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | If set to any value other than a ReadableStream, a Buffer, or `null`. | +| contents | ReadableStream
Buffer
`null` | Gets and sets the contents of the virtual file. If set to a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | If set to any value other than a ReadableStream, a Buffer, or `null`. | | stat | object | Gets and sets an instance of [`fs.Stats`][fs-stats-concepts]. Used when determining if a Vinyl object represents a directory or symbolic link. | | | cwd | string | Gets and sets the current working directory. Used for deriving relative paths. | If set to an empty string or any non-string value. | | base | string | Gets and sets the base directory. Used to calculate the `relative` instance property. On a Vinyl object generated by `src()` will be set to the [glob base][glob-base-concepts]. If set to `null` or `undefined`, falls back to the value of the `cwd` instance property. | If set to an empty string or any non-string value (except `null` or `undefined`). | diff --git a/docs/api/watch.md b/docs/api/watch.md index 2b9dde27..bc9d601e 100644 --- a/docs/api/watch.md +++ b/docs/api/watch.md @@ -30,9 +30,9 @@ watch(globs, [options], [task]) | parameter | type | note | |:--------------:|:-----:|--------| -| globs
**(required)** | string
array | [Globs][globs-concepts] to watch on the file system. | +| globs
**(required)** | string
array | [Globs][globs-concepts] to watch on the file system. | | options | object | Detailed in [Options][options-section] below. | -| task | function
string | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. | +| task | function
string | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. | ### Returns @@ -48,24 +48,24 @@ When a string or array is passed as `task`, throws an error with the message, "w | name | type | default | note | |:-------:|:------:|-----------|--------| -| ignoreInitial | boolean | true | If false, the task is called during instantiation as file paths are discovered. Use to trigger the task during startup.
**Note:** This option is passed to [chokidar][chokidar-external] but is defaulted to `true` instead of `false`. | +| ignoreInitial | boolean | true | If false, the task is called during instantiation as file paths are discovered. Use to trigger the task during startup.
**Note:** This option is passed to [chokidar][chokidar-external] but is defaulted to `true` instead of `false`. | | delay | number | 200 | The millisecond delay between a file change and task execution. Allows for waiting on many changes before executing a task, e.g. find-and-replace on many files. | | queue | boolean | true | When true and the task is already running, any file changes will queue a single task execution. Keeps long running tasks from overlapping. | -| events | string
array | [ 'add',
'change',
'unlink' ] | The events being watched to trigger task execution. Can be `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, and/or `'error'`. Additionally `'all'` is available, which represents all events other than `'ready'` and `'error'`.
_This option is passed directly to [chokidar][chokidar-external]._ | -| persistent | boolean | true | If false, the watcher will not keep the Node process running. Disabling this option is not recommended.
_This option is passed directly to [chokidar][chokidar-external]._ | -| ignored | array
string
RegExp
function | | Defines globs to be ignored. If a function is provided, it will be called twice per path - once with just the path, then with the path and the `fs.Stats` object of that file.
_This option is passed directly to [chokidar][chokidar-external]._ | -| followSymlinks | boolean | true | When true, changes to both symbolic links and the linked files trigger events. If false, only changes to the symbolic links trigger events.
_This option is passed directly to [chokidar][chokidar-external]._ | -| cwd | string | | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [chokidar][chokidar-external]._ | -| disableGlobbing | boolean | false | If true, all `globs` are treated as literal path names, even if they have special characters.
_This option is passed directly to [chokidar][chokidar-external]._ | -| usePolling | boolean | false | When false, the watcher will use `fs.watch()` (or [fsevents][fsevents-external] on Mac) for watching. If true, use `fs.watchFile()` polling instead - needed for successfully watching files over a network or other non-standard situations. Overrides the `useFsEvents` default.
_This option is passed directly to [chokidar][chokidar-external]._ | -| interval | number | 100 | Combine with `usePolling: true`. Interval of file system polling.
_This option is passed directly to [chokidar][chokidar-external]._ | -| binaryInterval | number | 300 | Combine with `usePolling: true`. Interval of file system polling for binary files.
_This option is passed directly to [chokidar][chokidar-external]._ | -| useFsEvents | boolean | true | When true, uses fsevents for watching if available. If explicitly set to true, supersedes the `usePolling` option. If set to false, automatically sets `usePolling` to true.
_This option is passed directly to [chokidar][chokidar-external]._ | -| alwaysStat | boolean | false | If true, always calls `fs.stat()` on changed files - will slow down file watcher. The `fs.Stat` object is only available if you are using the chokidar instance directly.
_This option is passed directly to [chokidar][chokidar-external]._ | -| depth | number | | Indicates how many nested levels of directories will be watched.
_This option is passed directly to [chokidar][chokidar-external]._ | -| awaitWriteFinish | boolean | false | Do not use this option, use `delay` instead.
_This option is passed directly to [chokidar][chokidar-external]._ | -| ignorePermissionErrors | boolean | false | Set to true to watch files that don't have read permissions. Then, if watching fails due to EPERM or EACCES errors, they will be skipped silently.
_This option is passed directly to [chokidar][chokidar-external]._ | -| atomic | number | 100 | Only active if `useFsEvents` and `usePolling` are false. Automatically filters out artifacts that occur from "atomic writes" by some editors. If a file is re-added within the specified milliseconds of being deleted, a change event - instead of unlink then add - will be emitted.
_This option is passed directly to [chokidar][chokidar-external]._ | +| events | string
array | [ 'add',
'change',
'unlink' ] | The events being watched to trigger task execution. Can be `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, and/or `'error'`. Additionally `'all'` is available, which represents all events other than `'ready'` and `'error'`.
_This option is passed directly to [chokidar][chokidar-external]._ | +| persistent | boolean | true | If false, the watcher will not keep the Node process running. Disabling this option is not recommended.
_This option is passed directly to [chokidar][chokidar-external]._ | +| ignored | array
string
RegExp
function | | Defines globs to be ignored. If a function is provided, it will be called twice per path - once with just the path, then with the path and the `fs.Stats` object of that file.
_This option is passed directly to [chokidar][chokidar-external]._ | +| followSymlinks | boolean | true | When true, changes to both symbolic links and the linked files trigger events. If false, only changes to the symbolic links trigger events.
_This option is passed directly to [chokidar][chokidar-external]._ | +| cwd | string | | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [chokidar][chokidar-external]._ | +| disableGlobbing | boolean | false | If true, all `globs` are treated as literal path names, even if they have special characters.
_This option is passed directly to [chokidar][chokidar-external]._ | +| usePolling | boolean | false | When false, the watcher will use `fs.watch()` (or [fsevents][fsevents-external] on Mac) for watching. If true, use `fs.watchFile()` polling instead - needed for successfully watching files over a network or other non-standard situations. Overrides the `useFsEvents` default.
_This option is passed directly to [chokidar][chokidar-external]._ | +| interval | number | 100 | Combine with `usePolling: true`. Interval of file system polling.
_This option is passed directly to [chokidar][chokidar-external]._ | +| binaryInterval | number | 300 | Combine with `usePolling: true`. Interval of file system polling for binary files.
_This option is passed directly to [chokidar][chokidar-external]._ | +| useFsEvents | boolean | true | When true, uses fsevents for watching if available. If explicitly set to true, supersedes the `usePolling` option. If set to false, automatically sets `usePolling` to true.
_This option is passed directly to [chokidar][chokidar-external]._ | +| alwaysStat | boolean | false | If true, always calls `fs.stat()` on changed files - will slow down file watcher. The `fs.Stat` object is only available if you are using the chokidar instance directly.
_This option is passed directly to [chokidar][chokidar-external]._ | +| depth | number | | Indicates how many nested levels of directories will be watched.
_This option is passed directly to [chokidar][chokidar-external]._ | +| awaitWriteFinish | boolean | false | Do not use this option, use `delay` instead.
_This option is passed directly to [chokidar][chokidar-external]._ | +| ignorePermissionErrors | boolean | false | Set to true to watch files that don't have read permissions. Then, if watching fails due to EPERM or EACCES errors, they will be skipped silently.
_This option is passed directly to [chokidar][chokidar-external]._ | +| atomic | number | 100 | Only active if `useFsEvents` and `usePolling` are false. Automatically filters out artifacts that occur from "atomic writes" by some editors. If a file is re-added within the specified milliseconds of being deleted, a change event - instead of unlink then add - will be emitted.
_This option is passed directly to [chokidar][chokidar-external]._ | ## Chokidar instance @@ -118,7 +118,7 @@ Adds additional globs to an already-running watcher instance. | parameter | type | note | |:-------------:|:-----:|--------| -| globs | string
array | The additional globs to be watched. | +| globs | string
array | The additional globs to be watched. | `watcher.unwatch(globs)` @@ -126,7 +126,7 @@ Removes globs that are being watched, while the watcher continues with the remai | parameter | type | note | |:-------------:|:-----:|--------| -| globs | string
array | The globs to be removed. | +| globs | string
array | The globs to be removed. | [chokidar-instance-section]: #chokidar-instance [options-section]: #options From b7d9cc1825a77381f1ea424025777deaead50343 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 15 Apr 2020 21:38:01 -0700 Subject: [PATCH 182/225] Docs: Add Tidelift page --- docs/support/for-enterprise.md | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/support/for-enterprise.md diff --git a/docs/support/for-enterprise.md b/docs/support/for-enterprise.md new file mode 100644 index 00000000..2e2b2694 --- /dev/null +++ b/docs/support/for-enterprise.md @@ -0,0 +1,53 @@ + + +# Gulp for enterprise + +Available as part of the Tidelift Subscription. + +Tidelift is working with the maintainers of Gulp and thousands of other +open source projects to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. + +Learn more + +Request a demo + +## Enterprise-ready open source software—managed for you + +The Tidelift Subscription is a managed open source subscription for application dependencies covering millions of open source projects across JavaScript, Python, Java, PHP, Ruby, .NET, and more. + +Your subscription includes: + +* **Security updates** + + Tidelift’s security response team coordinates patches for new breaking security vulnerabilities and alerts immediately through a private channel, so your software supply chain is always secure. + +* **Licensing verification and indemnification** + + Tidelift verifies license information to enable easy policy enforcement and adds intellectual property indemnification to cover creators and users in case something goes wrong. You always have a 100% up-to-date bill of materials for your dependencies to share with your legal team, customers, or partners. + +* **Maintenance and code improvement** + + Tidelift ensures the software you rely on keeps working as long as you need it to work. Your managed dependencies are actively maintained and we recruit additional maintainers where required. + +* **Package selection and version guidance** + + We help you choose the best open source packages from the start—and then guide you through updates to stay on the best releases as new issues arise. + +* **Roadmap input** + + Take a seat at the table with the creators behind the software you use. Tidelift’s participating maintainers earn more income as their software is used by more subscribers, so they’re interested in knowing what you need. + +* **Tooling and cloud integration** + + Tidelift works with GitHub, GitLab, BitBucket, and more. We support every cloud platform (and other deployment targets, too). + +The end result? All of the capabilities you expect from commercial-grade software, for the full breadth of open source you use. That means less time grappling with esoteric open source trivia, and more time building your own applications—and your business. + +Learn more + +Request a demo From 27166008c54b262f8718a26378096bc6d82f21fa Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 16 May 2020 15:52:12 -0700 Subject: [PATCH 183/225] Scaffold: Fallback to organization community files --- .github/FUNDING.yml | 2 -- .github/ISSUE_TEMPLATE.md | 28 ---------------------------- 2 files changed, 30 deletions(-) delete mode 100644 .github/FUNDING.yml delete mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 9ff36c3d..00000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -tidelift: npm/gulp -open_collective: gulpjs diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 1ec2c2c7..00000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,28 +0,0 @@ -This tracker is for bug reports only. - - -Before opening an issue, please make sure you've checked the following: - -- For support requests, please use Stack Overflow (stackoverflow.com) or Gitter (see the README). - -- If the bug is in a plugin, open an issue on the plugin repository, not the gulp repository. - -- If you're getting a deprecated module warning, don't worry about it: we're aware of it and it's not an issue. To make it go away, update to Gulp 4.0. - -- If you're asking about the status of Gulp 4, please don't! You can see the remaining issues on the gulp4 label: https://github.com/gulpjs/gulp/issues?q=is%3Aissue+is%3Aopen+label%3Agulp4 - ----- - -**What were you expecting to happen?** - -**What actually happened?** - -**Please post a sample of your gulpfile (preferably reduced to just the bit that's not working)** - -```js -gulp.task(function () {}); -``` - -**What version of gulp are you using?** - -**What versions of npm and node are you using?** From 0864ee0de5282e1a07907c4e51f0fca025c6772d Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 16 May 2020 17:45:55 -0700 Subject: [PATCH 184/225] Docs: Update gulp-imagemin usage (closes #2432) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eaa0250d..2095659e 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,7 @@ const paths = { function images() { return gulp.src(paths.images.src, {since: gulp.lastRun(images)}) - .pipe(imagemin({optimizationLevel: 5})) + .pipe(imagemin()) .pipe(gulp.dest(paths.images.dest)); } From 1ce063729714517da92310c8308d50e9541e4a47 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 16 May 2020 17:56:59 -0700 Subject: [PATCH 185/225] Scaffold: Remove support template --- .github/support.yml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .github/support.yml diff --git a/.github/support.yml b/.github/support.yml deleted file mode 100644 index cd6325e3..00000000 --- a/.github/support.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Configuration for support-requests - https://github.com/dessant/support-requests -supportLabel: support -supportComment: > - Issues are reserved for bugs and features. Here are a few places to find answers to your question: - - * For community support, use the `gulp` tag on [StackOverflow](https://stackoverflow.com/questions/tagged/gulp). - - * Participate in community chat on [Gitter](https://gitter.im/gulpjs/gulp). - - * To get paid support directly from the maintainers, sign up for [Tidelift](https://tidelift.com/subscription/pkg/npm-gulp?utm_source=npm-gulp&utm_medium=referral&utm_campaign=support). Subscribers should email support@tidelift.com, mention that it's a question for Gulp, and describe your question. Straightforward questions are answered as part of your subscription. Additional consulting hours are available for more complex help. -close: true -lock: false -setLockReason: false From 77393e18ae3c8eb439ad78734eb8dcc02e5a9ff4 Mon Sep 17 00:00:00 2001 From: Dirk Puge <67125647+dirkpuge@users.noreply.github.com> Date: Sun, 21 Jun 2020 15:48:07 -0400 Subject: [PATCH 186/225] Docs: End bullet items with a period (#2457) --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2095659e..162f1bee 100644 --- a/README.md +++ b/README.md @@ -12,19 +12,19 @@ - **Automation** - gulp is a toolkit that helps you automate painful or time-consuming tasks in your development workflow. - **Platform-agnostic** - Integrations are built into all major IDEs and people are using gulp with PHP, .NET, Node.js, Java, and other platforms. -- **Strong Ecosystem** - Use npm modules to do anything you want + over 3000 curated plugins for streaming file transformations -- **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use +- **Strong Ecosystem** - Use npm modules to do anything you want + over 3000 curated plugins for streaming file transformations. +- **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use. ## What's new in 4.0?! -* The task system was rewritten from the ground-up, allowing task composition using `series()` and `parallel()` methods -* The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system -* First-class support was added for incremental builds using `lastRun()` -* A `symlink()` method was exposed to create symlinks instead of copying files +* The task system was rewritten from the ground-up, allowing task composition using `series()` and `parallel()` methods. +* The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system. +* First-class support was added for incremental builds using `lastRun()`. +* A `symlink()` method was exposed to create symlinks instead of copying files. * Built-in support for sourcemaps was added - the gulp-sourcemaps plugin is no longer necessary! -* Task registration of exported functions - using node or ES exports - is now recommended -* Custom registries were designed, allowing for shared tasks or augmented functionality -* Stream implementations were improved, allowing for better conditional and phased builds +* Task registration of exported functions - using node or ES exports - is now recommended. +* Custom registries were designed, allowing for shared tasks or augmented functionality. +* Stream implementations were improved, allowing for better conditional and phased builds. ## gulp for enterprise From e7a20a48862179192b712356ae179b1003d11b98 Mon Sep 17 00:00:00 2001 From: Ru Singh Date: Tue, 28 Jul 2020 01:44:58 +0000 Subject: [PATCH 187/225] Docs: Update rollup recipe (#2466) --- docs/recipes/rollup-with-rollup-stream.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/recipes/rollup-with-rollup-stream.md b/docs/recipes/rollup-with-rollup-stream.md index 2a8840f2..ef5dd4b4 100644 --- a/docs/recipes/rollup-with-rollup-stream.md +++ b/docs/recipes/rollup-with-rollup-stream.md @@ -4,14 +4,14 @@ Like Browserify, [Rollup](https://rollupjs.org/) is a bundler and thus only fits ## Basic usage ```js -// npm install --save-dev gulp rollup-stream vinyl-source-stream +// npm install --save-dev gulp @rollup/stream@1 vinyl-source-stream var gulp = require('gulp'); var rollup = require('rollup-stream'); var source = require('vinyl-source-stream'); gulp.task('rollup', function() { return rollup({ - entry: './src/main.js' + input: './src/main.js' }) // give the file the name you want to output with @@ -24,7 +24,7 @@ gulp.task('rollup', function() { ## Usage with sourcemaps ```js -// npm install --save-dev gulp rollup-stream gulp-sourcemaps vinyl-source-stream vinyl-buffer +// npm install --save-dev gulp @rollup/stream@1 gulp-sourcemaps vinyl-source-stream vinyl-buffer // optional: npm install --save-dev gulp-rename var gulp = require('gulp'); var rollup = require('rollup-stream'); @@ -35,8 +35,9 @@ var buffer = require('vinyl-buffer'); gulp.task('rollup', function() { return rollup({ - entry: './src/main.js', - sourceMap: true + input: './src/main.js', + sourcemap: true, + format: 'umd' }) // point to the entry file. From 9f12c2d25a50f175b6bfe47c5485ab93782b1f7f Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 28 Jul 2020 19:12:28 +0200 Subject: [PATCH 188/225] Docs: Begin adding Polish translations (#2456) --- docs/README.md | 1 + docs/locale/pl_PL/README.md | 66 ++++++++++++++ docs/locale/pl_PL/api/concepts.md | 77 +++++++++++++++++ .../pl_PL/getting-started/1-quick-start.md | 85 +++++++++++++++++++ .../2-javascript-and-gulpfiles.md | 31 +++++++ 5 files changed, 260 insertions(+) create mode 100644 docs/locale/pl_PL/README.md create mode 100644 docs/locale/pl_PL/api/concepts.md create mode 100644 docs/locale/pl_PL/getting-started/1-quick-start.md create mode 100644 docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md diff --git a/docs/README.md b/docs/README.md index 9b5955ac..939c8285 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,6 +7,7 @@ * [Why Use Pump?](why-use-pump/README.md) - Why to use the `pump` module instead of calling `.pipe` yourself * [Simplified Chinese documentation][SimplifiedChineseDocs] - gulp 简体中文文档 * [Korean documentation][KoreanDocs] - gulp 한국어 참조 문서 +* [Polish documentation](/docs/locale/pl_PL/README.md) - gulp Dokumentacja ## FAQ diff --git a/docs/locale/pl_PL/README.md b/docs/locale/pl_PL/README.md new file mode 100644 index 00000000..ced80144 --- /dev/null +++ b/docs/locale/pl_PL/README.md @@ -0,0 +1,66 @@ +# Dokumentacja gulp + +* [Pierwsze kroki](getting-started/) - Pierwsze kroki z gulp +* [Dokumentacja API](/docs/api/) - Interfejs programowania, zdefiniowany +* [Dokumentacja CLI](/docs/CLI.md) - Dowiedz się, jak wywoływać taski i korzystać z kompilatorów +* [Pisanie wtyczki](/docs/writing-a-plugin/) - Podstawy pisania wtyczki gulp +* [Czemu używać Pump?](/docs/why-use-pump/README.md) - Dlaczego używać modułu `pump` zamiast wywoływać `.pipe` yourself +* [Dokumentacja język chiński uproszczony][SimplifiedChineseDocs] - gulp 简体中文文档 +* [Dokumentacja język koreański][KoreanDocs] - gulp 한국어 참조 문서 +* [Dokumentacja język polski][PolishDocs] - gulp Dokumentacja + + +## FAQ + +Zobacz [FAQ](/docs/FAQ.md) aby uzyskać odpowiedzi na najczęściej zadawane pytania. + + +## Receptury + +Społeczność napisała [receptury](/docs/recipes#recipes) dla typowych przypadków użycia gulp. + + +## Nadal masz pytania? + +Napisz post na [StackOverflow z tagiem #gulp](https://stackoverflow.com/questions/tagged/gulp) lub wpadnij z nami na czat [#gulpjs](https://webchat.freenode.net/?channels=gulpjs) na [Freenode](https://freenode.net/). + +## Wideo +* [Wstęp do Gulp 4](https://youtu.be/N42LQ2dLoA8) prezentowany przez @addyosmani oraz @gauntface + +## Książki +* [Developing a gulp Edge](http://shop.oreilly.com/product/9781939902146.do) +* [Getting Started with Gulp – Second Edition](https://www.packtpub.com/application-development/getting-started-gulp-%E2%80%93-second-edition) - Travis Maynard, Packt (April 2017) + + +## Artykuły +* [Tagtree intro to gulp video](http://tagtree.io/gulp) +* [Introduction to node.js streams](https://github.com/substack/stream-handbook) +* [Video introduction to node.js streams](https://www.youtube.com/watch?v=QgEuZ52OZtU) +* [Getting started with gulp (by @markgdyr)](https://markgoodyear.com/2014/01/getting-started-with-gulp/) +* [A cheatsheet for gulp](https://github.com/osscafe/gulp-cheatsheet) +* [Why you shouldn’t create a gulp plugin (or, how to stop worrying and learn to love existing node packages)](http://blog.overzealous.com/post/74121048393/why-you-shouldnt-create-a-gulp-plugin-or-how-to-stop) +* [Inspiration (slides) about why gulp was made](http://slid.es/contra/gulp) +* [Building With Gulp](http://www.smashingmagazine.com/2014/06/11/building-with-gulp/) +* [Gulp - The Basics (screencast)](https://www.youtube.com/watch?v=dwSLFai8ovQ) +* [Get started with gulp (video series)](https://www.youtube.com/playlist?list=PLRk95HPmOM6PN-G1xyKj9q6ap_dc9Yckm) +* [Optimize your web code with gulp](http://www.linuxuser.co.uk/tutorials/optimise-your-web-code-with-gulp-js) +* [Automate Your Tasks Easily with Gulp.js ](https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js) +* [How to upgrade to Gulp v4](https://www.liquidlight.co.uk/blog/article/how-do-i-update-to-gulp-4/) + +## Przykłady + +- [Web Starter Kit gulpfile](https://github.com/google/web-starter-kit/blob/master/gulpfile.babel.js) + + +## Licencja + +Cała dokumentacja objęta jest licencją CC0 *(rób co chcesz - domena publiczna)*. + +[![CC0](https://i.creativecommons.org/p/zero/1.0/88x31.png)](https://creativecommons.org/publicdomain/zero/1.0/) + +W zakresie, w jakim jest to możliwe na mocy prawa, [Fractal](http://wearefractal.com) zrzekł się wszelkich praw autorskich i pokrewnych lub powiązanych do tego dzieła. + +[SpanishDocs]: https://github.com/bucaran/gulp-docs-es +[SimplifiedChineseDocs]: https://github.com/lisposter/gulp-docs-zh-cn +[KoreanDocs]: https://github.com/preco21/gulp-docs-ko +[PolishDocs]: /docs/locale/pl_PL/README.md diff --git a/docs/locale/pl_PL/api/concepts.md b/docs/locale/pl_PL/api/concepts.md new file mode 100644 index 00000000..d23325bc --- /dev/null +++ b/docs/locale/pl_PL/api/concepts.md @@ -0,0 +1,77 @@ +# Pojęcia + +Poniższe pojęcia są niezbędne do zrozumienia dokumentacji API. Będą się do nich odwoływać w całości, wróć do tej strony, aby uzyskać szczegółowe wyjaśnienia. + +Jeśli jesteś tu nowy, zacznij od [Poradnik wprowadzający][quick-start-docs]. + +## Vinyl + +Vinyl to obiekt metadanych opisujący plik. Główne właściwości instancji Vinyl to `path` i `contents` - podstawowe aspekty pliku w systemie plików. Obiekty Vinyl mogą być używane do opisywania plików z wielu źródeł - w lokalnym systemie plików lub dowolnej opcji zdalnego przechowywania. + +## Adaptery Vinyl + +Chociaż Vinyl zapewnia sposób na opisanie pliku, potrzebny jest sposób na dostęp do tych plików. Każde źródło pliku jest dostępne za pomocą adaptera Vinyl. + +Adapter udostępnia: +* Metoda z podpisem `src (globs, [opcje])` i zwraca strumień, który produkuje obiekty Vinyl. +* Metoda z podpisem `dest (folder, [opcje])` i zwraca strumień, który zużywa obiekty Vinyl. +* Wszelkie dodatkowe metody specyficzne dla ich nośnika wejścia / wyjścia - takie jak metoda `symlink`, którą zapewnia `winyl-fs`. Powinny zawsze zwracać strumienie, które produkują i / lub zużywają obiekty Vinyl. + +## Zadania + +Każde zadanie gulp to asynchroniczna funkcja JavaScript, która albo przyjmuje wywołanie zwrotne z pierwszym błędem, albo zwraca strumień, obietnicę, emiter zdarzeń, proces podrzędny lub observable. Z powodu pewnych ograniczeń platformy zadania synchroniczne nie są obsługiwane. + +Aby uzyskać bardziej szczegółowe wyjaśnienie, patrz [Tworzenie zadań][creating-tasks-doc]. + +## Globs + +Glob jest ciągiem literałów i / lub symboli wieloznacznych, takich jak `*`, `**` lub `!`, używanych do dopasowania ścieżek plików. Globbing to czynność polegająca na lokalizowaniu plików w systemie plików przy użyciu co najmniej jednego globu. + +Jeśli nie masz doświadczenia z globami, zobacz [Wyjaśnianie Globs][explaining-globs-docs]. + +## Glob base + +Glob base - czasami nazywany globem parent - to segment ścieżki przed znakami specjalnymi w ciągu globu. Jako taka, globalną bazą `/src /js/**. Js` jest `/src/js/`. Wszystkie ścieżki pasujące do globu mają tę samą bazę globalną - ten segment ścieżki nie może być zmienny. + +Instancje Vinyl generowane przez `src ()` są konstruowane z ustawieniem glob base jako ich właściwości `base`. Po zapisaniu do systemu plików za pomocą `dest ()`, `base` zostanie usunięte ze ścieżki wyjściowej, aby zachować struktury katalogów. + +Aby uzyskać więcej szczegółowych informacji, zobacz [glob-parent][glob-parent-external] repository. + +## File system stats + +Metadane pliku są dostarczane jako instancja węzła [`fs.Stats`][fs-stats-external]. Jest dostępny jako właściwość `stat` w twoich instancjach Vinyl i używany wewnętrznie do ustalenia, czy obiekt Vinyl reprezentuje katalog lub dowiązanie symboliczne. Po zapisaniu w systemie plików uprawnienia i wartości czasu są synchronizowane z właściwością `stat` obiektu Vinyl. + +## File system modes + +Tryby systemu plików określają, jakie uprawnienia istnieją dla pliku. Większość plików i katalogów w twoim systemie plików będzie miała dość permisywny tryb, pozwalający gulpowi na odczyt / zapis / aktualizację plików w twoim imieniu. Domyślnie gulp tworzy pliki z tymi samymi uprawnieniami, co uruchomiony proces, ale możesz skonfigurować tryby za pomocą opcji w `src ()`, `dest ()` itp. Jeśli masz problemy z uprawnieniami (EPERM), sprawdź tryby plików. + +## Moduły + +Gulp składa się z wielu małych modułów połączonych ze sobą w celu zapewnienia spójnej pracy. Używając [semver][semver-external] w małych modułach, możemy wydać poprawki błędów i funkcje bez publikowania nowych wersji gulp. Często, gdy nie widać postępu w głównym repozytorium, praca jest wykonywana w jednym z tych modułów. + +Jeśli masz problemy, sprawdź, czy bieżące moduły zostały zaktualizowane za pomocą polecenia `npm update`. Jeśli problem będzie się powtarzał, otwórz problem w indywidualnym repozytorium projektu. + +* [undertaker][undertaker-external] - the task registration system +* [vinyl][vinyl-external] - the virtual file objects +* [vinyl-fs][vinyl-fs-external] - a vinyl adapter to your local file system +* [glob-watcher][glob-watcher-external] - the file watcher +* [bach][bach-external] - task orchestration using `series()` and `parallel()` +* [last-run][last-run-external] - tracks the last run time of a task +* [vinyl-sourcemap][vinyl-sourcemap-external] - built-in sourcemap support +* [gulp-cli][gulp-cli-external] - the command line interface for interacting with gulp + + +[quick-start-docs]: ../getting-started/1-quick-start.md +[creating-tasks-doc]: ../getting-started/3-creating-tasks.md +[explaining-globs-docs]: ../getting-started/6-explaining-globs.md +[undertaker-external]: https://github.com/gulpjs/undertaker +[vinyl-external]: https://github.com/gulpjs/vinyl +[vinyl-fs-external]: https://github.com/gulpjs/vinyl-fs +[glob-watcher-external]: https://github.com/gulpjs/glob-watcher +[bach-external]: https://github.com/gulpjs/bach +[last-run-external]: https://github.com/gulpjs/last-run +[vinyl-sourcemap-external]: https://github.com/gulpjs/vinyl-sourcemap +[gulp-cli-external]: https://github.com/gulpjs/gulp-cli +[semver-external]: https://semver.org +[fs-stats-external]: https://nodejs.org/api/fs.html#fs_class_fs_stats +[glob-parent-external]: https://github.com/es128/glob-parent diff --git a/docs/locale/pl_PL/getting-started/1-quick-start.md b/docs/locale/pl_PL/getting-started/1-quick-start.md new file mode 100644 index 00000000..3d1b54df --- /dev/null +++ b/docs/locale/pl_PL/getting-started/1-quick-start.md @@ -0,0 +1,85 @@ +# Szybki start + +Jeśli wcześniej instalowałeś gulp globalnie, uruchom `npm rm --global gulp` przed wykonaniem tych instrukcji. Aby uzyskać więcej informacji, przeczytaj to [Sip][sip-article]. + +## Sprawdź dla node, npm, oraz npx +```sh +node --version +``` +![Output: v8.11.1][img-node-version-command] +```sh +npm --version +``` +![Output: 5.6.0][img-npm-version-command] +```sh +npx --version +``` +![Output: 9.7.1][img-npx-version-command] + +If they are not installed, follow the instructions [here][node-install]. + +## Zainstaluj narzędzie wiersza poleceń gulp +```sh +npm install --global gulp-cli +``` + + +## Utwórz katalog projektu i przejdź do niego +```sh +npx mkdirp my-project +``` +```sh +cd my-project +``` + +## Utwórz plik package.json w katalogu projektu +```sh +npm init +``` + +To poprowadzi cię przez nadanie projektowi nazwy, wersji, opisu itp. + +## Zainstaluj pakiet gulp w swoich devDependencies +```sh +npm install --save-dev gulp +``` + +## Sprawdź swoje wersje gulp + +```sh +gulp --version +``` + +Upewnij się, że dane wyjściowe odpowiadają zrzutowi ekranu poniżej, w przeciwnym razie może być konieczne ponowne uruchomienie kroków opisanych w tym przewodniku. + +![Output: CLI version 2.0.1 & Local version 4.0.0][img-gulp-version-command] + +## Stwórz gulpfile +Za pomocą edytora tekstu utwórz plik o nazwie gulpfile.js w katalogu głównym projektu z następującymi treściami: +```js +function defaultTask(cb) { + // place code for your default task here + cb(); +} + +exports.default = defaultTask +``` + +## Przetestuj to +Uruchom polecenie gulp w katalogu projektu: +```sh +gulp +``` +Aby uruchomić wiele zadań, możesz użyć `gulp `. + +## Wynik +Zadanie domyślne zostanie uruchomione i nic nie zrobi. +![Output: Starting default & Finished default][img-gulp-command] + +[sip-article]: https://medium.com/gulpjs/gulp-sips-command-line-interface-e53411d4467 +[node-install]: https://nodejs.org/en/ +[img-node-version-command]: https://gulpjs.com/img/docs-node-version-command.png +[img-npm-version-command]: https://gulpjs.com/img/docs-npm-version-command.png +[img-npx-version-command]: https://gulpjs.com/img/docs-npx-version-command.png +[img-gulp-version-command]: https://gulpjs.com/img/docs-gulp-version-command.png +[img-gulp-command]: https://gulpjs.com/img/docs-gulp-command.png diff --git a/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md b/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md new file mode 100644 index 00000000..989ea917 --- /dev/null +++ b/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md @@ -0,0 +1,31 @@ +# JavaScript oraz Gulpfiles + +Gulp umożliwia wykorzystanie istniejącej wiedzy o języku JavaScript do pisania plików gulpfiles lub wykorzystanie doświadczenia z plikami gulpfiles do pisania zwykłego kodu JavaScript. Chociaż dostępnych jest kilka narzędzi upraszczających pracę z systemem plików i wierszem poleceń, wszystko, co piszesz, to czysty JavaScript. + +## Gulpfile wytłumaczony + +Plik gulpfile to plik w katalogu projektu o nazwie `gulpfile.js` (lub pisany wielkimi literami jako `Gulpfile.js`, jak Makefile), który automatycznie ładuje się po uruchomieniu polecenia `gulp`. W tym pliku często zobaczysz interfejsy API gulp, takie jak `src ()`, `dest ()`, `series ()` lub `parallel ()`, ale można użyć dowolnego standardowego modułu JavaScript lub Node. Wszelkie wyeksportowane funkcje zostaną zarejestrowane w systemie zadań gulp. + +## Transpilacja + +Możesz napisać plik gulpfile przy użyciu języka wymagającego transpilacji, takiego jak TypeScript lub Babel, zmieniając rozszerzenie w swoim `gulpfile.js` aby wskazać język i zainstalować odpowiedni moduł transpilatora. + +* Dla TypeScript, zmień nazwę `gulpfile.ts` i zaintaluj moduł [ts-node][ts-node-module]. +* Dla Babel, zmień nazwę na `gulpfile.babel.js` i zainstaluj moduł [@babel/register][babel-register-module]. + +__Większość nowych wersji node obsługuje większość funkcji udostępnianych przez TypeScript lub Babel, z wyjątkiem składni `import`/`export`. Jeśli pożądana jest tylko ta składnia, zmień nazwę na `gulpfile.esm.js` i zainstaluj moduł [esm][esm-module].__ + +Aby uzyskać bardziej zaawansowane informacje na ten temat i pełną listę obsługiwanych rozszerzeń, zobacz naszą dokumentację [gulpfile transpilation][gulpfile-transpilation-advanced]. + +## Dzielenie pliku gulpfile + +Wielu użytkowników zaczyna od dodania całej logiki do pliku gulpfile. Jeśli kiedykolwiek stanie się zbyt duży, można go przekształcić w osobne pliki. + +Każde zadanie można podzielić na własny plik, a następnie zaimportować do pliku gulp w celu złożenia. Pozwala to nie tylko utrzymać porządek, ale umożliwia testowanie każdego zadania niezależnie lub różnicowanie składu w zależności od warunków. + +Moduł Node'a pozwala zastąpić twój plik `gulpfile.js` z katalogiem o nazwie `gulpfile.js` który zawiera plik `index.js` który jest traktowany jako `gulpfile.js`. Ten katalog może następnie zawierać poszczególne moduły zadań. Jeśli używasz transpilatora, odpowiednio nazwij folder i plik. + +[gulpfile-transpilation-advanced]: ../documentation-missing.md +[ts-node-module]: https://www.npmjs.com/package/ts-node +[babel-register-module]: https://www.npmjs.com/package/@babel/register +[esm-module]: https://www.npmjs.com/package/esm From 208d6df797b08d0f288ca62ee254ca22fdcd85e7 Mon Sep 17 00:00:00 2001 From: Marouane R Date: Tue, 28 Jul 2020 18:17:22 +0100 Subject: [PATCH 189/225] Docs: Add gulp-cli answer to FAQ (#2212) --- docs/FAQ.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/FAQ.md b/docs/FAQ.md index f8a649ea..80729961 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -30,6 +30,10 @@ Probably. Ask yourself: Always use `\n` to prevent diff issues between operating systems. +## I installed gulp as a dependency from package.json file by running `npm install` but I keep getting `command not found` whenever I try running a gulp command, why doesn't it work? + +Upon installing gulp as a project dependency, you need to add that to your PATH environment variable so that when you run a command, the system can find it. An easy solution is to install gulp globally, so that its binaries end up in your PATH environment variable. To install gulp globally, use the command `npm install gulp-cli -g` + ## Where can I get updates on gulp? gulp updates can be found on the following twitters: From 22ce5f58bb1637e800508cb1ed3e2d82320f63cf Mon Sep 17 00:00:00 2001 From: Takashi Fujita Date: Mon, 24 Aug 2020 06:41:52 +0900 Subject: [PATCH 190/225] Docs: Fix link to gulp source (#2482) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 15e8baa3..3eff64bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ of the content # Project structure -Gulp itself is tiny: index.js contains [very few lines of code](https://github.com/gulpjs/gulp/blob/4.0/index.js). +Gulp itself is tiny: index.js contains [very few lines of code](https://github.com/gulpjs/gulp/blob/master/index.js). It is powered by a few other libraries which each handle a few specific tasks each. From 93564bd7b71b953e442babff7cc22d7f91e3c392 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 24 Aug 2020 00:13:45 +0000 Subject: [PATCH 191/225] Docs: Add advanced section for creation of custom registries (#2479) Co-authored-by: Blaine Bublitz --- docs/advanced/creating-custom-registries.md | 199 ++++++++++++++++++++ docs/api/registry.md | 2 +- 2 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 docs/advanced/creating-custom-registries.md diff --git a/docs/advanced/creating-custom-registries.md b/docs/advanced/creating-custom-registries.md new file mode 100644 index 00000000..8125b6a1 --- /dev/null +++ b/docs/advanced/creating-custom-registries.md @@ -0,0 +1,199 @@ + + +# Creating Custom Registries + +Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. Registries are registered using [`registry()`](registry). + +## Structure + +In order to be accepted by gulp, custom registries must follow a specific format. + +```js +// as a function +function TestRegistry() {} + +TestRegistry.prototype.init = function (gulpInst) {} +TestRegistry.prototype.get = function (name) {} +TestRegistry.prototype.set = function (name, fn) {} +TestRegistry.prototype.tasks = function () {} + +// as a class +class TestRegistry { + init(gulpInst) {} + + get(name) {} + + set(name, fn) {} + + tasks() {} +} +``` + +If a registry instance passed to `registry()` doesn't have all four methods, an error will be thrown. + +## Registration + +If we want to register our example registry from above, we will need to pass an instance of it to `registry()`. + +```js +const { registry } = require('gulp'); + +// ... TestRegistry setup code + +// good! +registry(new TestRegistry()) + +// bad! +registry(TestRegistry()) +// This will trigger an error: 'Custom registries must be instantiated, but it looks like you passed a constructor' +``` + +## Methods + +### `init(gulpInst)` + +The `init()` method of a registry is called at the very end of the `registry()` function. The gulp instance passed as the only argument (`gulpInst`) can be used to pre-define tasks using +`gulpInst.task(taskName, fn)`. + +#### Parameters + +| parameter | type | note | +|:---------:|:----:|------| +| gulpInst | object | Instance of gulp. | + +### `get(name)` + +The `get()` method receives a task `name` for the custom registry to resolve and return, or `undefined` if no task with that name exists. + +#### Parameters + +| parameter | type | note | +|:---------:|:----:|------| +| name | string | Name of the task to be retrieved. | + +### `set(name, fn)` + +The `set()` method receives a task `name` and `fn`. This is called internally by `task()` to provide user-registered tasks to custom registries. + +#### Parameters + +| parameter | type | note | +|:---------:|:----:|------| +| name | string | Name of the task to be set. | +| fn | function | Task function to be set. | + +### `tasks()` + +Must return an object listing all tasks in the registry. + +## Use Cases + +### Sharing Tasks + +To share common tasks with all your projects, you can expose an `init` method on the registry and it will receive the an instance of gulp as the only argument. You can then use `gulpInst.task(name, fn)` to register pre-defined tasks. + +For example, you might want to share a `clean` task: + +```js +const fs = require('fs'); +const util = require('util'); + +const DefaultRegistry = require('undertaker-registry'); +const del = require('del'); + +function CommonRegistry(opts){ + DefaultRegistry.call(this); + + opts = opts || {}; + + this.buildDir = opts.buildDir || './build'; +} + +util.inherits(CommonRegistry, DefaultRegistry); + +CommonRegistry.prototype.init = function(gulpInst) { + const buildDir = this.buildDir; + const exists = fs.existsSync(buildDir); + + if(exists){ + throw new Error('Cannot initialize common tasks. ' + buildDir + ' directory exists.'); + } + + gulpInst.task('clean', function(){ + return del([buildDir]); + }); +} + +module.exports = CommonRegistry; +``` + +Then to use it in a project: + +```js +const { registry, series, task } = require('gulp'); +const CommonRegistry = require('myorg-common-tasks'); + +registry(new CommonRegistry({ buildDir: '/dist' })); + +task('build', series('clean', function build(cb) { + // do things + cb(); +})); +``` + +### Sharing Functionality + +By controlling how tasks are added to the registry, you can decorate them. + +For example, if you wanted all tasks to share some data, you can use a custom registry to bind them to that data. Be sure to return the altered task, as per the description of registry methods above: + +```js +const { registry, series, task } = require('gulp'); +const util = require('util'); +const DefaultRegistry = require('undertaker-registry'); + +// Some task defined somewhere else +const BuildRegistry = require('./build.js'); +const ServeRegistry = require('./serve.js'); + +function ConfigRegistry(config){ + DefaultRegistry.call(this); + this.config = config; +} + +util.inherits(ConfigRegistry, DefaultRegistry); + +ConfigRegistry.prototype.set = function set(name, fn) { + // The `DefaultRegistry` uses `this._tasks` for storage. + var task = this._tasks[name] = fn.bind(this.config); + return task; +}; + +registry(new BuildRegistry()); +registry(new ServeRegistry()); + +// `registry` will reset each task in the registry with +// `ConfigRegistry.prototype.set` which will bind them to the config object. +registry(new ConfigRegistry({ + src: './src', + build: './build', + bindTo: '0.0.0.0:8888' +})); + +task('default', series('clean', 'build', 'serve', function(cb) { + console.log('Server bind to ' + this.bindTo); + console.log('Serving' + this.build); + cb(); +})); +``` + +## Examples + +* [`undertaker-registry`](https://github.com/gulpjs/undertaker-registry): The Gulp 4 default registry. +* [`undertaker-common-tasks`](https://github.com/gulpjs/undertaker-common-tasks): Proof-of-concept custom registry that pre-defines tasks. +* [` undertaker-task-metadata`](https://github.com/gulpjs/undertaker-task-metadata): Proof-of-concept custom registry that attaches metadata to each task. diff --git a/docs/api/registry.md b/docs/api/registry.md index 415f2cd9..c25198a3 100644 --- a/docs/api/registry.md +++ b/docs/api/registry.md @@ -60,4 +60,4 @@ When a registry without an `init` method is passed as `registryInstance`, throws When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `tasks` function". -[creating-custom-registries]: ../documentation-missing.md +[creating-custom-registries]: ../advanced/creating-custom-registries.md From b7b70b8a4c1ca4f0e78517f57a467b20552a992d Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 23 Aug 2020 17:20:08 -0700 Subject: [PATCH 192/225] Docs: Fix some links --- docs/advanced/creating-custom-registries.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/advanced/creating-custom-registries.md b/docs/advanced/creating-custom-registries.md index 8125b6a1..fdd2a94a 100644 --- a/docs/advanced/creating-custom-registries.md +++ b/docs/advanced/creating-custom-registries.md @@ -7,7 +7,7 @@ sidebar_label: Creating Custom Registries # Creating Custom Registries -Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. Registries are registered using [`registry()`](registry). +Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. Registries are registered using [`registry()`][registry-api-docs]. ## Structure @@ -194,6 +194,11 @@ task('default', series('clean', 'build', 'serve', function(cb) { ## Examples -* [`undertaker-registry`](https://github.com/gulpjs/undertaker-registry): The Gulp 4 default registry. -* [`undertaker-common-tasks`](https://github.com/gulpjs/undertaker-common-tasks): Proof-of-concept custom registry that pre-defines tasks. -* [` undertaker-task-metadata`](https://github.com/gulpjs/undertaker-task-metadata): Proof-of-concept custom registry that attaches metadata to each task. +* [undertaker-registry][undertaker-registry-example]: The Gulp 4 default registry. +* [undertaker-common-tasks][undertaker-common-tasks-example]: Proof-of-concept custom registry that pre-defines tasks. +* [undertaker-task-metadata][undertaker-task-metadata-example]: Proof-of-concept custom registry that attaches metadata to each task. + +[registry-api-docs]: ../api/registry.md +[undertaker-registry-example]: https://github.com/gulpjs/undertaker-registry +[undertaker-common-tasks-example]: https://github.com/gulpjs/undertaker-common-tasks +[undertaker-task-metadata-example]: https://github.com/gulpjs/undertaker-task-metadata From 486f92750027fa016b3558c9942ed0d37ee9ac93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 22:55:40 +0200 Subject: [PATCH 193/225] Docs: Remove recipes for selecting changed files gulp v4 supports this natively by combining `since` with `gulp.lastRun()`. https://gulpjs.com/docs/en/api/lastrun --- docs/recipes/README.md | 2 -- .../only-pass-through-changed-files.md | 28 ------------------- .../recipes/rebuild-only-files-that-change.md | 16 ----------- 3 files changed, 46 deletions(-) delete mode 100644 docs/recipes/only-pass-through-changed-files.md delete mode 100644 docs/recipes/rebuild-only-files-that-change.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 3e822432..e38f26e4 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -7,9 +7,7 @@ * [Incremental rebuilding, including operating on full file sets](incremental-builds-with-concatenate.md) * [Make stream from buffer (memory contents)](make-stream-from-buffer.md) * [Mocha test-runner with gulp](mocha-test-runner-with-gulp.md) -* [Only pass through changed files](only-pass-through-changed-files.md) * [Pass parameters from the command line](pass-arguments-from-cli.md) -* [Rebuild only files that change](rebuild-only-files-that-change.md) * [Generating a file per folder](running-task-steps-per-folder.md) * [Running tasks in series](running-tasks-in-series.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) diff --git a/docs/recipes/only-pass-through-changed-files.md b/docs/recipes/only-pass-through-changed-files.md deleted file mode 100644 index f2db5972..00000000 --- a/docs/recipes/only-pass-through-changed-files.md +++ /dev/null @@ -1,28 +0,0 @@ -# Only pass through changed files - -Files are passed through the whole pipe chain on every run by default. By using [gulp-changed](https://github.com/sindresorhus/gulp-changed) only changed files will be passed through. This can speed up consecutive runs considerably. - - -```js -// npm install --save-dev gulp gulp-changed gulp-jscs gulp-uglify - -var gulp = require('gulp'); -var changed = require('gulp-changed'); -var jscs = require('gulp-jscs'); -var uglify = require('gulp-uglify'); - -// we define some constants here so they can be reused -var SRC = 'src/*.js'; -var DEST = 'dist'; - -gulp.task('default', function() { - return gulp.src(SRC) - // the `changed` task needs to know the destination directory - // upfront to be able to figure out which files changed - .pipe(changed(DEST)) - // only files that has changed will pass through here - .pipe(jscs()) - .pipe(uglify()) - .pipe(gulp.dest(DEST)); -}); -``` diff --git a/docs/recipes/rebuild-only-files-that-change.md b/docs/recipes/rebuild-only-files-that-change.md deleted file mode 100644 index 245ddc4f..00000000 --- a/docs/recipes/rebuild-only-files-that-change.md +++ /dev/null @@ -1,16 +0,0 @@ -# Rebuild only files that change - -With [`gulp-watch`](https://github.com/floatdrop/gulp-watch): - -```js -var gulp = require('gulp'); -var sass = require('gulp-sass'); -var watch = require('gulp-watch'); - -gulp.task('default', function() { - return gulp.src('sass/*.scss') - .pipe(watch('sass/*.scss')) - .pipe(sass()) - .pipe(gulp.dest('dist')); -}); -``` From c4305df006d8c9acc915a8ccc82495cd17ca2f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:09:03 +0200 Subject: [PATCH 194/225] Docs: Remove recipe for running tasks in series gulp v4 supports this natively, as explained in the recipe itself, so there is no need for it. --- docs/recipes/README.md | 1 - docs/recipes/running-tasks-in-series.md | 89 ------------------------- 2 files changed, 90 deletions(-) delete mode 100644 docs/recipes/running-tasks-in-series.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index e38f26e4..10ca6a12 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -9,7 +9,6 @@ * [Mocha test-runner with gulp](mocha-test-runner-with-gulp.md) * [Pass parameters from the command line](pass-arguments-from-cli.md) * [Generating a file per folder](running-task-steps-per-folder.md) -* [Running tasks in series](running-tasks-in-series.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) * [Specifying a new cwd (current working directory)](specifying-a-cwd.md) diff --git a/docs/recipes/running-tasks-in-series.md b/docs/recipes/running-tasks-in-series.md deleted file mode 100644 index b28e692a..00000000 --- a/docs/recipes/running-tasks-in-series.md +++ /dev/null @@ -1,89 +0,0 @@ -# Running tasks in series - -By default, gulp CLI run tasks with maximum concurrency - e.g. it launches -all the tasks at once and waits for nothing. If you want to create a series -where tasks run in a particular order, you should use `gulp.series`; - -```js -var gulp = require('gulp'); -var doAsyncStuff = require('./stuff'); - -gulp.task('one', function(done) { - doAsyncStuff(function(err){ - done(err); - }); -}); - -gulp.task('two', function(done) { - // do things - done(); -}); - -gulp.task('default', gulp.series('one', 'two')); -``` - -Another example, using a dependency pattern. It uses -[`async-once`](https://www.npmjs.com/package/async-once) to run the `clean` -task operations only once: -```js -var gulp = require('gulp'); -var del = require('del'); // rm -rf -var once = require('async-once'); - -gulp.task('clean', once(function(done) { - // run only once. - // for the next call to the clean task, once will call done with - // the same arguments as the first call. - del(['output'], done); -})); - -gulp.task('templates', gulp.series('clean', function() { - return gulp.src(['src/templates/*.hbs']) - // do some concatenation, minification, etc. - .pipe(gulp.dest('output/templates/')); -})); - -gulp.task('styles', gulp.series('clean', function() { - return gulp.src(['src/styles/app.less']) - // do some hinting, minification, etc. - .pipe(gulp.dest('output/css/app.css')); -})); - -// templates and styles will be processed in parallel. -// `clean` will be guaranteed to complete before either start. -// `clean` operations will not be run twice, -// even though it is called as a dependency twice. -gulp.task('build', gulp.parallel('templates', 'styles')); - -// an alias. -gulp.task('default', gulp.parallel('build')); -``` - -Note that it's an anti-pattern in Gulp 4 and the logs will show the clean task -running twice. Instead, `templates` and `style` should use dedicated `clean:*` -tasks: -```js -var gulp = require('gulp'); -var del = require('del'); - -gulp.task('clean:templates', function() { - return del(['output/templates/']); -}); - -gulp.task('templates', gulp.series('clean:templates', function() { - return gulp.src(['src/templates/*.hbs']) - .pipe(gulp.dest('output/templates/')); -}); - -gulp.task('clean:styles', function() { - return del(['output/css/']); -}); - -gulp.task('styles', gulp.series('clean:styles', function() { - return gulp.src(['src/styles/app.less']) - .pipe(gulp.dest('output/css/app.css')); -})); - -gulp.task('build', gulp.parallel('templates', 'styles')); -gulp.task('default', gulp.parallel('build')); -``` From e1190ea05e2eb36080bc513512190c895e0cc4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:13:00 +0200 Subject: [PATCH 195/225] Docs: Remove recipe for exporting tasks This is a core feature, it's not necessary to explain it in a recipe. --- docs/recipes/README.md | 1 - docs/recipes/exports-as-tasks.md | 22 ---------------------- 2 files changed, 23 deletions(-) delete mode 100644 docs/recipes/exports-as-tasks.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 10ca6a12..55dc0f38 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -21,7 +21,6 @@ * [Output both a minified and non-minified version](minified-and-non-minified.md) * [Templating with Swig and YAML front-matter](templating-with-swig-and-yaml-front-matter.md) * [Run Grunt Tasks from Gulp](run-grunt-tasks-from-gulp.md) -* [Exports as tasks](exports-as-tasks.md) * [Rollup with rollup-stream](rollup-with-rollup-stream.md) * [Run gulp task via cron job](cron-task.md) * [Running shell commands](running-shell-commands.md) diff --git a/docs/recipes/exports-as-tasks.md b/docs/recipes/exports-as-tasks.md deleted file mode 100644 index 2eaea490..00000000 --- a/docs/recipes/exports-as-tasks.md +++ /dev/null @@ -1,22 +0,0 @@ -# Exports as Tasks - -Using the ES2015 module syntax you can use your exports as tasks. - -```js -import gulp from 'gulp'; -import babel from 'gulp-babel'; - -// named task -export function build() { - return gulp.src('src/*.js') - .pipe(babel()) - .pipe(gulp.dest('lib')); -} - -// default task -export default function dev() { - gulp.watch('src/*.js', ['build']); -} -``` - -This will **not** work with the gulp-cli version bundled with gulp 3.x. You must use the latest published version. From 1a653a92b7ee567b184109c30028d99f64290458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:17:12 +0200 Subject: [PATCH 196/225] Docs: Remove recipe for running shell commands gulp v4 supports this natively now, tasks can return a child process. https://gulpjs.com/docs/en/getting-started/async-completion#returning-a-child-process --- docs/recipes/README.md | 1 - docs/recipes/running-shell-commands.md | 31 -------------------------- 2 files changed, 32 deletions(-) delete mode 100644 docs/recipes/running-shell-commands.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 55dc0f38..a022bc45 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -23,4 +23,3 @@ * [Run Grunt Tasks from Gulp](run-grunt-tasks-from-gulp.md) * [Rollup with rollup-stream](rollup-with-rollup-stream.md) * [Run gulp task via cron job](cron-task.md) -* [Running shell commands](running-shell-commands.md) diff --git a/docs/recipes/running-shell-commands.md b/docs/recipes/running-shell-commands.md deleted file mode 100644 index 5d344747..00000000 --- a/docs/recipes/running-shell-commands.md +++ /dev/null @@ -1,31 +0,0 @@ -# Running Shell Commands - -Sometimes it is helpful to be able to call existing command line tools from gulp. - -There are 2 ways to handle this: node's [`child_process`](https://nodejs.org/api/child_process.html) -built-in module or [`gulp-exec`](https://github.com/robrich/gulp-exec) if you need to integrate the -command with an existing pipeline. - -```js -'use strict'; - -var cp = require('child_process'); -var gulp = require('gulp'); - -gulp.task('reset', function() { - // In gulp 4, you can return a child process to signal task completion - return cp.execFile('git checkout -- .'); -}); -``` - -```js -'use strict'; - -var gulp = require('gulp'); -var exec = require('gulp-exec'); - -gulp.task('reset', function() { - return gulp.src('./**/**') - .pipe(exec('git checkout -- <%= file.path %>')); -}); -``` From 147327c4d7b14ba9ee98182cee7d377dc2194d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:20:03 +0200 Subject: [PATCH 197/225] Docs: Remove recipe for specifying a CWD The `cwd` option is described in the docs for `gulp.src`, and `--cwd` can be found when running `gulp --help`. Having this as a recipe seems unnecessary. --- docs/recipes/README.md | 1 - docs/recipes/specifying-a-cwd.md | 23 ----------------------- 2 files changed, 24 deletions(-) delete mode 100644 docs/recipes/specifying-a-cwd.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index a022bc45..9234b603 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -11,7 +11,6 @@ * [Generating a file per folder](running-task-steps-per-folder.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) -* [Specifying a new cwd (current working directory)](specifying-a-cwd.md) * [Split tasks across multiple files](split-tasks-across-multiple-files.md) * [Using external config file](using-external-config-file.md) * [Using multiple sources in one task](using-multiple-sources-in-one-task.md) diff --git a/docs/recipes/specifying-a-cwd.md b/docs/recipes/specifying-a-cwd.md deleted file mode 100644 index eba0ceca..00000000 --- a/docs/recipes/specifying-a-cwd.md +++ /dev/null @@ -1,23 +0,0 @@ -# Specifying a new cwd (current working directory) - -This is helpful for projects using a nested directory structure, such as: - -``` -/project - /layer1 - /layer2 -``` - -You can use the gulp CLI option `--cwd`. - -From the `project/` directory: - -```sh -gulp --cwd layer1 -``` - -If you only need to specify a cwd for a certain glob, you can use the `cwd` option on a [glob-stream](https://github.com/gulpjs/glob-stream): - -```js -gulp.src('./some/dir/**/*.js', { cwd: 'public' }); -``` From c5ff7e06263d23ee19700a3af0478103590060eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:22:22 +0200 Subject: [PATCH 198/225] Docs: Remove recipe for splitting tasks in files It should be very obvious that you can `require` functions from other files in `gulpfile.js` and export them as tasks, it seems unnecessary to use `gulp-hub`. --- docs/recipes/README.md | 1 - .../split-tasks-across-multiple-files.md | 38 ------------------- 2 files changed, 39 deletions(-) delete mode 100644 docs/recipes/split-tasks-across-multiple-files.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 9234b603..46cadd4b 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -11,7 +11,6 @@ * [Generating a file per folder](running-task-steps-per-folder.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) -* [Split tasks across multiple files](split-tasks-across-multiple-files.md) * [Using external config file](using-external-config-file.md) * [Using multiple sources in one task](using-multiple-sources-in-one-task.md) * [Browserify + Uglify with sourcemaps](browserify-uglify-sourcemap.md) diff --git a/docs/recipes/split-tasks-across-multiple-files.md b/docs/recipes/split-tasks-across-multiple-files.md deleted file mode 100644 index a93217a9..00000000 --- a/docs/recipes/split-tasks-across-multiple-files.md +++ /dev/null @@ -1,38 +0,0 @@ -# Split tasks across multiple files - -If your `gulpfile.js` is starting to grow too large, you can split the tasks -into separate files by using the [gulp-hub](https://github.com/frankwallis/gulp-hub/tree/4.0) -module as a [custom registry](https://github.com/phated/undertaker#registryregistryinstance). - -Imagine the following file structure: - -``` -gulpfile.js -tasks/ -├── dev.js -├── release.js -└── test.js -``` - -Install the `gulp-hub` module: - -```sh -npm install --save-dev gulp gulp-hub -``` - -Add the following lines to your `gulpfile.js` file: - -```js -'use strict'; - -var gulp = require('gulp'); -var HubRegistry = require('gulp-hub'); - -/* load some files into the registry */ -var hub = new HubRegistry(['tasks/*.js']); - -/* tell gulp to use the tasks just loaded */ -gulp.registry(hub); -``` - -This recipe can also be found at https://github.com/frankwallis/gulp-hub/tree/4.0/examples/recipe From 131b70288475255812e2959d0ba116f3f551fcef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:24:40 +0200 Subject: [PATCH 199/225] Docs: Remove recipe for using a config file It seems too basic and obvious. --- docs/recipes/README.md | 1 - docs/recipes/using-external-config-file.md | 53 ---------------------- 2 files changed, 54 deletions(-) delete mode 100644 docs/recipes/using-external-config-file.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 46cadd4b..3433f444 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -11,7 +11,6 @@ * [Generating a file per folder](running-task-steps-per-folder.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) -* [Using external config file](using-external-config-file.md) * [Using multiple sources in one task](using-multiple-sources-in-one-task.md) * [Browserify + Uglify with sourcemaps](browserify-uglify-sourcemap.md) * [Browserify + Globs](browserify-with-globs.md) diff --git a/docs/recipes/using-external-config-file.md b/docs/recipes/using-external-config-file.md deleted file mode 100644 index 6c740761..00000000 --- a/docs/recipes/using-external-config-file.md +++ /dev/null @@ -1,53 +0,0 @@ -# Using external config file - -Beneficial because it's keeping tasks DRY and config.json can be used by another task runner, like `grunt`. - -- - -###### `config.json` - -```json -{ - "desktop" : { - "src" : [ - "dev/desktop/js/**/*.js", - "!dev/desktop/js/vendor/**" - ], - "dest" : "build/desktop/js" - }, - "mobile" : { - "src" : [ - "dev/mobile/js/**/*.js", - "!dev/mobile/js/vendor/**" - ], - "dest" : "build/mobile/js" - } -} -``` - -- - -###### `gulpfile.js` - -```js -// npm install --save-dev gulp gulp-uglify merge-stream -var gulp = require('gulp'); -var uglify = require('gulp-uglify'); -var merge = require('merge-stream'); - -var config = require('./config.json'); - -function doStuff(cfg) { - return gulp.src(cfg.src) - .pipe(uglify()) - .pipe(gulp.dest(cfg.dest)); -} - -gulp.task('dry', function() { - // return a stream to signal completion - return merge([ - doStuff(config.desktop), - doStuff(config.mobile) - ]) -}); -``` From 6e56ed8cb5a64cee038475c05f94ea47f7c092d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 21 Oct 2020 20:49:01 +0200 Subject: [PATCH 200/225] Docs: Update and refactor release workflow recipe (#2498) --- docs/recipes/automate-release-workflow.md | 167 ++++++++++++---------- 1 file changed, 94 insertions(+), 73 deletions(-) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-release-workflow.md index e12646c7..4e64bb53 100644 --- a/docs/recipes/automate-release-workflow.md +++ b/docs/recipes/automate-release-workflow.md @@ -1,79 +1,100 @@ -# Automate release workflow + + +# Automate Releases If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release. -Below you have a simple recipe that bumps the project version, commits the changes to git and creates a new tag. - -``` javascript - -var gulp = require('gulp'); -var conventionalChangelog = require('gulp-conventional-changelog'); -var conventionalGithubReleaser = require('conventional-github-releaser'); -var bump = require('gulp-bump'); -var log = require('gulplog'); -var git = require('gulp-git'); -var fs = require('fs'); - -gulp.task('changelog', function () { - return gulp.src('CHANGELOG.md', { - buffer: false - }) - .pipe(conventionalChangelog({ - preset: 'angular' // Or to any other commit message convention you use. - })) - .pipe(gulp.dest('./')); -}); - -gulp.task('github-release', function(done) { - conventionalGithubReleaser({ - type: "oauth", - token: 'abcdefghijklmnopqrstuvwxyz1234567890' // change this to your own GitHub token or use an environment variable - }, { - preset: 'angular' // Or to any other commit message convention you use. - }, done); -}); - -gulp.task('bump-version', function () { -// We hardcode the version change type to 'patch' but it may be a good idea to -// use minimist (https://www.npmjs.com/package/minimist) to determine with a -// command argument whether you are doing a 'major', 'minor' or a 'patch' change. - return gulp.src(['./bower.json', './package.json']) - .pipe(bump({type: "patch"}).on('error', log.error)) - .pipe(gulp.dest('./')); -}); - -gulp.task('commit-changes', function () { - return gulp.src('.') - .pipe(git.add()) - .pipe(git.commit('[Prerelease] Bumped version number')); -}); - -gulp.task('push-changes', function (done) { - git.push('origin', 'master', done); -}); - -gulp.task('create-new-tag', function (done) { - var version = getPackageJsonVersion(); - git.tag(version, 'Created Tag for version: ' + version, function (error) { - if (error) { - return done(error); - } - git.push('origin', 'master', {args: '--tags'}, done); +The recipe below bumps the project version, commits the changes to git and creates a new GitHub release. + +For publishing a GitHub release you'll need to [create a personal access token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) and add it to your project. However, we don't want to commit it, so we'll use [`dotenv`](https://www.npmjs.com/package/dotenv) to load it from a git-ignored `.env` file: + +``` +GH_TOKEN=ff34885... +``` + +Don't forget to add `.env` to your `.gitignore`. + +Next, install all the necessary dependencies for this recipe: + +```sh +npm install --save-dev conventional-recommended-bump conventional-changelog-cli conventional-github-releaser dotenv execa +``` + +Based on your environment, setup and preferences, your release workflow might look something like this: + +``` js +const gulp = require('gulp'); +const conventionalRecommendedBump = require('conventional-recommended-bump'); +const conventionalGithubReleaser = require('conventional-github-releaser'); +const execa = require('execa'); +const fs = require('fs'); +const { promisify } = require('util'); +const dotenv = require('dotenv'); + +// load environment variables +const result = dotenv.config(); + +if (result.error) { + throw result.error; +} + +// Conventional Changelog preset +const preset = 'angular'; +// print output of commands into the terminal +const stdio = 'inherit'; + +async function bumpVersion() { + // get recommended version bump based on commits + const { releaseType } = await promisify(conventionalRecommendedBump)({ preset }); + // bump version without committing and tagging + await execa('npm', ['version', releaseType, '--no-git-tag-version'], { + stdio, }); +} + +async function changelog() { + await execa( + 'npx', + [ + 'conventional-changelog', + '--preset', + preset, + '--infile', + 'CHANGELOG.md', + '--same-file', + ], + { stdio } + ); +} + +async function commitTagPush() { + // even though we could get away with "require" in this case, we're taking the safe route + // because "require" caches the value, so if we happen to use "require" again somewhere else + // we wouldn't get the current value, but the value of the last time we called "require" + const { version } = JSON.parse(await promisify(fs.readFile)('package.json')); + const commitMsg = `chore: release ${version}`; + await execa('git', ['add', '.'], { stdio }); + await execa('git', ['commit', '--message', commitMsg], { stdio }); + await execa('git', ['tag', `v${version}`], { stdio }); + await execa('git', ['push', '--follow-tags'], { stdio }); +} - function getPackageJsonVersion () { - // We parse the json file instead of using require because require caches - // multiple calls so the version number won't be updated - return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version; - }; -}); - -gulp.task('release', gulp.series( - 'bump-version', - 'changelog', - 'commit-changes', - 'push-changes', - 'create-new-tag', - 'github-release' -)); +function githubRelease(done) { + conventionalGithubReleaser( + { type: 'oauth', token: process.env.GH_TOKEN }, + { preset }, + done + ); +} +exports.release = gulp.series( + bumpVersion, + changelog, + commitTagPush, + githubRelease +); ``` From 4c1beadcba7381ae3b938947bd06c8785ca11fb9 Mon Sep 17 00:00:00 2001 From: entrywayaudibly <71117336+entrywayaudibly@users.noreply.github.com> Date: Wed, 21 Oct 2020 18:51:22 +0000 Subject: [PATCH 201/225] Docs: Add subtitles for registry error messages (#2502) --- docs/api/registry.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/docs/api/registry.md b/docs/api/registry.md index c25198a3..008c959f 100644 --- a/docs/api/registry.md +++ b/docs/api/registry.md @@ -7,7 +7,6 @@ sidebar_label: registry() # registry() - Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. **Note:** Only tasks registered with `task()` will be provided to the custom registry. The task functions passed directly to `series()` or `parallel()` will not be provided - if you need to customize the registry behavior, compose tasks with string references. @@ -50,14 +49,34 @@ If a `registryInstance` is passed, nothing will be returned. If no arguments are ### Errors -When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message, "Custom registries must be instantiated, but it looks like you passed a constructor". +#### Incorrect Parameter + +When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message: + +> Custom registries must be instantiated, but it looks like you passed a constructor. + +#### Missing get Method + +When a registry without a `get` method is passed as `registryInstance`, throws an error with the message: + +> Custom registry must have `get` function. + +#### Missing set Method + +When a registry without a `set` method is passed as `registryInstance`, throws an error with the message: + +> Custom registry must have `set` function. + +#### Missing init Method + +When a registry without an `init` method is passed as `registryInstance`, throws an error with the message: -When a registry without a `get` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `get` function". +> Custom registry must have `init` function" -When a registry without a `set` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `set` function". +#### Missing tasks Method -When a registry without an `init` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `init` function" +When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message: -When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `tasks` function". +> Custom registry must have `tasks` function. [creating-custom-registries]: ../advanced/creating-custom-registries.md From d51c6eb8ff51bc7d251f30e1b15288b72492c384 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 21 Oct 2020 12:02:40 -0700 Subject: [PATCH 202/225] Docs: Rename the automate releases recipe file --- .../{automate-release-workflow.md => automate-releases.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/recipes/{automate-release-workflow.md => automate-releases.md} (100%) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-releases.md similarity index 100% rename from docs/recipes/automate-release-workflow.md rename to docs/recipes/automate-releases.md From c26ebcb1c9842251c8dd716461d735e26feb862a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 21 Oct 2020 12:25:54 -0700 Subject: [PATCH 203/225] Docs: Cleanup registry error message subtitles --- docs/api/registry.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/api/registry.md b/docs/api/registry.md index 008c959f..d1b2123d 100644 --- a/docs/api/registry.md +++ b/docs/api/registry.md @@ -49,31 +49,31 @@ If a `registryInstance` is passed, nothing will be returned. If no arguments are ### Errors -#### Incorrect Parameter +#### Incorrect parameter When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message: > Custom registries must be instantiated, but it looks like you passed a constructor. -#### Missing get Method +#### Missing `get` method When a registry without a `get` method is passed as `registryInstance`, throws an error with the message: > Custom registry must have `get` function. -#### Missing set Method +#### Missing `set` method When a registry without a `set` method is passed as `registryInstance`, throws an error with the message: > Custom registry must have `set` function. -#### Missing init Method +#### Missing `init` method When a registry without an `init` method is passed as `registryInstance`, throws an error with the message: > Custom registry must have `init` function" -#### Missing tasks Method +#### Missing `tasks` method When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message: From b6d6d7c8c37f4be846cf796d3929fe25c5329808 Mon Sep 17 00:00:00 2001 From: azu Date: Mon, 11 Jan 2021 07:49:51 +0900 Subject: [PATCH 204/225] Docs: fix recipe link (#2526) --- docs/recipes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 3433f444..6748fa54 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -1,6 +1,6 @@ # Recipes -* [Automate release workflow](automate-release-workflow.md) +* [Automate release workflow](automate-releases.md) * [Combining streams to handle errors](combining-streams-to-handle-errors.md) * [Delete files and folders](delete-files-folder.md) * [Fast browserify builds with watchify](fast-browserify-builds-with-watchify.md) From df252509b52acd712300b3b5d00bf7aedf0dbd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anderson=20Samir=20Corr=C3=AAa=20Paz=20de=20Camargo?= Date: Sun, 10 Jan 2021 20:13:16 -0300 Subject: [PATCH 205/225] Docs: Fix typo in task docs (#2524) --- docs/api/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/task.md b/docs/api/task.md index 21aaec40..de3c5462 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -61,7 +61,7 @@ Since any registered task can be run from the command line, avoid using spaces i | parameter | type | note | |:--------------:|:------:|-------| -| taskName | string | An alias for the task function within the the task system. Not needed when using named functions for `taskFunction`. | +| taskName | string | An alias for the task function within the task system. Not needed when using named functions for `taskFunction`. | | taskFunction
**(required)** | function | A [task function][task-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | ### Returns From f91c388beb265e5008202f11100309549162247a Mon Sep 17 00:00:00 2001 From: roydukkey Date: Mon, 8 Feb 2021 15:22:24 -0500 Subject: [PATCH 206/225] Docs: Remove typo in custom registry docs (#2543) --- docs/advanced/creating-custom-registries.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/advanced/creating-custom-registries.md b/docs/advanced/creating-custom-registries.md index fdd2a94a..a5423b5f 100644 --- a/docs/advanced/creating-custom-registries.md +++ b/docs/advanced/creating-custom-registries.md @@ -95,7 +95,7 @@ Must return an object listing all tasks in the registry. ### Sharing Tasks -To share common tasks with all your projects, you can expose an `init` method on the registry and it will receive the an instance of gulp as the only argument. You can then use `gulpInst.task(name, fn)` to register pre-defined tasks. +To share common tasks with all your projects, you can expose an `init` method on the registry and it will receive an instance of gulp as the only argument. You can then use `gulpInst.task(name, fn)` to register pre-defined tasks. For example, you might want to share a `clean` task: From 9877de07cf923c889d7f0661d87f3d6f8634eeb1 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Martin Date: Fri, 9 Apr 2021 23:07:03 +0200 Subject: [PATCH 207/225] Docs: Guide CustomRegistries to maintain properties on tasks (fixes #2561) (#2565) --- docs/advanced/creating-custom-registries.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/advanced/creating-custom-registries.md b/docs/advanced/creating-custom-registries.md index a5423b5f..6fcdbeb6 100644 --- a/docs/advanced/creating-custom-registries.md +++ b/docs/advanced/creating-custom-registries.md @@ -169,8 +169,11 @@ function ConfigRegistry(config){ util.inherits(ConfigRegistry, DefaultRegistry); ConfigRegistry.prototype.set = function set(name, fn) { + var bound = fn.bind(this.config); + // Preserve internal properties and task metadata. + var task = Object.assign(bound, fn); // The `DefaultRegistry` uses `this._tasks` for storage. - var task = this._tasks[name] = fn.bind(this.config); + this._tasks[name] = task; return task; }; From 598f971a6567401e5760f4fd0b84df0180c2e350 Mon Sep 17 00:00:00 2001 From: Seno <4535187+s-en-o@users.noreply.github.com> Date: Tue, 4 May 2021 07:37:34 +1200 Subject: [PATCH 208/225] Docs: Fix broken link in recipe (#2571) --- docs/recipes/minimal-browsersync-setup-with-gulp4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/minimal-browsersync-setup-with-gulp4.md b/docs/recipes/minimal-browsersync-setup-with-gulp4.md index ec22c071..82acb674 100644 --- a/docs/recipes/minimal-browsersync-setup-with-gulp4.md +++ b/docs/recipes/minimal-browsersync-setup-with-gulp4.md @@ -35,7 +35,7 @@ The gulpfile could be broken in 3 parts. ### 1. Write the task to prepare the dist package as usual -Refer to the main [README](https://github.com/gulpjs/gulp/blob/4.0/README.md#use-last-javascript-version-in-your-gulpfile) +Refer to the main [README](https://github.com/gulpjs/gulp/blob/master/docs/README.md) for more information. ```javascript From 818bd73e5da1ad69f43eef84214c98d6392a73e4 Mon Sep 17 00:00:00 2001 From: Artem Guskov <61526280+brendan8c@users.noreply.github.com> Date: Tue, 22 Jun 2021 21:18:17 +0300 Subject: [PATCH 209/225] Docs: Remove gulp-sourcemaps because it is built-in (#2592) --- docs/recipes/browserify-transforms.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/recipes/browserify-transforms.md b/docs/recipes/browserify-transforms.md index 47a0d4d5..58c74bc3 100644 --- a/docs/recipes/browserify-transforms.md +++ b/docs/recipes/browserify-transforms.md @@ -15,7 +15,6 @@ var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var log = require('gulplog'); var uglify = require('gulp-uglify'); -var sourcemaps = require('gulp-sourcemaps'); var reactify = require('reactify'); gulp.task('javascript', function () { @@ -28,13 +27,11 @@ gulp.task('javascript', function () { }); return b.bundle() - .pipe(source('app.js')) + .pipe(source('app.js', { sourcemaps: true })) .pipe(buffer()) - .pipe(sourcemaps.init({loadMaps: true})) // Add transformation tasks to the pipeline here. .pipe(uglify()) .on('error', log.error) - .pipe(sourcemaps.write('./')) - .pipe(gulp.dest('./dist/js/')); + .pipe(gulp.dest('./dist/js/', { sourcemaps: '../sourcemaps/' })); }); ``` From 85896d4f099a80d58dd08d1f6d80586b07678995 Mon Sep 17 00:00:00 2001 From: Viishesh Jain <60565221+Viisheshjain05@users.noreply.github.com> Date: Mon, 19 Dec 2022 23:32:08 +0530 Subject: [PATCH 210/225] chore(docs): Update stream handbook link (#2711) --- docs/writing-a-plugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/writing-a-plugin/README.md b/docs/writing-a-plugin/README.md index bcd70835..bf2b54b6 100644 --- a/docs/writing-a-plugin/README.md +++ b/docs/writing-a-plugin/README.md @@ -193,7 +193,7 @@ if (someCondition) { If you're unfamiliar with streams, you will need to read up on them: -* https://github.com/substack/stream-handbook (a MUST read) +* https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/ * https://nodejs.org/api/stream.html Other libraries that are not file manipulating through streams but are made for use with gulp are tagged with the [gulpfriendly](https://npmjs.org/browse/keyword/gulpfriendly) keyword on npm. From 72668c61e445c81fad23bc6ed24967a3238a648d Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 24 Mar 2024 17:43:12 -0700 Subject: [PATCH 211/225] chore!: Normalize repository, dropping node <10.13 support (#2758) feat: Support `.cjs` extension for gulpfiles fix: Ensure watch does not trigger on negated globs fix: Ensure watch allows japanese characters in globs --- .ci/.azure-pipelines-steps.yml | 38 ---------- .ci/.azure-pipelines.yml | 90 ------------------------ .github/workflows/dev.yml | 75 ++++++++++++++++++++ .github/workflows/release.yml | 16 +++++ .npmrc | 1 + .prettierignore | 3 + .travis.yml | 12 ---- LICENSE | 2 +- README.md | 75 ++++---------------- appveyor.yml | 26 ------- package.json | 39 +++++----- test/.eslintrc | 3 - test/.gitkeep | 0 test/dest.js | 48 +++++++------ test/fixtures/gulpfiles/cjs/gulpfile.cjs | 3 + test/index.test.js | 36 +++++++--- test/src.js | 52 +++++++------- test/watch.js | 79 +++++++++++++++++---- 18 files changed, 279 insertions(+), 319 deletions(-) delete mode 100644 .ci/.azure-pipelines-steps.yml delete mode 100644 .ci/.azure-pipelines.yml create mode 100644 .github/workflows/dev.yml create mode 100644 .github/workflows/release.yml create mode 100644 .npmrc create mode 100644 .prettierignore delete mode 100644 .travis.yml delete mode 100644 appveyor.yml delete mode 100644 test/.eslintrc create mode 100644 test/.gitkeep create mode 100644 test/fixtures/gulpfiles/cjs/gulpfile.cjs diff --git a/.ci/.azure-pipelines-steps.yml b/.ci/.azure-pipelines-steps.yml deleted file mode 100644 index 894c21ee..00000000 --- a/.ci/.azure-pipelines-steps.yml +++ /dev/null @@ -1,38 +0,0 @@ -steps: -- script: npm i -g npm@$(npm_version) - displayName: Use legacy npm version $(npm_version) - condition: ne(variables['npm_version'], '') - -- task: NodeTool@0 - inputs: - versionSpec: '$(node_version)' - displayName: Use Node $(node_version) - -- script: npm install - displayName: npm install - -- script: npm test - displayName: Run tests - -- script: npm run coveralls - displayName: Run coveralls - env: - # Pretend to be AppVeyor for now - APPVEYOR: true - APPVEYOR_BUILD_NUMBER: $(Build.BuildNumber) - APPVEYOR_BUILD_ID: $(Agent.OS)_$(node_version) - APPVEYOR_REPO_COMMIT: $(Build.SourceVersion) - APPVEYOR_REPO_BRANCH: $(Build.SourceBranchName) - # Overwrite the AppVeyor Service Name - COVERALLS_SERVICE_NAME: Azure Pipelines - COVERALLS_REPO_TOKEN: $(COVERALLS_REPO_TOKEN_SECRET) - COVERALLS_PARALLEL: true - CI_PULL_REQUEST: $(System.PullRequest.PullRequestNumber) - -- script: npm run azure-pipelines - displayName: Write tests to xml - -- task: PublishTestResults@2 - inputs: - testResultsFiles: '**/test.xunit' - condition: succeededOrFailed() diff --git a/.ci/.azure-pipelines.yml b/.ci/.azure-pipelines.yml deleted file mode 100644 index 2d717af1..00000000 --- a/.ci/.azure-pipelines.yml +++ /dev/null @@ -1,90 +0,0 @@ -trigger: -- master -- releases/* - -jobs: - - job: Test_Linux - displayName: Run Tests on Linux - pool: - vmImage: "Ubuntu 16.04" - strategy: - matrix: - Node_v12: - node_version: 12 - Node_v10: - node_version: 10 - Node_v8: - node_version: 8 - Node_v6: - node_version: 6 - Node_v4: - node_version: 4 - Node_v0_12: - node_version: 0.12 - Node_v0_10: - node_version: 0.10 - steps: - - template: .azure-pipelines-steps.yml - - - job: Test_Windows - displayName: Run Tests on Windows - pool: - vmImage: vs2017-win2016 - strategy: - matrix: - Node_v12: - node_version: 12 - Node_v10: - node_version: 10 - Node_v8: - node_version: 8 - Node_v6: - node_version: 6 - Node_v4: - node_version: 4 - npm_version: 2 - Node_v0_12: - node_version: 0.12 - npm_version: 2 - Node_v0_10: - node_version: 0.10 - npm_version: 2 - steps: - - template: .azure-pipelines-steps.yml - - - job: Test_MacOS - displayName: Run Tests on MacOS - pool: - vmImage: macos-10.13 - strategy: - matrix: - Node_v12: - node_version: 12 - Node_v10: - node_version: 10 - Node_v8: - node_version: 8 - Node_v6: - node_version: 6 - Node_v4: - node_version: 4 - Node_v0_12: - node_version: 0.12 - Node_v0_10: - node_version: 0.10 - steps: - - template: .azure-pipelines-steps.yml - - - job: Notify_Coveralls - displayName: Notify Coveralls that the parallel report is done - pool: - vmImage: "Ubuntu 16.04" - dependsOn: - - Test_Linux - - Test_Windows - - Test_MacOS - steps: - - script: curl -k https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN -d "payload[build_num]=$BUILD_NAME&payload[status]=done" - env: - COVERALLS_REPO_TOKEN: $(COVERALLS_REPO_TOKEN_SECRET) - BUILD_NAME: $(Build.BuildNumber) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml new file mode 100644 index 00000000..3b07263a --- /dev/null +++ b/.github/workflows/dev.yml @@ -0,0 +1,75 @@ +name: dev +on: + pull_request: + push: + branches: + - master + - main +env: + CI: true + +jobs: + prettier: + name: Format code + runs-on: ubuntu-latest + if: ${{ github.event_name == 'push' }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Prettier + uses: gulpjs/prettier_action@v3.0 + with: + commit_message: 'chore: Run prettier' + prettier_options: '--write .' + + test: + name: Tests for Node ${{ matrix.node }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + node: [10, 12, 14, 16] + os: [ubuntu-latest, windows-latest, macos-latest] + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set Node.js version + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + + - run: node --version + - run: npm --version + + - name: Install npm dependencies + run: npm install + + - name: Run lint + run: npm run lint + + - name: Run tests + run: npm test + + - name: Coveralls + uses: coverallsapp/github-action@v1.1.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: ${{matrix.os}}-node-${{ matrix.node }} + parallel: true + + coveralls: + needs: test + name: Finish up + + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@v1.1.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..87cd13c0 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,16 @@ +name: release +on: + push: + branches: + - master + - main + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: GoogleCloudPlatform/release-please-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + release-type: node + package-name: release-please-action diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..43c97e71 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..c96ebe0c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +coverage/ +.nyc_output/ +CHANGELOG.md diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index eda5b000..00000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -sudo: false -language: node_js -node_js: - - '12' - - '10' - - '8' - - '6' - - '4' - - '0.12' - - '0.10' -after_script: - - npm run coveralls diff --git a/LICENSE b/LICENSE index 6a29df97..7980c1d4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2018 Blaine Bublitz , Eric Schoffstall and other contributors +Copyright (c) 2013-2024 Blaine Bublitz and Eric Schoffstall Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 162f1bee..b8b66b50 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@

The streaming build system

-[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Azure Pipelines Build Status][azure-pipelines-image]][azure-pipelines-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![OpenCollective Backers][backer-badge]][backer-url] [![OpenCollective Sponsors][sponsor-badge]][sponsor-url] [![Gitter chat][gitter-image]][gitter-url] - +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Coveralls Status][coveralls-image]][coveralls-url] ## What is gulp? @@ -15,25 +14,6 @@ - **Strong Ecosystem** - Use npm modules to do anything you want + over 3000 curated plugins for streaming file transformations. - **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use. -## What's new in 4.0?! - -* The task system was rewritten from the ground-up, allowing task composition using `series()` and `parallel()` methods. -* The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system. -* First-class support was added for incremental builds using `lastRun()`. -* A `symlink()` method was exposed to create symlinks instead of copying files. -* Built-in support for sourcemaps was added - the gulp-sourcemaps plugin is no longer necessary! -* Task registration of exported functions - using node or ES exports - is now recommended. -* Custom registries were designed, allowing for shared tasks or augmented functionality. -* Stream implementations were improved, allowing for better conditional and phased builds. - - -## gulp for enterprise - -Available as part of the Tidelift Subscription - -The maintainers of gulp and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-gulp?utm_source=npm-gulp&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - - ## Installation Follow our [Quick Start guide][quick-start]. @@ -246,48 +226,21 @@ for a second time. Anyone can help make this project better - check out our [Contributing guide](/CONTRIBUTING.md)! -## Backers - -Support us with a monthly donation and help us continue our activities. - -[![Backers][backers-image]][support-url] - -## Sponsors - -Become a sponsor to get your logo on our README on Github. - -[![Sponsors][sponsors-image]][support-url] + +[quick-start]: https://gulpjs.com/docs/en/getting-started/quick-start +[getting-started-guide]: https://gulpjs.com/docs/en/getting-started/quick-start +[api-docs]: https://gulpjs.com/docs/en/api/concepts +[esm-module]: https://github.com/standard-things/esm + -[downloads-image]: https://img.shields.io/npm/dm/gulp.svg + +[downloads-image]: https://img.shields.io/npm/dm/gulp.svg?style=flat-square [npm-url]: https://www.npmjs.com/package/gulp -[npm-image]: https://img.shields.io/npm/v/gulp.svg - -[azure-pipelines-url]: https://dev.azure.com/gulpjs/gulp/_build/latest?definitionId=1&branchName=master -[azure-pipelines-image]: https://dev.azure.com/gulpjs/gulp/_apis/build/status/gulp?branchName=master +[npm-image]: https://img.shields.io/npm/v/gulp.svg?style=flat-square -[travis-url]: https://travis-ci.org/gulpjs/gulp -[travis-image]: https://img.shields.io/travis/gulpjs/gulp.svg?label=travis-ci - -[appveyor-url]: https://ci.appveyor.com/project/gulpjs/gulp -[appveyor-image]: https://img.shields.io/appveyor/ci/gulpjs/gulp.svg?label=appveyor +[ci-url]: https://github.com/gulpjs/gulp/actions?query=workflow:dev +[ci-image]: https://img.shields.io/github/actions/workflow/status/gulpjs/gulp/dev.yml?branch=master&style=flat-square [coveralls-url]: https://coveralls.io/r/gulpjs/gulp -[coveralls-image]: https://img.shields.io/coveralls/gulpjs/gulp/master.svg - -[gitter-url]: https://gitter.im/gulpjs/gulp -[gitter-image]: https://badges.gitter.im/gulpjs/gulp.svg - -[backer-url]: #backers -[backer-badge]: https://opencollective.com/gulpjs/backers/badge.svg?color=blue -[sponsor-url]: #sponsors -[sponsor-badge]: https://opencollective.com/gulpjs/sponsors/badge.svg?color=blue - -[support-url]: https://opencollective.com/gulpjs#support - -[backers-image]: https://opencollective.com/gulpjs/backers.svg -[sponsors-image]: https://opencollective.com/gulpjs/sponsors.svg - -[quick-start]: https://gulpjs.com/docs/en/getting-started/quick-start -[getting-started-guide]: https://gulpjs.com/docs/en/getting-started/quick-start -[api-docs]: https://gulpjs.com/docs/en/api/concepts -[esm-module]: https://github.com/standard-things/esm +[coveralls-image]: https://img.shields.io/coveralls/gulpjs/gulp/master.svg?style=flat-square + diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index d8845d71..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,26 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml -# https://www.appveyor.com/docs/lang/nodejs-iojs - -environment: - matrix: - # node.js - - nodejs_version: "0.10" - - nodejs_version: "0.12" - - nodejs_version: "4" - - nodejs_version: "6" - - nodejs_version: "8" - - nodejs_version: "10" - -install: - - ps: Install-Product node $env:nodejs_version - - npm install - -test_script: - - node --version - - npm --version - - cmd: npm test - -build: off - -# build version format -version: "{build}" diff --git a/package.json b/package.json index 256684af..b335a134 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "repository": "gulpjs/gulp", "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=10.13.0" }, "main": "index.js", "files": [ @@ -25,25 +25,32 @@ "scripts": { "lint": "eslint .", "pretest": "npm run lint", - "test": "nyc mocha --async-only", - "azure-pipelines": "nyc mocha --async-only --reporter xunit -O output=test.xunit", - "coveralls": "nyc report --reporter=text-lcov | coveralls" + "test": "nyc mocha --async-only" }, "dependencies": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" + "glob-watcher": "^6.0.0", + "gulp-cli": "^3.0.0", + "undertaker": "^2.0.0", + "vinyl-fs": "^4.0.0" }, "devDependencies": { - "coveralls": "github:phated/node-coveralls#2.x", - "eslint": "^2.13.1", - "eslint-config-gulp": "^3.0.1", - "expect": "^1.20.2", - "mkdirp": "^0.5.1", - "mocha": "^3.0.0", - "nyc": "^10.3.2", - "rimraf": "^2.6.3" + "eslint": "^7.0.0", + "eslint-config-gulp": "^5.0.0", + "eslint-plugin-node": "^11.1.0", + "expect": "^27.0.0", + "mkdirp": "^3.0.1", + "mocha": "^8.0.0", + "nyc": "^15.0.0", + "rimraf": "^3.0.0" + }, + "nyc": { + "reporter": [ + "lcov", + "text-summary" + ] + }, + "prettier": { + "singleQuote": true }, "keywords": [ "build", diff --git a/test/.eslintrc b/test/.eslintrc deleted file mode 100644 index 06b940f7..00000000 --- a/test/.eslintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "gulp/test" -} diff --git a/test/.gitkeep b/test/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/test/dest.js b/test/dest.js index 3dbba460..16c58d21 100644 --- a/test/dest.js +++ b/test/dest.js @@ -16,8 +16,8 @@ describe('gulp.dest()', function() { it('should return a stream', function(done) { var stream = gulp.dest(path.join(__dirname, './fixtures/')); - expect(stream).toExist(); - expect(stream.on).toExist(); + expect(stream).toBeDefined(); + expect(stream.on).toBeDefined(); done(); }); @@ -26,20 +26,22 @@ describe('gulp.dest()', function() { var outstream = gulp.dest(outpath); instream.pipe(outstream); + var expectedContents = Buffer.from('this is a test'); + outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); - expect(file.contents).toEqual('this is a test'); + expect(file.contents).toEqual(expectedContents); }); outstream.on('end', function() { fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { - expect(err).toNotExist(); - expect(contents).toExist(); - expect(contents).toEqual('this is a test'); + expect(err).toBeNull(); + expect(contents).toBeDefined(); + expect(contents).toEqual(expectedContents); done(); }); }); @@ -53,15 +55,15 @@ describe('gulp.dest()', function() { outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toNotExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeNull(); expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); }); outstream.on('end', function() { fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { - expect(err).toExist(); - expect(contents).toNotExist(); + expect(err).toBeDefined(); + expect(contents).toBeUndefined(); done(); }); }); @@ -74,16 +76,16 @@ describe('gulp.dest()', function() { outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); }); outstream.on('end', function() { fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { - expect(err).toNotExist(); - expect(contents).toExist(); - expect(contents).toEqual('this is a test'); + expect(err).toBeNull(); + expect(contents).toBeDefined(); + expect(contents).toEqual(Buffer.from('this is a test')); done(); }); }); @@ -112,13 +114,13 @@ describe('gulp.dest()', function() { outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right - expect(file).toExist(); - expect(file.path).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); expect(file.path).toEqual(path.join(outpath, './stuff')); }); outstream.on('end', function() { fs.exists(path.join(outpath, 'stuff'), function(exists) { - expect(exists).toExist(); + expect(exists).toBeDefined(); done(); }); }); diff --git a/test/fixtures/gulpfiles/cjs/gulpfile.cjs b/test/fixtures/gulpfiles/cjs/gulpfile.cjs new file mode 100644 index 00000000..b7e1a2d3 --- /dev/null +++ b/test/fixtures/gulpfiles/cjs/gulpfile.cjs @@ -0,0 +1,3 @@ +exports.default = function (done) { + done() +} diff --git a/test/index.test.js b/test/index.test.js index 8921084d..0e8b65fb 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,5 +1,8 @@ 'use strict'; +var cp = require('child_process'); +var path = require('path'); + var expect = require('expect'); var gulp = require('../'); @@ -8,52 +11,65 @@ describe('gulp', function() { describe('hasOwnProperty', function() { it('src', function(done) { - expect(gulp.hasOwnProperty('src')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'src')).toEqual(true); done(); }); it('dest', function(done) { - expect(gulp.hasOwnProperty('dest')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'dest')).toEqual(true); done(); }); it('symlink', function(done) { - expect(gulp.hasOwnProperty('symlink')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'symlink')).toEqual(true); done(); }); it('watch', function(done) { - expect(gulp.hasOwnProperty('watch')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'watch')).toEqual(true); done(); }); it('task', function(done) { - expect(gulp.hasOwnProperty('task')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'task')).toEqual(true); done(); }); it('series', function(done) { - expect(gulp.hasOwnProperty('series')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'series')).toEqual(true); done(); }); it('parallel', function(done) { - expect(gulp.hasOwnProperty('parallel')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'parallel')).toEqual(true); done(); }); it('tree', function(done) { - expect(gulp.hasOwnProperty('tree')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'tree')).toEqual(true); done(); }); it('lastRun', function(done) { - expect(gulp.hasOwnProperty('lastRun')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'lastRun')).toEqual(true); done(); }); it('registry', function(done) { - expect(gulp.hasOwnProperty('registry')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'registry')).toEqual(true); + done(); + }); + }); + + it('can run against gulpfile.cjs', function (done) { + this.timeout(5000); + + var cli = path.join(__dirname, '../bin/gulp.js'); + var opts = { cwd: path.join(__dirname, 'fixtures/gulpfiles/cjs' ) }; + cp.exec('node ' + cli, opts, function (err, stdout, stderr) { + expect(err).toBeNull(); + expect(stdout).toMatch('gulpfile.cjs'); + expect(stderr).toEqual(''); done(); }); }); diff --git a/test/src.js b/test/src.js index 4ec1df96..82501e73 100644 --- a/test/src.js +++ b/test/src.js @@ -9,19 +9,20 @@ var gulp = require('../'); describe('gulp.src()', function() { it('should return a stream', function(done) { var stream = gulp.src('./fixtures/*.coffee', { cwd: __dirname }); - expect(stream).toExist(); - expect(stream.on).toExist(); + expect(stream).toBeDefined(); + expect(stream.on).toBeDefined(); done(); }); + it('should return a input stream from a flat glob', function(done) { var stream = gulp.src('./fixtures/*.coffee', { cwd: __dirname }); stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); - expect(file.contents).toEqual('this is a test'); + expect(file.contents).toEqual(Buffer.from('this is a test')); }); stream.on('end', function() { done(); @@ -38,8 +39,8 @@ describe('gulp.src()', function() { var files = []; stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); files.push(file); }); stream.on('end', function() { @@ -61,8 +62,8 @@ describe('gulp.src()', function() { var files = []; stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); files.push(file); }); stream.on('end', function() { @@ -76,22 +77,23 @@ describe('gulp.src()', function() { var stream = gulp.src('./fixtures/*.coffee', { read: false, cwd: __dirname }); stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toNotExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeNull(); expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); }); stream.on('end', function() { done(); }); }); + it('should return a input stream with contents as stream when buffer is false', function(done) { var stream = gulp.src('./fixtures/*.coffee', { buffer: false, cwd: __dirname }); stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); var buf = ''; file.contents.on('data', function(d) { buf += d; @@ -103,20 +105,22 @@ describe('gulp.src()', function() { expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); }); }); + it('should return a input stream from a deep glob', function(done) { var stream = gulp.src('./fixtures/**/*.jade', { cwd: __dirname }); stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(__dirname, './fixtures/test/run.jade')); - expect(file.contents).toEqual('test template'); + expect(file.contents).toEqual(Buffer.from('test template')); }); stream.on('end', function() { done(); }); }); + it('should return a input stream from a deeper glob', function(done) { var stream = gulp.src('./fixtures/**/*.dmc', { cwd: __dirname }); var a = 0; @@ -136,11 +140,11 @@ describe('gulp.src()', function() { stream.on('error', done); stream.on('data', function(file) { ++a; - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); - expect(file.contents).toEqual('this is a test'); + expect(file.contents).toEqual(Buffer.from('this is a test')); }); stream.on('end', function() { expect(a).toEqual(1); diff --git a/test/watch.js b/test/watch.js index 0ac076d2..eab1ec01 100644 --- a/test/watch.js +++ b/test/watch.js @@ -7,7 +7,7 @@ var path = require('path'); var expect = require('expect'); var rimraf = require('rimraf'); -var mkdirp = require('mkdirp'); +var mkdirp = require('mkdirp').mkdirp; var gulp = require('../'); @@ -25,10 +25,22 @@ function updateTempFile(path) { }, 125); } +function removeTempFile(path) { + setTimeout(function() { + fs.unlinkSync(path); + }, 125); +} + describe('gulp.watch()', function() { - beforeEach(rimraf.bind(null, outpath)); - beforeEach(mkdirp.bind(null, outpath)); - afterEach(rimraf.bind(null, outpath)); + beforeEach(function (done) { + rimraf(outpath, done); + }); + beforeEach(function () { + return mkdirp(outpath); + }); + afterEach(function (done) { + rimraf(outpath, done); + }); it('should call the function when file changes: no options', function(done) { var tempFile = path.join(outpath, 'watch-func.txt'); @@ -83,15 +95,18 @@ describe('gulp.watch()', function() { createTempFile(tempFile); - var watcher = gulp.watch('watch-func.txt', { cwd: outpath }, function() { - // TODO: proper fail here - expect('Watcher erroneously called'); - }); - setTimeout(function() { - watcher.close(); - done(); - }, 10); + // Chokidar seems to pick up the file we just created, so we wait briefly before setup + // I wonder if node hasn't fully flushed the file or something... + var watcher = gulp.watch('watch-func.txt', { cwd: outpath }, function() { + done(new Error('should not each here!')); + }); + + setTimeout(function () { + watcher.close(); + done(); + }, 1000); + }, 250); }); it('should call the function when file changes: w/ options', function(done) { @@ -108,6 +123,40 @@ describe('gulp.watch()', function() { updateTempFile(tempFile); }); + it('should call the function when file changes at a path with japanese characters', function(done) { + var japaneseDir = path.join(outpath, 'フォルダ'); + + fs.mkdirSync(japaneseDir); + + var tempFile = path.join(japaneseDir, 'foobar.txt'); + + createTempFile(tempFile); + + var watcher = gulp.watch('フォルダ/*', { cwd: outpath }, function(cb) { + watcher.close(); + cb(); + done(); + }); + + updateTempFile(tempFile); + }); + + it('should not call the function when ignored file changes', function(done) { + var tempFile = path.join(outpath, 'ignored.txt'); + + createTempFile(tempFile); + + var watcher = gulp.watch(['*', '!ignored.txt'], { cwd: outpath }, function() { + done(new Error('should not each here!')); + }); + + removeTempFile(tempFile); + setTimeout(function () { + watcher.close(); + done(); + }, 1000); + }); + it('should not drop options when no callback specified', function(done) { var tempFile = path.join(outpath, 'watch-func-nodrop-options.txt'); // By passing a cwd option, ensure options are not lost to gaze @@ -118,7 +167,7 @@ describe('gulp.watch()', function() { var watcher = gulp.watch(relFile, { cwd: cwd }) .on('change', function(filepath) { - expect(filepath).toExist(); + expect(filepath).toBeDefined(); expect(path.resolve(cwd, filepath)).toEqual(path.resolve(tempFile)); watcher.close(); done(); @@ -128,8 +177,8 @@ describe('gulp.watch()', function() { }); it('should work without options or callback', function(done) { - // TODO: check we return watcher? - gulp.watch('x'); + var watcher = gulp.watch('x'); + watcher.close(); done(); }); From b00de681f5ef6ade283d544f62f770f6b27a9e52 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 25 Mar 2024 07:47:55 -0700 Subject: [PATCH 212/225] feat: Provide an ESM export (#2760) --- README.md | 32 +++++++----------------- index.mjs | 16 ++++++++++++ package.json | 6 +++++ test/fixtures/gulpfiles/mjs/gulpfile.mjs | 30 ++++++++++++++++++++++ test/index.test.js | 18 +++++++++++++ 5 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 index.mjs create mode 100644 test/fixtures/gulpfiles/mjs/gulpfile.mjs diff --git a/README.md b/README.md index b8b66b50..96d62a67 100644 --- a/README.md +++ b/README.md @@ -112,26 +112,12 @@ exports.default = build; ## Use latest JavaScript version in your gulpfile -__Most new versions of node support most features that Babel provides, except the `import`/`export` syntax. When only that syntax is desired, rename to `gulpfile.esm.js`, install the [esm][esm-module] module, and skip the Babel portion below.__ +Gulp provides a wrapper that will be loaded in your ESM code, so you can name your gulpfile as `gulpfile.mjs` or with `"type": "module"` specified in your `package.json` file. -Node already supports a lot of __ES2015+__ features, but to avoid compatibility problems we suggest to install Babel and rename your `gulpfile.js` to `gulpfile.babel.js`. - -```sh -npm install --save-dev @babel/register @babel/core @babel/preset-env -``` - -Then create a **.babelrc** file with the preset configuration. - -```js -{ - "presets": [ "@babel/preset-env" ] -} -``` - -And here's the same sample from above written in **ES2015+**. +And here's the same sample from above written in **ESNext**. ```js -import gulp from 'gulp'; +import { src, dest, watch } from 'gulp'; import less from 'gulp-less'; import babel from 'gulp-babel'; import concat from 'gulp-concat'; @@ -160,7 +146,7 @@ export const clean = () => del([ 'assets' ]); * You can also declare named functions and export them as tasks */ export function styles() { - return gulp.src(paths.styles.src) + return src(paths.styles.src) .pipe(less()) .pipe(cleanCSS()) // pass in options to the stream @@ -168,23 +154,23 @@ export function styles() { basename: 'main', suffix: '.min' })) - .pipe(gulp.dest(paths.styles.dest)); + .pipe(dest(paths.styles.dest)); } export function scripts() { - return gulp.src(paths.scripts.src, { sourcemaps: true }) + return src(paths.scripts.src, { sourcemaps: true }) .pipe(babel()) .pipe(uglify()) .pipe(concat('main.min.js')) - .pipe(gulp.dest(paths.scripts.dest)); + .pipe(dest(paths.scripts.dest)); } /* * You could even use `export as` to rename exported tasks */ function watchFiles() { - gulp.watch(paths.scripts.src, scripts); - gulp.watch(paths.styles.src, styles); + watch(paths.scripts.src, scripts); + watch(paths.styles.src, styles); } export { watchFiles as watch }; diff --git a/index.mjs b/index.mjs new file mode 100644 index 00000000..f1d808dd --- /dev/null +++ b/index.mjs @@ -0,0 +1,16 @@ +import gulp from "./index.js"; + +// These are bound to the gulp instance in our CommonJS file +// so it is okay to reassign them to export +export const watch = gulp.watch; +export const task = gulp.task; +export const series = gulp.series; +export const parallel = gulp.parallel; +export const registry = gulp.registry; +export const tree = gulp.tree; +export const lastRun = gulp.lastRun; +export const src = gulp.src; +export const dest = gulp.dest; +export const symlink = gulp.symlink; + +export default gulp; diff --git a/package.json b/package.json index b335a134..5d2a668a 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,12 @@ "node": ">=10.13.0" }, "main": "index.js", + "exports": { + ".": { + "import": "./index.mjs", + "require": "./index.js" + } + }, "files": [ "LICENSE", "index.js", diff --git a/test/fixtures/gulpfiles/mjs/gulpfile.mjs b/test/fixtures/gulpfiles/mjs/gulpfile.mjs new file mode 100644 index 00000000..332e027c --- /dev/null +++ b/test/fixtures/gulpfiles/mjs/gulpfile.mjs @@ -0,0 +1,30 @@ +import assert from "assert"; +import EventEmitter from "events"; + +import gulp, { + watch, + task, + series, + parallel, + registry, + tree, + lastRun, + src, + dest, + symlink, +} from 'gulp'; + +export default function (done) { + assert(typeof watch === 'function'); + assert(typeof task === 'function'); + assert(typeof series === 'function'); + assert(typeof parallel === 'function'); + assert(typeof registry === 'function'); + assert(typeof tree === 'function'); + assert(typeof lastRun === 'function'); + assert(typeof src === 'function'); + assert(typeof dest === 'function'); + assert(typeof symlink === 'function'); + assert(gulp instanceof EventEmitter); + done(); +} diff --git a/test/index.test.js b/test/index.test.js index 0e8b65fb..de5f68c4 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -73,4 +73,22 @@ describe('gulp', function() { done(); }); }); + + it('can run against gulpfile.mjs', function (done) { + // Node v10 didn't support `exports` in package.json + if (process.version.startsWith('v10.')) { + this.skip(); + } + + this.timeout(5000); + + var cli = path.join(__dirname, '../bin/gulp.js'); + var opts = { cwd: path.join(__dirname, 'fixtures/gulpfiles/mjs' ) }; + cp.exec('node ' + cli, opts, function (err, stdout, stderr) { + expect(err).toBeNull(); + expect(stdout).toMatch('gulpfile.mjs'); + expect(stderr).toEqual(''); + done(); + }); + }); }); From bf72116c5d5f613836b392fb83633ea6c14f3a65 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 28 Mar 2024 19:49:51 -0700 Subject: [PATCH 213/225] chore: Add index.mjs to files list --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 5d2a668a..2596c608 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "files": [ "LICENSE", "index.js", + "index.mjs", "bin" ], "bin": { From 5c4c5473c5582a8e4495c695ecd93b13f0852cbd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 19:56:40 -0700 Subject: [PATCH 214/225] chore: Release 5.0.0 (#2762) chore: Update changelog for all subprojects (#2763) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Blaine Bublitz --- CHANGELOG.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6555ded..d712e881 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,108 @@ # gulp changelog +## [5.0.0](https://www.github.com/gulpjs/gulp/compare/v4.0.2...v5.0.0) (2024-03-29) + +We've tried to provide a high-level changelog for gulp v5 below, but it +doesn't contain all changes from the 60+ dependencies that we maintain. + +Please see [individual changelogs](#individual-changelogs) to drill down +into all changes that were made. + +### ⚠ BREAKING CHANGES + +* Drop support for Node.js <10.13 +* Default stream encoding to UTF-8 +* Standardized on `anymatch` library for globbing paths. All globs should work the same between `src` and `watch` now! +* Removed support for ordered globs. This aligns with the chokidar globbing implementation. If you need your globs to be ordered, you can use `ordered-read-stream` +* All globs and paths are normalized to unix-like filepaths +* Only allow JS variants for `.gulp.*` config files +* Removed support for alpha releases of v4 from `gulp-cli` +* Removed the `--verify` flag +* Renamed the `--require` flag to `--preload` to avoid conflicting with Node.js flags +* Removed many legacy and deprecated loaders +* Upgrade to chokidar v3 +* Clone `Vinyl` objects with stream contents using `teex`, but no longer wait for all streams to flow before cloned streams will receive data +* Stop using `process.umask()` to make directories, instead falling back to Node's default mode +* Throw on non-function, non-string option coercers +* Drop support of Node.js snake_case flags +* Use a Symbol for attaching the `gulplog` namespace to the store +* Use a Symbol for attaching the `gulplog` store to the global +* Use sha256 to hash the `v8flags` cache into a filename + +### Features + +* Streamlined the dependency tree +* Switch all streams implementation to Streamx +* Rewrote `glob-stream` to use a custom directory walk that relies on newer Node.js features and is more performant than old implementation +* Implement translation support for all CLI messages and all messages passing through gulplog +* Allow users to customize or remove the timestamp from their logs +* Upgraded gulplog to v2. Messages logged via v1 will also display a deprecated warning. Plugins should update to v2 as the community upgrades to gulp 5 +* Added support for `gulpile.cjs` and `gulpfile.mjs` +* Add support for `swc`, `esbuild`, `sucrase`, and `mdx` loaders +* Provide an ESM export ([#2760](https://www.github.com/gulpjs/gulp/issues/2760)) ([b00de68](https://www.github.com/gulpjs/gulp/commit/b00de681f5ef6ade283d544f62f770f6b27a9e52)) +* Support sourcemap handling on streaming `Vinyl` contents +* Support `extends` syntax for `.gulp.*` config file +* Allow overriding `gulpfile` and `preloads` via `.gulp.*` config file + +### Bug Fixes + +* Resolve bugs related to symlinks on various platforms +* Resolved some reported ReDoS CVEs and improved performance in glob-parent +* Rework errors surfaced when encountering files or symlinks when trying to create directories +* Ensure watch allows japanese characters in globs ([72668c6](https://www.github.com/gulpjs/gulp/commit/72668c61e445c81fad23bc6ed24967a3238a648d)) +* Ensure watch does not trigger on negated globs ([72668c6](https://www.github.com/gulpjs/gulp/commit/72668c61e445c81fad23bc6ed24967a3238a648d)) +* Improve handling of BOM at the beginning of a stream +* Properly handle function coercer in array of option coercers +* Fork `to-absolute-glob` to: + - Check negative patterns before trimming + - Ensure glob-like characters are escaped in cwd & root options + - Resolve `../` at the beginning of globs + +### Miscellaneous Chores + +* Remove lazystream dependency +* Updated various stream test suites to test against Node.js core `stream`, `readable-stream`, and `streamx` +* Normalize repository, dropping node <10.13 support ([#2758](https://www.github.com/gulpjs/gulp/issues/2758)) ([72668c6](https://www.github.com/gulpjs/gulp/commit/72668c61e445c81fad23bc6ed24967a3238a648d)) + +### Individual Changelogs + +We created and maintain various projects that gulp depends upon. You can find their changelogs linked below: + +* [undertaker](https://github.com/gulpjs/undertaker/blob/master/CHANGELOG.md#200-2024-03-22) +* [vinyl-fs](https://github.com/gulpjs/vinyl-fs/blob/master/CHANGELOG.md#400-2023-06-11) +* [glob-stream](https://github.com/gulpjs/glob-stream/blob/master/CHANGELOG.md#801-2024-03-25) +* [gulp-cli](https://github.com/gulpjs/gulp-cli/blob/master/CHANGELOG.md#300-2024-03-24) +* [interpret](https://github.com/gulpjs/interpret/blob/master/CHANGELOG.md#311-2022-06-29) +* [glob-parent](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md#602-2021-09-29) +* [glob-watcher](https://github.com/gulpjs/glob-watcher/blob/master/CHANGELOG.md#600-2023-05-31) +* [vinyl](https://github.com/gulpjs/vinyl/blob/master/CHANGELOG.md#300-2022-09-26) +* [fs-mkdirp-stream](https://github.com/gulpjs/fs-mkdirp-stream/blob/master/CHANGELOG.md#201-2022-09-17) +* [lead](https://github.com/gulpjs/lead/blob/master/CHANGELOG.md#400-2022-09-22) +* [vinyl-sourcemap](https://github.com/gulpjs/vinyl-sourcemap/blob/master/CHANGELOG.md#200-2022-10-17) +* [to-through](https://github.com/gulpjs/to-through/blob/master/CHANGELOG.md#300-2022-09-07) +* [resolve-options](https://github.com/gulpjs/resolve-options/blob/master/CHANGELOG.md#200-2022-06-24) +* [remove-bom-stream](https://github.com/gulpjs/remove-bom-stream/blob/master/CHANGELOG.md#200-2022-04-19) +* [value-or-function](https://github.com/gulpjs/value-or-function/blob/master/CHANGELOG.md#400-2022-01-30) +* [now-and-later](https://github.com/gulpjs/now-and-later/blob/master/CHANGELOG.md#300-2022-06-25) +* [@gulpjs/to-absolute-glob](https://github.com/gulpjs/to-absolute-glob/blob/master/CHANGELOG.md#400-2023-01-03) +* [fined](https://github.com/gulpjs/fined/blob/master/CHANGELOG.md#200-2021-10-31) +* [mute-stdout](https://github.com/gulpjs/mute-stdout/blob/master/CHANGELOG.md#200-2021-11-22) +* [semver-greatest-satisfied-range](https://github.com/gulpjs/semver-greatest-satisfied-range/blob/master/CHANGELOG.md#200-2022-01-31) +* [flagged-respawn](https://github.com/gulpjs/flagged-respawn/blob/master/CHANGELOG.md#200-2021-11-21) +* [rechoir](https://github.com/gulpjs/rechoir/blob/master/CHANGELOG.md#080-2021-07-24) +* [gulplog](https://github.com/gulpjs/gulplog/blob/master/CHANGELOG.md#220-2024-03-23) +* [glogg](https://github.com/gulpjs/glogg/blob/master/CHANGELOG.md#220-2024-03-23) +* [@gulpjs/messages](https://github.com/gulpjs/messages/blob/master/CHANGELOG.md#110-2024-03-24) +* [sparkles](https://github.com/gulpjs/sparkles/blob/master/CHANGELOG.md#210-2024-03-23) +* [liftoff](https://github.com/gulpjs/liftoff/blob/main/CHANGELOG.md#500-2024-03-16) +* [v8flags](https://github.com/gulpjs/v8flags/blob/master/CHANGELOG.md#401-2023-09-03) +* [bach](https://github.com/gulpjs/bach/blob/master/CHANGELOG.md#201-2022-08-29) +* [undertaker-registry](https://github.com/gulpjs/undertaker-registry/blob/master/CHANGELOG.md#200-2021-12-29) +* [async-settle](https://github.com/gulpjs/async-settle/blob/master/CHANGELOG.md#200-2022-06-25) +* [last-run](https://github.com/gulpjs/last-run/blob/master/CHANGELOG.md#200-2022-01-10) +* [async-done](https://github.com/gulpjs/async-done/blob/master/CHANGELOG.md#200-2022-06-25) +* [replace-homedir](https://github.com/gulpjs/replace-homedir/blob/master/CHANGELOG.md#200-2022-01-31) + ## 4.0.0 ### Task system changes diff --git a/package.json b/package.json index 2596c608..be5477dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gulp", - "version": "4.0.2", + "version": "5.0.0", "description": "The streaming build system.", "homepage": "https://gulpjs.com", "author": "Gulp Team (https://gulpjs.com/)", From 9c818e68e3e0124ca44ceeafeb4f7d1d934f1e49 Mon Sep 17 00:00:00 2001 From: contra Date: Sat, 6 Apr 2024 12:44:10 -0700 Subject: [PATCH 215/225] chore: update src.md docs to add encoding parameter --- docs/api/src.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/api/src.md b/docs/api/src.md index b6c69009..ac28ec17 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -55,6 +55,7 @@ When an invalid glob is given in `globs`, throws an error with the message, "Inv | name | type | default | note | |:--------:|:------:|------------|--------| +| encoding | string
boolean | "utf8" | When false, file contents are treated as binary. When a string, this is used as the text encoding. | | buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. It may not be possible to buffer the contents of large files.
**Note:** Plugins may not implement support for streaming contents. | | read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | | since | date
timestamp
function | | When set, only creates Vinyl objects for files modified since the specified time. | From a85eddb1660fd9a61265a5a260c417514be469a7 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 7 Apr 2024 21:13:19 -0700 Subject: [PATCH 216/225] chore: Remove node-glob options from docs (#2786) --- docs/api/src.md | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/docs/api/src.md b/docs/api/src.md index ac28ec17..a4d9105e 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -68,27 +68,15 @@ When an invalid glob is given in `globs`, throws an error with the message, "Inv | root | string | | The root path that `globs` are resolved against.
_This option is passed directly to [glob-stream][glob-stream-external]._ | | allowEmpty | boolean | false | When false, `globs` which can only match one file (such as `foo/bar.js`) causes an error to be thrown if they don't find a match. If true, suppresses glob failures.
_This option is passed directly to [glob-stream][glob-stream-external]._ | | uniqueBy | string
function | `'path'` | Remove duplicates from the stream by comparing the string property name or the result of the function.
**Note:** When using a function, the function receives the streamed data (objects containing `cwd`, `base`, `path` properties). | -| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| silent | boolean | true | When true, suppresses warnings from printing on `stderr`.
**Note:** This option is passed directly to [node-glob][node-glob-external] but defaulted to `true` instead of `false`. | -| mark | boolean | false | If true, a `/` character will be appended to directory matches. Generally not needed because paths are normalized within the pipeline.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nosort | boolean | false | If true, disables sorting the glob results.
_This option is passed directly to [node-glob][node-glob-external]._ | -| stat | boolean | false | If true, `fs.stat()` is called on all results. This adds extra overhead and generally should not be used.
_This option is passed directly to [node-glob][node-glob-external]._ | -| strict | boolean | false | If true, an error will be thrown if an unexpected problem is encountered while attempting to read a directory.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [node-glob][node-glob-external]._ | -| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [node-glob][node-glob-external]._ | -| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [node-glob][node-glob-external]._ | -| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nodir | boolean | false | If true, only matches files, not directories.
**Note:** To match only directories, end your glob with a `/`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [node-glob][node-glob-external]._ | -| follow | boolean | false | If true, symlinked directories will be traversed when expanding `**` globs.
**Note:** This can cause problems with cyclical links.
_This option is passed directly to [node-glob][node-glob-external]._ | -| realpath | boolean | false | If true, `fs.realpath()` is called on all results. This may result in dangling links.
_This option is passed directly to [node-glob][node-glob-external]._ | -| cache | object | | A previously generated cache object - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| statCache | object | | A previously generated cache of `fs.Stat` results - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| symlinks | object | | A previously generated cache of symbolic links - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nocomment | boolean | false | When false, treat a `#` character at the start of a glob as a comment.
_This option is passed directly to [node-glob][node-glob-external]._ | +| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [anymatch][anymatch-external]._ | +| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [anymatch][anymatch-external]._ | +| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [anymatch][anymatch-external]._ | +| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [anymatch][anymatch-external]._ | +| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [anymatch][anymatch-external]._ | +| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [anymatch][anymatch-external]._ | +| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [anymatch][anymatch-external]._ | +| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [anymatch][anymatch-external]._ | +| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [anymatch][anymatch-external]._ | ## Sourcemaps @@ -120,5 +108,5 @@ src('input/**/*.js', { sourcemaps: true }) [glob-base-concepts]: ../api/concepts.md#glob-base [globs-concepts]: ../api/concepts.md#globs [extglob-docs]: ../documentation-missing.md -[node-glob-external]: https://github.com/isaacs/node-glob +[anymatch-external]: https://github.com/micromatch/anymatch [glob-stream-external]: https://github.com/gulpjs/glob-stream From fe9dee65f31dd0540116dad8a4e9b976a0014d4c Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 7 Apr 2024 21:13:56 -0700 Subject: [PATCH 217/225] chore: Remove locale docs (#2787) --- docs/locale/pl_PL/README.md | 66 -------------- docs/locale/pl_PL/api/concepts.md | 77 ----------------- .../pl_PL/getting-started/1-quick-start.md | 85 ------------------- .../2-javascript-and-gulpfiles.md | 31 ------- 4 files changed, 259 deletions(-) delete mode 100644 docs/locale/pl_PL/README.md delete mode 100644 docs/locale/pl_PL/api/concepts.md delete mode 100644 docs/locale/pl_PL/getting-started/1-quick-start.md delete mode 100644 docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md diff --git a/docs/locale/pl_PL/README.md b/docs/locale/pl_PL/README.md deleted file mode 100644 index ced80144..00000000 --- a/docs/locale/pl_PL/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Dokumentacja gulp - -* [Pierwsze kroki](getting-started/) - Pierwsze kroki z gulp -* [Dokumentacja API](/docs/api/) - Interfejs programowania, zdefiniowany -* [Dokumentacja CLI](/docs/CLI.md) - Dowiedz się, jak wywoływać taski i korzystać z kompilatorów -* [Pisanie wtyczki](/docs/writing-a-plugin/) - Podstawy pisania wtyczki gulp -* [Czemu używać Pump?](/docs/why-use-pump/README.md) - Dlaczego używać modułu `pump` zamiast wywoływać `.pipe` yourself -* [Dokumentacja język chiński uproszczony][SimplifiedChineseDocs] - gulp 简体中文文档 -* [Dokumentacja język koreański][KoreanDocs] - gulp 한국어 참조 문서 -* [Dokumentacja język polski][PolishDocs] - gulp Dokumentacja - - -## FAQ - -Zobacz [FAQ](/docs/FAQ.md) aby uzyskać odpowiedzi na najczęściej zadawane pytania. - - -## Receptury - -Społeczność napisała [receptury](/docs/recipes#recipes) dla typowych przypadków użycia gulp. - - -## Nadal masz pytania? - -Napisz post na [StackOverflow z tagiem #gulp](https://stackoverflow.com/questions/tagged/gulp) lub wpadnij z nami na czat [#gulpjs](https://webchat.freenode.net/?channels=gulpjs) na [Freenode](https://freenode.net/). - -## Wideo -* [Wstęp do Gulp 4](https://youtu.be/N42LQ2dLoA8) prezentowany przez @addyosmani oraz @gauntface - -## Książki -* [Developing a gulp Edge](http://shop.oreilly.com/product/9781939902146.do) -* [Getting Started with Gulp – Second Edition](https://www.packtpub.com/application-development/getting-started-gulp-%E2%80%93-second-edition) - Travis Maynard, Packt (April 2017) - - -## Artykuły -* [Tagtree intro to gulp video](http://tagtree.io/gulp) -* [Introduction to node.js streams](https://github.com/substack/stream-handbook) -* [Video introduction to node.js streams](https://www.youtube.com/watch?v=QgEuZ52OZtU) -* [Getting started with gulp (by @markgdyr)](https://markgoodyear.com/2014/01/getting-started-with-gulp/) -* [A cheatsheet for gulp](https://github.com/osscafe/gulp-cheatsheet) -* [Why you shouldn’t create a gulp plugin (or, how to stop worrying and learn to love existing node packages)](http://blog.overzealous.com/post/74121048393/why-you-shouldnt-create-a-gulp-plugin-or-how-to-stop) -* [Inspiration (slides) about why gulp was made](http://slid.es/contra/gulp) -* [Building With Gulp](http://www.smashingmagazine.com/2014/06/11/building-with-gulp/) -* [Gulp - The Basics (screencast)](https://www.youtube.com/watch?v=dwSLFai8ovQ) -* [Get started with gulp (video series)](https://www.youtube.com/playlist?list=PLRk95HPmOM6PN-G1xyKj9q6ap_dc9Yckm) -* [Optimize your web code with gulp](http://www.linuxuser.co.uk/tutorials/optimise-your-web-code-with-gulp-js) -* [Automate Your Tasks Easily with Gulp.js ](https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js) -* [How to upgrade to Gulp v4](https://www.liquidlight.co.uk/blog/article/how-do-i-update-to-gulp-4/) - -## Przykłady - -- [Web Starter Kit gulpfile](https://github.com/google/web-starter-kit/blob/master/gulpfile.babel.js) - - -## Licencja - -Cała dokumentacja objęta jest licencją CC0 *(rób co chcesz - domena publiczna)*. - -[![CC0](https://i.creativecommons.org/p/zero/1.0/88x31.png)](https://creativecommons.org/publicdomain/zero/1.0/) - -W zakresie, w jakim jest to możliwe na mocy prawa, [Fractal](http://wearefractal.com) zrzekł się wszelkich praw autorskich i pokrewnych lub powiązanych do tego dzieła. - -[SpanishDocs]: https://github.com/bucaran/gulp-docs-es -[SimplifiedChineseDocs]: https://github.com/lisposter/gulp-docs-zh-cn -[KoreanDocs]: https://github.com/preco21/gulp-docs-ko -[PolishDocs]: /docs/locale/pl_PL/README.md diff --git a/docs/locale/pl_PL/api/concepts.md b/docs/locale/pl_PL/api/concepts.md deleted file mode 100644 index d23325bc..00000000 --- a/docs/locale/pl_PL/api/concepts.md +++ /dev/null @@ -1,77 +0,0 @@ -# Pojęcia - -Poniższe pojęcia są niezbędne do zrozumienia dokumentacji API. Będą się do nich odwoływać w całości, wróć do tej strony, aby uzyskać szczegółowe wyjaśnienia. - -Jeśli jesteś tu nowy, zacznij od [Poradnik wprowadzający][quick-start-docs]. - -## Vinyl - -Vinyl to obiekt metadanych opisujący plik. Główne właściwości instancji Vinyl to `path` i `contents` - podstawowe aspekty pliku w systemie plików. Obiekty Vinyl mogą być używane do opisywania plików z wielu źródeł - w lokalnym systemie plików lub dowolnej opcji zdalnego przechowywania. - -## Adaptery Vinyl - -Chociaż Vinyl zapewnia sposób na opisanie pliku, potrzebny jest sposób na dostęp do tych plików. Każde źródło pliku jest dostępne za pomocą adaptera Vinyl. - -Adapter udostępnia: -* Metoda z podpisem `src (globs, [opcje])` i zwraca strumień, który produkuje obiekty Vinyl. -* Metoda z podpisem `dest (folder, [opcje])` i zwraca strumień, który zużywa obiekty Vinyl. -* Wszelkie dodatkowe metody specyficzne dla ich nośnika wejścia / wyjścia - takie jak metoda `symlink`, którą zapewnia `winyl-fs`. Powinny zawsze zwracać strumienie, które produkują i / lub zużywają obiekty Vinyl. - -## Zadania - -Każde zadanie gulp to asynchroniczna funkcja JavaScript, która albo przyjmuje wywołanie zwrotne z pierwszym błędem, albo zwraca strumień, obietnicę, emiter zdarzeń, proces podrzędny lub observable. Z powodu pewnych ograniczeń platformy zadania synchroniczne nie są obsługiwane. - -Aby uzyskać bardziej szczegółowe wyjaśnienie, patrz [Tworzenie zadań][creating-tasks-doc]. - -## Globs - -Glob jest ciągiem literałów i / lub symboli wieloznacznych, takich jak `*`, `**` lub `!`, używanych do dopasowania ścieżek plików. Globbing to czynność polegająca na lokalizowaniu plików w systemie plików przy użyciu co najmniej jednego globu. - -Jeśli nie masz doświadczenia z globami, zobacz [Wyjaśnianie Globs][explaining-globs-docs]. - -## Glob base - -Glob base - czasami nazywany globem parent - to segment ścieżki przed znakami specjalnymi w ciągu globu. Jako taka, globalną bazą `/src /js/**. Js` jest `/src/js/`. Wszystkie ścieżki pasujące do globu mają tę samą bazę globalną - ten segment ścieżki nie może być zmienny. - -Instancje Vinyl generowane przez `src ()` są konstruowane z ustawieniem glob base jako ich właściwości `base`. Po zapisaniu do systemu plików za pomocą `dest ()`, `base` zostanie usunięte ze ścieżki wyjściowej, aby zachować struktury katalogów. - -Aby uzyskać więcej szczegółowych informacji, zobacz [glob-parent][glob-parent-external] repository. - -## File system stats - -Metadane pliku są dostarczane jako instancja węzła [`fs.Stats`][fs-stats-external]. Jest dostępny jako właściwość `stat` w twoich instancjach Vinyl i używany wewnętrznie do ustalenia, czy obiekt Vinyl reprezentuje katalog lub dowiązanie symboliczne. Po zapisaniu w systemie plików uprawnienia i wartości czasu są synchronizowane z właściwością `stat` obiektu Vinyl. - -## File system modes - -Tryby systemu plików określają, jakie uprawnienia istnieją dla pliku. Większość plików i katalogów w twoim systemie plików będzie miała dość permisywny tryb, pozwalający gulpowi na odczyt / zapis / aktualizację plików w twoim imieniu. Domyślnie gulp tworzy pliki z tymi samymi uprawnieniami, co uruchomiony proces, ale możesz skonfigurować tryby za pomocą opcji w `src ()`, `dest ()` itp. Jeśli masz problemy z uprawnieniami (EPERM), sprawdź tryby plików. - -## Moduły - -Gulp składa się z wielu małych modułów połączonych ze sobą w celu zapewnienia spójnej pracy. Używając [semver][semver-external] w małych modułach, możemy wydać poprawki błędów i funkcje bez publikowania nowych wersji gulp. Często, gdy nie widać postępu w głównym repozytorium, praca jest wykonywana w jednym z tych modułów. - -Jeśli masz problemy, sprawdź, czy bieżące moduły zostały zaktualizowane za pomocą polecenia `npm update`. Jeśli problem będzie się powtarzał, otwórz problem w indywidualnym repozytorium projektu. - -* [undertaker][undertaker-external] - the task registration system -* [vinyl][vinyl-external] - the virtual file objects -* [vinyl-fs][vinyl-fs-external] - a vinyl adapter to your local file system -* [glob-watcher][glob-watcher-external] - the file watcher -* [bach][bach-external] - task orchestration using `series()` and `parallel()` -* [last-run][last-run-external] - tracks the last run time of a task -* [vinyl-sourcemap][vinyl-sourcemap-external] - built-in sourcemap support -* [gulp-cli][gulp-cli-external] - the command line interface for interacting with gulp - - -[quick-start-docs]: ../getting-started/1-quick-start.md -[creating-tasks-doc]: ../getting-started/3-creating-tasks.md -[explaining-globs-docs]: ../getting-started/6-explaining-globs.md -[undertaker-external]: https://github.com/gulpjs/undertaker -[vinyl-external]: https://github.com/gulpjs/vinyl -[vinyl-fs-external]: https://github.com/gulpjs/vinyl-fs -[glob-watcher-external]: https://github.com/gulpjs/glob-watcher -[bach-external]: https://github.com/gulpjs/bach -[last-run-external]: https://github.com/gulpjs/last-run -[vinyl-sourcemap-external]: https://github.com/gulpjs/vinyl-sourcemap -[gulp-cli-external]: https://github.com/gulpjs/gulp-cli -[semver-external]: https://semver.org -[fs-stats-external]: https://nodejs.org/api/fs.html#fs_class_fs_stats -[glob-parent-external]: https://github.com/es128/glob-parent diff --git a/docs/locale/pl_PL/getting-started/1-quick-start.md b/docs/locale/pl_PL/getting-started/1-quick-start.md deleted file mode 100644 index 3d1b54df..00000000 --- a/docs/locale/pl_PL/getting-started/1-quick-start.md +++ /dev/null @@ -1,85 +0,0 @@ -# Szybki start - -Jeśli wcześniej instalowałeś gulp globalnie, uruchom `npm rm --global gulp` przed wykonaniem tych instrukcji. Aby uzyskać więcej informacji, przeczytaj to [Sip][sip-article]. - -## Sprawdź dla node, npm, oraz npx -```sh -node --version -``` -![Output: v8.11.1][img-node-version-command] -```sh -npm --version -``` -![Output: 5.6.0][img-npm-version-command] -```sh -npx --version -``` -![Output: 9.7.1][img-npx-version-command] - -If they are not installed, follow the instructions [here][node-install]. - -## Zainstaluj narzędzie wiersza poleceń gulp -```sh -npm install --global gulp-cli -``` - - -## Utwórz katalog projektu i przejdź do niego -```sh -npx mkdirp my-project -``` -```sh -cd my-project -``` - -## Utwórz plik package.json w katalogu projektu -```sh -npm init -``` - -To poprowadzi cię przez nadanie projektowi nazwy, wersji, opisu itp. - -## Zainstaluj pakiet gulp w swoich devDependencies -```sh -npm install --save-dev gulp -``` - -## Sprawdź swoje wersje gulp - -```sh -gulp --version -``` - -Upewnij się, że dane wyjściowe odpowiadają zrzutowi ekranu poniżej, w przeciwnym razie może być konieczne ponowne uruchomienie kroków opisanych w tym przewodniku. - -![Output: CLI version 2.0.1 & Local version 4.0.0][img-gulp-version-command] - -## Stwórz gulpfile -Za pomocą edytora tekstu utwórz plik o nazwie gulpfile.js w katalogu głównym projektu z następującymi treściami: -```js -function defaultTask(cb) { - // place code for your default task here - cb(); -} - -exports.default = defaultTask -``` - -## Przetestuj to -Uruchom polecenie gulp w katalogu projektu: -```sh -gulp -``` -Aby uruchomić wiele zadań, możesz użyć `gulp `. - -## Wynik -Zadanie domyślne zostanie uruchomione i nic nie zrobi. -![Output: Starting default & Finished default][img-gulp-command] - -[sip-article]: https://medium.com/gulpjs/gulp-sips-command-line-interface-e53411d4467 -[node-install]: https://nodejs.org/en/ -[img-node-version-command]: https://gulpjs.com/img/docs-node-version-command.png -[img-npm-version-command]: https://gulpjs.com/img/docs-npm-version-command.png -[img-npx-version-command]: https://gulpjs.com/img/docs-npx-version-command.png -[img-gulp-version-command]: https://gulpjs.com/img/docs-gulp-version-command.png -[img-gulp-command]: https://gulpjs.com/img/docs-gulp-command.png diff --git a/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md b/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md deleted file mode 100644 index 989ea917..00000000 --- a/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md +++ /dev/null @@ -1,31 +0,0 @@ -# JavaScript oraz Gulpfiles - -Gulp umożliwia wykorzystanie istniejącej wiedzy o języku JavaScript do pisania plików gulpfiles lub wykorzystanie doświadczenia z plikami gulpfiles do pisania zwykłego kodu JavaScript. Chociaż dostępnych jest kilka narzędzi upraszczających pracę z systemem plików i wierszem poleceń, wszystko, co piszesz, to czysty JavaScript. - -## Gulpfile wytłumaczony - -Plik gulpfile to plik w katalogu projektu o nazwie `gulpfile.js` (lub pisany wielkimi literami jako `Gulpfile.js`, jak Makefile), który automatycznie ładuje się po uruchomieniu polecenia `gulp`. W tym pliku często zobaczysz interfejsy API gulp, takie jak `src ()`, `dest ()`, `series ()` lub `parallel ()`, ale można użyć dowolnego standardowego modułu JavaScript lub Node. Wszelkie wyeksportowane funkcje zostaną zarejestrowane w systemie zadań gulp. - -## Transpilacja - -Możesz napisać plik gulpfile przy użyciu języka wymagającego transpilacji, takiego jak TypeScript lub Babel, zmieniając rozszerzenie w swoim `gulpfile.js` aby wskazać język i zainstalować odpowiedni moduł transpilatora. - -* Dla TypeScript, zmień nazwę `gulpfile.ts` i zaintaluj moduł [ts-node][ts-node-module]. -* Dla Babel, zmień nazwę na `gulpfile.babel.js` i zainstaluj moduł [@babel/register][babel-register-module]. - -__Większość nowych wersji node obsługuje większość funkcji udostępnianych przez TypeScript lub Babel, z wyjątkiem składni `import`/`export`. Jeśli pożądana jest tylko ta składnia, zmień nazwę na `gulpfile.esm.js` i zainstaluj moduł [esm][esm-module].__ - -Aby uzyskać bardziej zaawansowane informacje na ten temat i pełną listę obsługiwanych rozszerzeń, zobacz naszą dokumentację [gulpfile transpilation][gulpfile-transpilation-advanced]. - -## Dzielenie pliku gulpfile - -Wielu użytkowników zaczyna od dodania całej logiki do pliku gulpfile. Jeśli kiedykolwiek stanie się zbyt duży, można go przekształcić w osobne pliki. - -Każde zadanie można podzielić na własny plik, a następnie zaimportować do pliku gulp w celu złożenia. Pozwala to nie tylko utrzymać porządek, ale umożliwia testowanie każdego zadania niezależnie lub różnicowanie składu w zależności od warunków. - -Moduł Node'a pozwala zastąpić twój plik `gulpfile.js` z katalogiem o nazwie `gulpfile.js` który zawiera plik `index.js` który jest traktowany jako `gulpfile.js`. Ten katalog może następnie zawierać poszczególne moduły zadań. Jeśli używasz transpilatora, odpowiednio nazwij folder i plik. - -[gulpfile-transpilation-advanced]: ../documentation-missing.md -[ts-node-module]: https://www.npmjs.com/package/ts-node -[babel-register-module]: https://www.npmjs.com/package/@babel/register -[esm-module]: https://www.npmjs.com/package/esm From 2fa4981a910d7bdedb758bd09868620c9bb21d54 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 7 Apr 2024 21:15:08 -0700 Subject: [PATCH 218/225] chore: Update glob docs with replacement to ordered globs (#2788) --- docs/getting-started/6-explaining-globs.md | 28 +++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/getting-started/6-explaining-globs.md b/docs/getting-started/6-explaining-globs.md index 11f34fae..4517d8aa 100644 --- a/docs/getting-started/6-explaining-globs.md +++ b/docs/getting-started/6-explaining-globs.md @@ -9,7 +9,7 @@ sidebar_label: Explaining Globs A glob is a string of literal and/or wildcard characters used to match filepaths. Globbing is the act of locating files on a filesystem using one or more globs. -The `src()` method expects a single glob string or an array of globs to determine which files your pipeline will operate on. At least one match must be found for your glob(s) otherwise `src()` will error. When an array of globs is used, they are matched in array order - especially useful for negative globs. +The `src()` method expects a single glob string or an array of globs to determine which files your pipeline will operate on. At least one match must be found for your glob(s) otherwise `src()` will error. When an array of globs is used, any negative globs will remove matches from any positive glob. ## Segments and separators @@ -49,26 +49,37 @@ Here, the glob is appropriately restricted to the `scripts/` directory. It will ## Special character: ! (negative) -Since globs are matched in array order, a negative glob must follow at least one non-negative glob in an array. The first finds a set of matches, then the negative glob removes a portion of those results. When excluding all files within a directory, you must add `/**` after the directory name, which the globbing library optimizes internally. +Globs prefixed with the `!` character will "negate" the glob, excluding the match completely. All negative globs are applied to every positive glob, which is a departure from gulp versions before v5. + +Here, the `scripts/` directory will be traversed for all files ending in `.js`, but all files from the `scripts/vendor/` directory will be excluded. ```js ['scripts/**/*.js', '!scripts/vendor/**'] ``` -If any non-negative globs follow a negative, nothing will be removed from the later set of matches. +Negative globs can be used as an alternative for restricting double-star globs. ```js -['scripts/**/*.js', '!scripts/vendor/**', 'scripts/vendor/react.js'] +['**/*.js', '!node_modules/**'] ``` -Negative globs can be used as an alternative for restricting double-star globs. +## Ordered globs + +Versions of gulp before v5 allowed "ordered globs"; however, that has been removed to align with most globbing libraries in the ecosystem. + +If you need the "ordered glob" functionality, you can use the [ordered-read-streams][ordered-read-streams-docs] library to combine streams: ```js -['**/*.js', '!node_modules/**'] +const order = require("ordered-read-streams"); + +exports.default = function () { + return order([ + gulp.src("input/jquery/dist/jquery.js"), + gulp.src("input/detect_swipe/jquery.detect_swipe.js"), + ]).pipe(gulp.dest('output/')); +} ``` -In the previous example, if the negative glob was `!node_modules/**/*.js`, the globbing library wouldn't optimize the negation and every match would have to be compared against the negative glob, which would be extremely slow. To ignore all files in a directory, only add the `/**` glob after the directory name. - ## Overlapping globs Two or more globs that (un)intentionally match the same file are considered overlapping. When overlapping globs are used within a single `src()`, gulp does its best to remove the duplicates, but doesn't attempt to deduplicate across separate `src()` calls. @@ -86,3 +97,4 @@ Most of what you'll need to work with globs in gulp is covered here. If you'd li [glob-primer-docs]: https://github.com/isaacs/node-glob#glob-primer [begin-globbing-docs]: https://github.com/begin/globbing#what-is-globbing [wikipedia-glob]: https://en.wikipedia.org/wiki/Glob_(programming) +[ordered-read-streams-docs]: https://github.com/gulpjs/ordered-read-streams#orderedstreams-options From 54126058d78a879ab4ebfbfa1e768c7eaa72e6ab Mon Sep 17 00:00:00 2001 From: IOLOII Date: Sun, 1 Jun 2025 10:58:29 +0800 Subject: [PATCH 219/225] chore(docs): Update async completion document for newer RxJS (#2831) Starting with RxJS 6.x, the Observable.of method has been removed, and it's recommended to directly import the of function from 'rxjs' instead. --- docs/getting-started/4-async-completion.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/4-async-completion.md b/docs/getting-started/4-async-completion.md index 0fa262cd..a3a550d0 100644 --- a/docs/getting-started/4-async-completion.md +++ b/docs/getting-started/4-async-completion.md @@ -68,10 +68,10 @@ exports.default = childProcessTask; ### Returning an observable ```js -const { Observable } = require('rxjs'); +const { of } = require('rxjs'); function observableTask() { - return Observable.of(1, 2, 3); + return of(1, 2, 3); } exports.default = observableTask; From c90e79ebcdb697466fb15c127665fa8f57f7f2c0 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 1 Jun 2025 14:18:34 -0700 Subject: [PATCH 220/225] chore: Fix CI (#2835) chore(ci): Add additional Node versions to matrix chore(ci): Temporarily only build on x86_64 MacOS chore(ci): Skip stream tests on Node 10 due to broken compatibility --- .github/workflows/dev.yml | 4 ++-- test/dest.js | 7 +++++++ test/src.js | 7 +++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 3b07263a..4dfe1927 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -31,8 +31,8 @@ jobs: strategy: fail-fast: false matrix: - node: [10, 12, 14, 16] - os: [ubuntu-latest, windows-latest, macos-latest] + node: [10, 12, 14, 16, 18, 20, 22, 24] + os: [ubuntu-latest, windows-latest, macos-13] steps: - name: Clone repository diff --git a/test/dest.js b/test/dest.js index 16c58d21..d3d2dfb0 100644 --- a/test/dest.js +++ b/test/dest.js @@ -11,6 +11,13 @@ var gulp = require('../'); var outpath = path.join(__dirname, './out-fixtures'); describe('gulp.dest()', function() { + before(function () { + if (process.versions.node.startsWith("10.")) { + this.skip(); + return; + } + }); + beforeEach(rimraf.bind(null, outpath)); afterEach(rimraf.bind(null, outpath)); diff --git a/test/src.js b/test/src.js index 82501e73..d2c81611 100644 --- a/test/src.js +++ b/test/src.js @@ -7,6 +7,13 @@ var expect = require('expect'); var gulp = require('../'); describe('gulp.src()', function() { + before(function () { + if (process.versions.node.startsWith("10.")) { + this.skip(); + return; + } + }); + it('should return a stream', function(done) { var stream = gulp.src('./fixtures/*.coffee', { cwd: __dirname }); expect(stream).toBeDefined(); From 04b4a74aec63302f603f0cca3826f75b1bda64ad Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 1 Jun 2025 14:25:53 -0700 Subject: [PATCH 221/225] fix: Support top-level await on Node 22.12+ (#2836) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be5477dd..d0c7c64d 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "dependencies": { "glob-watcher": "^6.0.0", - "gulp-cli": "^3.0.0", + "gulp-cli": "^3.1.0", "undertaker": "^2.0.0", "vinyl-fs": "^4.0.0" }, From 69a5d0e904278dde61c835a0b198d7d1c5a15b95 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 1 Jun 2025 14:43:53 -0700 Subject: [PATCH 222/225] fix: Avoid Node.js deprecation warning for `fs.Stats` (#2838) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d0c7c64d..bf23d3cb 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "glob-watcher": "^6.0.0", "gulp-cli": "^3.1.0", "undertaker": "^2.0.0", - "vinyl-fs": "^4.0.0" + "vinyl-fs": "^4.0.1" }, "devDependencies": { "eslint": "^7.0.0", From 19122f3d9eefccaadcf0e96313a7d3b83348348b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 1 Jun 2025 14:50:03 -0700 Subject: [PATCH 223/225] fix: Avoid globbing before read stream is opened (#2839) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf23d3cb..f9d03e0f 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "glob-watcher": "^6.0.0", "gulp-cli": "^3.1.0", "undertaker": "^2.0.0", - "vinyl-fs": "^4.0.1" + "vinyl-fs": "^4.0.2" }, "devDependencies": { "eslint": "^7.0.0", From 0003e9fd25ffc7dd8c4f1a9335c102b73de017c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 1 Jun 2025 14:52:41 -0700 Subject: [PATCH 224/225] chore: release 5.0.1 (#2837) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d712e881..8dcf8c08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # gulp changelog +### [5.0.1](https://www.github.com/gulpjs/gulp/compare/v5.0.0...v5.0.1) (2025-06-01) + + +### Bug Fixes + +* Avoid globbing before read stream is opened ([#2839](https://www.github.com/gulpjs/gulp/issues/2839)) ([19122f3](https://www.github.com/gulpjs/gulp/commit/19122f3d9eefccaadcf0e96313a7d3b83348348b)) +* Avoid Node.js deprecation warning for `fs.Stats` ([#2838](https://www.github.com/gulpjs/gulp/issues/2838)) ([69a5d0e](https://www.github.com/gulpjs/gulp/commit/69a5d0e904278dde61c835a0b198d7d1c5a15b95)) +* Support top-level await on Node 22.12+ ([#2836](https://www.github.com/gulpjs/gulp/issues/2836)) ([04b4a74](https://www.github.com/gulpjs/gulp/commit/04b4a74aec63302f603f0cca3826f75b1bda64ad)) + ## [5.0.0](https://www.github.com/gulpjs/gulp/compare/v4.0.2...v5.0.0) (2024-03-29) We've tried to provide a high-level changelog for gulp v5 below, but it diff --git a/package.json b/package.json index f9d03e0f..9263e217 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gulp", - "version": "5.0.0", + "version": "5.0.1", "description": "The streaming build system.", "homepage": "https://gulpjs.com", "author": "Gulp Team (https://gulpjs.com/)", From 61f22dc11bb14234b555253095fa1d224ce0eab1 Mon Sep 17 00:00:00 2001 From: Andrew Brampton Date: Sun, 8 Feb 2026 22:30:13 -0800 Subject: [PATCH 225/225] Update README.md to use deleteAsync (#2806) For ~two years 'del' no longer exports a default method, and instead exports `deleteAsync()` and `deleteSync()`, the former replacing `del()` See https://github.com/sindresorhus/del/commit/106d7d8ff813059c437d7c428539b7719292d1d6 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 96d62a67..75b9af80 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ import concat from 'gulp-concat'; import uglify from 'gulp-uglify'; import rename from 'gulp-rename'; import cleanCSS from 'gulp-clean-css'; -import del from 'del'; +import {deleteAsync} from 'del'; const paths = { styles: { @@ -140,7 +140,7 @@ const paths = { /* * For small tasks you can export arrow functions */ -export const clean = () => del([ 'assets' ]); +export const clean = () => deleteAsync([ 'assets' ]); /* * You can also declare named functions and export them as tasks