任务(Tasks) 每一个 gulp 任务都是一个异步 JavaScript 函数,它要么接受一个错误优先回调,要么返回一个流、promise、事件发射器、子进程或observable。因为一些平台限制,不支持同步任务。javascript
gulp 再也不支持同步任务(Synchronous tasks)了。由于同步任务经常会致使难以调试的细微错误,例如忘记从任务(task)中返回 stream。css
当你看到 "Did you forget to signal async completion?" 警告时,说明你并未使用前面提到的返回方式。你须要使用 callback 或返回 stream、promise、event emitter、child process、observable 来解决此问题。java
src() 接受 glob 参数,并从文件系统中读取文件而后生成一个 Node 流(stream)。它将全部匹配的文件读取到内存中并经过流(stream)进行处理。npm
流(stream)所提供的主要的 API 是 .pipe() 方法,用于链接转换流(Transform streams)或可写流(Writable streams)。gulp
当它接收到经过管道(pipeline)传输的文件时,它会将文件内容及文件属性写入到指定的目录中。gulp 还提供了 symlink() 方法,其操做方式相似 dest(),可是建立的是连接而不是文件( 详情请参阅 symlink() )。 大多数状况下,利用 .pipe() 方法将插件放置在 src() 和 dest() 之间,并转换流(stream)中的文件。api
src() 也能够放在管道(pipeline)的中间,以根据给定的 glob 向流(stream)中添加文件。新加入的文件只对后续的转换可用。若是 glob 匹配的文件与以前的有重复,仍然会再次添加文件。 这对于在添加普通的 JavaScript 文件以前先转换部分文件的场景颇有用,添加新的文件后能够对全部文件统一进行压缩并混淆(uglifying)。promise
dest() 能够用在管道(pipeline)中间用于将文件的中间状态写入文件系统。当接收到一个文件时,当前状态的文件将被写入文件系统,文件路径也将被修改以反映输出文件的新位置,而后该文件继续沿着管道(pipeline)传输。 此功能可用于在同一个管道(pipeline)中建立未压缩(unminified)和已压缩(minified)的文件。bash
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/'));
}
复制代码
src() 能够工做在三种模式下:缓冲(buffering)、流动(streaming)和空(empty)模式。这些模式能够经过对 src() 的 buffer 和 read 参数 进行设置。babel
缓冲(Buffering)模式是默认模式,将文件内容加载内存中。插件一般运行在缓冲(buffering)模式下,而且许多插件不支持流动(streaming)模式。并发
流动(Streaming)模式的存在主要用于操做没法放入内存中的大文件,例如巨幅图像或电影。文件内容从文件系统中以小块的方式流式传输,而不是一次性所有加载。若是须要流动(streaming)模式,请查找支持此模式的插件或本身编写。
空(Empty)模式不包含任何内容,仅在处理文件元数据时有用。
glob 是由普通字符和/或通配字符组成的字符串,用于匹配文件路径。能够利用一个或多个 glob 在文件系统中定位文件。
Gulp 插件实质上是 Node 转换流(Transform Streams),它封装了经过管道(pipeline)转换文件的常见功能,一般是使用 .pipe() 方法并放在 src() 和 dest() 之间。他们能够更改通过流(stream)的每一个文件的文件名、元数据或文件内容。
const { src, dest } = require('gulp');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
exports.default = function() {
return src('src/*.js')
// gulp-uglify 插件并不改变文件名
.pipe(uglify())
// 所以使用 gulp-rename 插件修改文件的扩展名
.pipe(rename({ extname: '.min.js' }))
.pipe(dest('output/'));
}
复制代码
gulp api 中的 watch() 方法利用文件系统的监控程序(file system watcher)将 globs 与 任务(task) 进行关联。它对匹配 glob 的文件进行监控,若是有文件被修改了就执行关联的任务(task)。若是被执行的任务(task)没有触发 异步完成 信号,它将永远不会再次运行了
const { watch, series } = require('gulp');
function clean(cb) {
// body omitted
cb();
}
function javascript(cb) {
// body omitted
cb();
}
function css(cb) {
// body omitted
cb();
}
// 能够只关联一个任务
watch('src/*.css', css);
// 或者关联一个任务组合
watch('src/*.js', series(clean, javascript));
复制代码
# Babel 7
$ npm install --save-dev gulp-babel @babel/core @babel/preset-env
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.task('default', () =>
gulp.src('src/app.js')
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(gulp.dest('dist'))
);
复制代码