什么是Gulp
一个工具包,可以帮你自动化和增加你的工作流
Gulp和Webpack
Gulp
gulp的核心理念是task runner
- 可以定义自己的一系列任务,等待任务被执行
- 基于文件
Stream的构建流 - 我们可以使用
gulp的插件体系来完成某些任务
Webpack
webpack的核心理念是module bundler
webpack是一个模块化的打包工具- 可以使用各种各样的
loader来加载不同的模块 - 可以使用各种各样的插件在
webpack打包的生命周期完成其他的任务
Gulp优缺点
gulp相对于webpack思想更加的简单、易用,更适合编写一些自动化的任务- 目前对于大型项目(
Vue、React、Angular)并不会使用gulp来构建,比如默认gulp是不支持模块化的
Gulp基本使用
安装
//1.安装gulp脚手架
npm install --global gulp-cli
//2.创建文件夹gulp-demo
mkdir gulp-demo
//3.进入文件夹
cd gulp-demo
//4.初始化项目
npm init
创建gulp任务
- 每个
gulp任务都是一个异步的JavaScript函数- 此函数可以接受一个callback作为参数,调用callback函数那么任务会结束;
- 或者是一个返回
stream、promise、event emitter、child process或observable类型的函数;
- 任务可以是
public或者private类型的公开任务(Public tasks)从gulpfile中被导出(export),可以通过gulp命令直接调用私有任务(Private tasks)被设计为在内部使用,通常作为series()或parallel()组合的组成部分;
gulpfile.js
在项目根目录创建个gulpfile.js文件,执行gulp命令后,gulp会去读取gulpfile.js文件,这是gulp的入口文件,所有的指令逻辑处理都在此文件中进行。
当项目体量过大时,可以在根目录内创建个gulpfile.js文件夹,文件夹内部创建index.js,可以在index.js中引入不同的处理模块.
在以前的版本中都是通过gulp.task来创建不同的任务,新版本主要通过exports.xxx来导出任务
function test(cb) {
console.log('test')
cb()
}
exports.test = test;
在控制台输入指令gulp test
如果将exports.test = test改为exports.default=test,在控制台直接输入gulp就可以直接构建了
任务组合series和parallel
gulp提供了两个强大的组合方法:
series():串行任务组合parallel():并行任务组合
// 多个任务的串行执行
exports.seriesTask = series(task1, task2)
// 多个任务的并行执行
exports.parallelTask = parallel(task1, task2)
// 再次组合
exports.composeTask = series(exports.seriesTask, exports.parallelTask)
读取和写入文件
gulp 暴露了 src() 和 dest() 方法用于处理计算机上存放的文件
src()接受参数,并从文件系统中读取文件然后生成一个Node流(Stream),它将所有匹配的文件读取到内存中并通过流(Stream)进行处理- 由
src()产生的流(stream)应当从任务(task函数)中返回并发出异步完成的信号 dest()接受一个输出目录作为参数,并且它还会产生一个Node流(stream),通过该流将内容输出到文件中
exports.default = function() {
return src('./index.html').pipe(dest('output/'))
}
流(stream)所提供的主要的 API 是.pipe() 方法
pipe方法接受一个 转换流(Transform streams)或可写流(Writable streams),转换流或者可写流拿到数据之后可以对数据进行处理,再次传递给下一个转换流或者可写流;
glob文件匹配
src()方法接受一个 glob字符串或由多个 glob字符串组成的数组作为参数,用于确定哪些文件需要被操作(glob 或 glob 数组必须至少匹配到一个匹配项,否则 src() 将报错;)
glob的匹配规则:
(一个星号*):在一个字符串中,匹配任意数量的字符,包括零个匹配;'*.js'(两个星号**):在多个字符串匹配中匹配任意数量的字符串,通常用在匹配目录下的文件;scripts/**/*.js取反:['scripts/**/*.js', '!scripts/lib/']- 由于
glob匹配时是按照每个glob在数组中的位置依次进行匹配操作的 - 所以
glob数组中的取反(negative)glob必须跟在一个非取反(non-negative)的glob后面 - 第一个
glob匹配到一组匹配项,然后后面的取反 glob 删除这些匹配项中的一部分
- 由于
文件转换
如果在流传递过程中,我们希望对文件进行某些处理,可以使用插件
处理js
压缩js、创建sourcemap、重命名js
const {
src, //gulp的内置方法
dest
} = require('gulp');
//重命名js文件
const rename = require('gulp-rename');
const uglify = require('gulp-uglify');
const sourcemaps = require('gulp-sourcemaps');
function javascript() {
return src(['src/js/*.js', '!src/js/*.min.js']) //1.创建一个流,从src读取
//2.创建sourcemap
.pipe(sourcemaps.init())
//pipe为gulp内的一个方法
//用于流之间的链接
// 3. 压缩文件
.pipe(uglify())
//4.重命名,名称后加min.js
.pipe(rename({
extname: '.min.js'
}))
//5.将sourcemap写入
.pipe(sourcemaps.write('./'))
// 6.将文件写入build/js目录下
.pipe(dest('build/js'))
}
exports.javascript = javascript;
控制台输入指令gulp javascript
在build/js下会生成两个文件index.min.js 以及index.min.js.map
处理css
压缩css、创建sourcemap、重命名css
const {
src,
dest
} = require('gulp');
const minifyCSS = require('gulp-clean-css');
const sourcemaps = require('gulp-sourcemaps');
const autoprefixer = require('gulp-autoprefixer');
function css() {
return src('src/css/*.css') //1.流入口文件
//2.创建sourcemap
.pipe(sourcemaps.init())
//3.自动添加浏览器前缀
.pipe(autoprefixer())
// 4.压缩css
.pipe(minifyCSS())
//5.写入sourcemap
.pipe(sourcemaps.write('./'))
//6.写入文件
.pipe(dest('build/css'))
}
exports.css = css;
控制台输入指令gulp css
在build/js下会生成两个文件index.min.css 以及index.min.css.map
处理less
const {
src,
dest
} = require('gulp');
const gulpLess = require('gulp-less');
const minifyCss = require('gulp-clean-css')
const sourcemaps = require('gulp-sourcemaps');
const rename = require('gulp-rename');
function less() {
return src('src/less/**.less') //1.创建输入流
//2.创建sourcemap
.pipe(sourcemaps.init())
//3.less转为css
.pipe(gulpLess())
//4.压缩css
.pipe(minifyCss())
//5.修改名称
.pipe(rename({extname: '.min.css'}))
//6.写入sourcemap
.pipe(sourcemaps.write('./'))
//7.写入文件
.pipe(dest('build/less'))
}
exports.less = less;
处理图片
const {
src,
dest
} = require('gulp');
const imagemin = require('gulp-imagemin')
function image() {
return src('src/images/*.*') // 1. 创建输入流
// 2. 压缩图片
.pipe(imagemin({
progressive: true
}))
// 3. 写入文件
.pipe(dest('build/images'))
}
exports.image = image;
控制台输入指令gulp image
[17:00:07] Using gulpfile F:\gulp-demo\gulpfile.js
[17:00:07] Starting 'image'...
[17:00:19] gulp-imagemin: Minified 3 images (saved 449 kB - 35.5%)
[17:00:19] Finished 'image' after 12 s
可以看到图片的压缩比例
静态服务器
const browserSync = require("browser-sync").create();
function browser() {
browserSync.init({
server: {
baseDir: "./dist",
},
});
// next
}
exports.dev = series(browser)
文件监听
gulp api 中的 watch() 方法主要利用文件系统的监控程序(file system watcher)。
const { watch } = require('gulp')
const task = function() {
return src('./scr/*.js')
.pipe(babel({presets: ['@babel/preset-env']}))
.pipe(terser())
.pipe('./output')
}
watch('./src/js/*.js', task)