Skip to content

Commit 45adfc3

Browse files
terinjokesphated
authored andcommitted
Docs: Integrate pump documentation from gulp-uglify (closes #1791)
1 parent a0ec3ff commit 45adfc3

File tree

4 files changed

+123
-0
lines changed

4 files changed

+123
-0
lines changed

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* [API documentation](API.md) - Learn the ins and outs of using gulp
55
* [CLI documentation](CLI.md) - Learn how to call tasks and use compilers
66
* [Writing a Plugin](writing-a-plugin/README.md) - So you're writing a gulp plugin? Go here for the essential dos and don'ts.
7+
* [Why Use Pump?](why-use-pump/README.md) - Why you should use the `pump` module instead of calling `.pipe` yourself.
78
* [Spanish documentation][SpanishDocs] - gulp en Español.
89
* [Simplified Chinese documentation][SimplifiedChineseDocs] - gulp 简体中文文档.
910
* [Korean documentation][KoreanDocs] - gulp 한국어 참조 문서.

docs/why-use-pump/README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Why Use Pump?
2+
3+
When using `pipe` from the Node.js streams, errors are not propagated forward
4+
through the piped streams, and source streams aren’t closed if a destination
5+
stream closed. The [`pump`][pump] module normalizes these problems and passes
6+
you the errors in a callback.
7+
8+
## A common gulpfile example
9+
10+
A common pattern in gulp files is to simply return a Node.js stream, and expect
11+
the gulp tool to handle errors.
12+
13+
```javascript
14+
// example of a common gulpfile
15+
var gulp = require('gulp');
16+
var uglify = require('gulp-uglify');
17+
18+
gulp.task('compress', function () {
19+
// returns a Node.js stream, but no handling of error messages
20+
return gulp.src('lib/*.js')
21+
.pipe(uglify())
22+
.pipe(gulp.dest('dist'));
23+
});
24+
```
25+
26+
![pipe error](pipe-error.png)
27+
28+
There’s an error in one of the JavaScript files, but that error message is the
29+
opposite of helpful. You want to know what file and line contains the error. So
30+
what is this mess?
31+
32+
When there’s an error in a stream, the Node.js stream fire the 'error' event,
33+
but if there’s no handler for this event, it instead goes to the defined
34+
[uncaught exception][uncaughtException] handler. The default behavior of the
35+
uncaught exception handler is documented:
36+
37+
> By default, Node.js handles such exceptions by printing the stack trace to
38+
> stderr and exiting.
39+
40+
## Handling the Errors
41+
42+
Since allowing the errors to make it to the uncaught exception handler isn’t
43+
useful, we should handle the exceptions properly. Let’s give that a quick shot.
44+
45+
```javascript
46+
var gulp = require('gulp');
47+
var uglify = require('gulp-uglify');
48+
49+
gulp.task('compress', function () {
50+
return gulp.src('lib/*.js')
51+
.pipe(uglify())
52+
.pipe(gulp.dest('dist'))
53+
.on('error', function(err) {
54+
console.error('Error in compress task', err.toString());
55+
});
56+
});
57+
```
58+
59+
Unfortunately, Node.js stream’s `pipe` function doesn’t forward errors through
60+
the chain, so this error handler only handles the errors given by
61+
`gulp.dest`. Instead we need to handle errors for each stream.
62+
63+
```javascript
64+
var gulp = require('gulp');
65+
var uglify = require('gulp-uglify');
66+
67+
gulp.task('compress', function () {
68+
function createErrorHandler(name) {
69+
return function (err) {
70+
console.error('Error from ' + name + ' in compress task', err.toString());
71+
};
72+
}
73+
74+
return gulp.src('lib/*.js')
75+
.on('error', createErrorHandler('gulp.src'))
76+
.pipe(uglify())
77+
.on('error', createErrorHandler('uglify'))
78+
.pipe(gulp.dest('dist'))
79+
.on('error', createErrorHandler('gulp.dest'));
80+
});
81+
```
82+
83+
This is a lot of complexity to add in each of your gulp tasks, and it’s easy to
84+
forget to do it. In addition, it’s still not perfect, as it doesn’t properly
85+
signal to gulp’s task system that the task has failed. We can fix this, and we
86+
can handle the other pesky issues with error propogations with streams, but it’s
87+
even more work!
88+
89+
## Using pump
90+
91+
The [`pump`][pump] module is a cheat code of sorts. It’s a wrapper around the
92+
`pipe` functionality that handles these cases for you, so you can stop hacking
93+
on your gulpfiles, and get back to hacking new features into your app.
94+
95+
```javascript
96+
var gulp = require('gulp');
97+
var uglify = require('gulp-uglify');
98+
var pump = require('pump');
99+
100+
gulp.task('compress', function (cb) {
101+
pump([
102+
gulp.src('lib/*.js'),
103+
uglify(),
104+
gulp.dest('dist')
105+
],
106+
cb
107+
);
108+
});
109+
```
110+
111+
The gulp task system provides a gulp task with a callback, which can signal
112+
successful task completion (being called with no arguments), or a task failure
113+
(being called with an Error argument). Fortunately, this is the exact same
114+
format `pump` uses!
115+
116+
![pump error](pump-error.png)
117+
118+
Now it’s very clear what plugin the error was from, what the error actually was,
119+
and from what file and line number.
120+
121+
[pump]: https://github.com/mafintosh/pump
122+
[uncaughtException]: https://nodejs.org/api/process.html#process_event_uncaughtexception

docs/why-use-pump/pipe-error.png

141 KB
Loading

docs/why-use-pump/pump-error.png

65.6 KB
Loading

0 commit comments

Comments
 (0)