1.什么是gulp
Gulp
是一个基于Node.js的自动化构建工具,用于前端项目的构建和开发流程的优化。通过Gulp,可以自动完成文件的压缩、合并、重命名、文件监听、浏览器自动刷新等任务,提高开发效率和代码质量。
2. gulp特点
- 简单易用:Gulp的API简单易懂,上手容易,学习曲线较低。
- 插件丰富:Gulp的插件生态非常丰富,可以满足各种不同的开发需求。
- 高效性能:Gulp采用了流式处理机制,可以在构建过程中尽可能减少中间文件的生成,提高构建效率。
- 可定制性强:Gulp的任务可以自由组合,可以根据项目需求进行灵活配置。
3. gulp常用用途
使用Gulp,可以轻松完成如下任务:
- 压缩CSS、JavaScript、HTML等文件。
- 合并多个CSS、JavaScript等文件为一个文件。
- 对图片进行压缩和优化。
- 实现浏览器自动刷新。
- 实时监控文件变化,并自动执行相应的任务。
- 在构建过程中使用sourcemaps追踪代码。
- 自定义任务,满足项目特定的需求。
4. gulp安装及运行
安装 gulp 命令行工具
最新版本的gulp是4.x,和之前的3.x的gulp有所不同,把cli分离出去了,所以需要单独安装gulp-cli。
npm install --global gulp-cli
创建项目目录并创建 package.json 文件
npx mkdirp my-project
cd my-project
npm init
安装 gulp,作为开发时依赖项
npm install --save-dev gulp
检查 gulp 版本
gulp --version
创建gulpfile.js
文件
在项目根目录下创建一个名为 gulpfile.js 的文件
// gulpfile.js
function defaultTask(cb) {
// place code for your default task here
cb();
}
exports.default = defaultTask
测试
gulp
默认任务(task)将执行,因为任务为空,因此没有实际动作。如果gulp执行不成功 可能是node版本与gulp 版本未对应
gulp 和 Node.js 版本对应关系
- gulp 4.x: 支持 Node.js 16.x.x
- gulp 3.x: 支持 Node.js 10.x.x
5. gulp常用API
5.1 gulp.src(globs, [options])
输出(Emits)符合所提供的匹配模式(glob)或者匹配模式的数组(array of globs)的文件。 将返回一个虚拟文件对象( [Vinyl files](https://github.com/wearefractal/vinyl-fs)
)的 [stream](http://nodejs.org/api/stream.html)
它可以被 [piped](http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options)
到别的插件中,这个虚拟文件对象中存储着原始文件的路径、文件名、内容等信息。
gulp.src还可以接受一个选项对象作为第二个参数,以指定如何处理文件流。 选项对象中最常用的选项是base,它指定将要处理的文件路径的基准目录,以便在后续的Gulp任务中能够保持文件路径的结构 例如:
gulp.src('app/**/*.js', { base: 'app' }).pipe(gulp.dest('dist'));
上面例子会将app路径下的所有js文件写入到dist
中( dist/**/*.js
) 中间没有app这层级路径
5.2 gulp.dest(directory, [options])
将流中的文件写入到指定的文件夹中,并返回一个可读流以便后续的 Gulp 操作。
const gulp = require('gulp');
const uglify = require('gulp-uglify');
gulp.task('compress', function() {
return gulp.src('src/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/'));
});
在上面的示例中**.pipe(gulp.dest('dist'))
** 将经过压缩的文件写入到 **dist
**文件夹中,并返回一个可读流以供其他 Gulp 操作使用。
5.3 pipe
是将一个 gulp 插件的输出连接到另一个 gulp 插件的输入的方法。是一种在 gulp 中处理文件流的机制。
在 Gulp 中,通常会创建一个任务(task),用于指定需要对哪些文件进行处理,并使用一个或多个 Gulp 插件来处理这些文件。在处理文件时,可以通过 pipe 方法将多个插件连接起来,形成一个处理文件的管道,以实现逐步处理文件的目的。
例如,假设我们有一个名为 "scss" 的任务,需要将 SCSS 文件编译成 CSS 文件,并将编译后的文件保存到指定目录中。在 gulp 中,可以通过以下方式来实现这个任务:
const gulp = require('gulp');
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssnano = require('gulp-cssnano');
gulp.task('scss', function() {
return gulp.src('src/scss/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(cssnano())
.pipe(gulp.dest('dist/css'));
});
5.4 gulp.watch(glob [, options], tasks)
用于监视指定的文件,并在文件发生变化时自动执行相应的任务。
gulp.watch('src/js/*.js', ['js']);
gulp.watch(['src/css/*.css', 'src/sass/**/*.scss'], ['css']);
glob
是需要监听的文件的路径模式
options
: 一个可选的对象,用于配置监视行为。它可以包含以下属性:
cwd
: 指定相对路径的基准目录,默认为当前工作目录。ignoreInitial
: 指定是否在监视开始时执行一次任务,默认为**false
**。events
: 一个字符串或字符串数组,用于指定要监视的事件类型,默认为**['add', 'change', 'unlink']
**,即文件新增、文件变化和文件删除。delay
: 指定延迟多少毫秒后执行任务,默认为200毫秒。
tasks
: 一个字符串或字符串数组,用于指定要执行的任务。
5.5 gulp.series(…tasks)
series
是用于按顺序运行多个任务的方法。当需要在 Gulp 中运行多个任务时,可以使用 series 方法将它们连接起来,以确保它们按照指定的顺序依次运行。
例如,假设我们有一个名为 build
的任务,需要先执行 clean
任务清除旧文件,然后执行 scss
任务将 SCSS 文件编译成 CSS 文件,最后执行 js
任务将 JavaScript 文件压缩成单个文件
const { src, dest, series } = require('gulp');
const del = require('del'); // del 7.0.0版本不支持commonJS
const sass = require('gulp-sass')(require('sass'));
const uglify = require('gulp-uglify');
const concat = require('gulp-concat');
// 清除旧文件
function clean() {
return del(['dist']);
}
// 编译 SCSS 文件
function scss() {
return src('src/scss/*.scss')
.pipe(sass())
.pipe(dest('dist/css'));
}
// 压缩 JavaScript 文件
function js() {
return src('src/js/*.js')
.pipe(uglify())
.pipe(concat('app.min.js'))
.pipe(dest('dist/js'));
}
// 将多个任务连接起来按顺序执行
exports.default = series(clean, scss, js)
5.6 gulp.parallel()
parallel
是用于并行运行多个任务的方法。当需要同时运行多个任务时,可以使用 parallel 方法将它们连接起来,以确保它们同时运行。
例如,假设我们有一个名为 watch
的任务,需要同时监视 SCSS 文件和 JavaScript 文件的变化,并在文件变化时重新编译和压缩文件
const {
src, dest, task, parallel, series, watch
} = require('gulp');
const browserSync = require('browser-sync').create();
const sass = require('gulp-sass')(require('sass'));
const uglify = require('gulp-uglify');
// 编译 SCSS 文件
function scss() {
return src('src/scss/*.scss')
.pipe(sass())
.pipe(dest('dist/css'))
.pipe(browserSync.stream());
}
// 压缩 JavaScript 文件
function js() {
return src('src/js/*.js')
.pipe(uglify())
.pipe(dest('dist/js'))
.pipe(browserSync.stream());
}
// 刷新浏览器
function reload(done) {
browserSync.reload();
done();
}
// 监视 SCSS 文件的变化并自动重新编译
function watchScss() {
return watch('src/scss/*.scss', series(scss, reload));
}
// 监视 JavaScript 文件的变化并自动压缩
function watchJs() {
return watch('src/js/*.js', series(js, reload));
}
// 将多个任务连接起来并行执行
task('watch', parallel(watchScss, watchJs));
在这个任务中,首先通过定义 watchScss、watchJs、scss、js 和 reload 五个任务来分别实现监视 SCSS 文件、监视 JavaScript 文件、编译 SCSS 文件、压缩 JavaScript 文件和刷新浏览器的功能。然后,通过使用 gulp.parallel 方法将监视 SCSS 文件和监视 JavaScript 文件的任务连接起来,并行执行,以实现自动重新编译和刷新浏览器的功能。
6. 拆分gulp配置文件
大型项目中**gulpfile.js
**文件可能会变得越来越复杂,难以维护。为了解决这个问题,我们可以将 **gulpfile.js
**文件拆分成多个文件,每个文件负责一个或多个任务的定义和配置。
目录结构
my-gulp/
tasks/
js.js
images.js
gulpfile.js
// images.js 文件:
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
gulp.task('images', function() {
return gulp.src('src/images/*')
.pipe(imagemin())
.pipe(gulp.dest('dist/images'));
});
// js.js 文件
const gulp = require('gulp');
const uglify = require('gulp-uglify');
gulp.task('js', function() {
return gulp.src('src/js/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
// gulpfile.js 文件
const gulp = require('gulp');
const requireDir = require('require-dir');
requireDir('./tasks');
gulp.task('default', gulp.series('js','images'));
这种拆分方式可以使 **gulpfile.js
**文件变得更加清晰和易于维护。当需要添加或修改任务时,只需要编辑对应的文件即可,而不需要在一个庞大的文件中查找和编辑。