安装
需要先全局安装,相当于安装了环境
npm i gulp -g
然后在项目里需要再次安装
npm i gulp -D
gulp常用API
1.gulp.task(任务名称, 任务处理函数) 创建一个基于流的任务
gulp.task('htmlHandler', function () {
//找到html源文件,进行压缩打包,放入指定目录
})
2.gulp.src(路径) 找到源文件
gulp.src('./a/b.html')
gulp.src('./**') //任意文件
gulp.src('./* /*.html') //同级任意目录下以html结尾的文件
3.gulp.dest(路径) 把一个内容放到指定目录内
gulp.dest('./abc') //把接收到的内容放到abc目录下
4.gulp.watch(路径,任务名称)
gulp.watch('./src/pages/*.html', htmlHandler) //当指定目录下的html文件发生变化时就会执行htmlHandler这个任务
5.gulp.series(任务1,任务2,任务3,任务4,任务5,...) 逐步执行多个任务
6.gulp.parallel(任务1,任务2,任务3,任务4,任务5,...) 并行开始多个任务
7.pipe() 管道函数, 接收当前流,进入下一个流,gulp的精髓所在
gulp.src('./src/pages/index.html').pipe(压缩任务).pipe(转码).pipe(gulp.dest('./dist'))
了解了一些常用的api,我们就可以来开始配置gulp了,首先需要在项目的根目录下创建gulpfile.js
然后我们先来了解一下是gulp是如何工作的
gulp是一个基于流的打包工具,可以理解为完成一个任务需要分成许多步骤,这些步骤需要一步一步走,最终完成任务。
想一想我们打包的过程,以打包压缩css文件为例,首先是找到某个目录下的所有css文件,然后将他们进行压缩,最后保存到dist目录下,别忘了开始要先创建任务
gulp.task('cssHandler', () => {
return gulp.src('./src/assets/css/*.css') //找到源文件
.pipe(cssmin()) //压缩文件
.pipe(gulp.dest('./dist/assets/css/')) //输出到指定目录
// })
先别管那个cssmin,这是gulp的插件,下面就有介绍。这个执行的步骤是不是很清晰明了,但这是gulp@3的写法,现在基本都在用gulp@4版本了,一般按照如下写法
const cssHandler = () => {
return gulp.src('./src/assets/css/*.css') //找到源文件
.pipe(cssmin()) //压缩文件
.pipe(gulp.dest('./dist/assets/css/'))
}
对于3的写法,在命令行输入gulp cssHandler就会进行打包了,而对于4,需要把cssHandler这个模块暴露出来,因为没有用gulp.task包装起来,gulp不认识。
module.exports = { cssHandler }
然后再输入gulp cssHandler就可以完成打包了。这时候可能就会疑惑了,难道每个任务都要自己手打一遍执行吗?当然不是,别忘了还有gulp.parallel()和gulp.series()这两个的区别就是前者是不按照规定顺序,异步执行任务,后者是按顺序同步执行任务。
module.exports.default = gulp.series(cssHandler, xxx, xxx)
这样子就可以一条命令同时执行多个任务了,这里使用属性名为default 的原因是可以简化指令,直接在命令行输入gulp,会自动找到default去执行。
gulp常用的插件
安装 npm i xxx -D
引入 require('xxx')
1. gulp-cssmin //压缩css
直接放到管道执行就好,不需要带参数
2. gulp-autoprefixer //添加css前缀
放管道执行,需要传递参数
{browsers: ['last 2 versions']}
//推荐放在package.json中配置浏览器列表,否则有提示
"browserslist": ['last 2 versions']
//关于跨浏览器和PC和移动端兼容的详见https://github.com/browserslist/browserslist#readme
3.gulp-sass //将sass转成css
还需安装 node-sass
引入和上述两个不一样
const sass = require('gulp-sass')(require('node-sass'))
4.gulp-uglify //压缩js文件
直接放到管道执行就好,不需要带参数
5.gulp-babel //ES6 转 ES5
还需依赖两个包,需要一起安装
@babel/core @babel/preset-env
使用只需导入一个包
const babel = require('gulp-babel')
使用pipe(babel({
presets: ['@babel/env']
}))
6.gulp-htmlmin //压缩html
使用需要配置参数
.pipe(htmlmin({
collapseWhitespace: true, //移除空格换行
removeEmptyAttributes: true, //移除空的原生属性
collapseBooleanAttributes: true, //移除 checked 类似的布尔值, 例如checked="checked"变成checked
removeAttributeQuotes: true, //移除属性上的双引号(单个值时)
minifyCSS: true, //压缩内嵌的css(不能添加前缀)
minifyJS: true, //压缩内嵌js代码 且不认识es6
removeStyleLinkTypeAttributes: true, //移除 style 和 link 标签上的type属性
removeScriptTypeAttributes: true, //移除 script 标签上的type属性
}))
7.gulp-imagemin //压缩图片
一般是不需要压缩的,并且压缩的效率不高,因为是无损压缩
8.del //删除文件(夹), 每次生成dist之前,需要删除
del(['./dist/'])
9.gulp-webserver //启动一个基于node的服务器
.pipe(webserve({
host: 'localhost',
port: '8080',
livereload: true, //文件修改时,自动刷新 热重启
open: './pages/index.html', //默认自动打开哪个文件(从dist目录中)
// proxies:[{ //代理 如果没代理, 就不要写此项
// source: 'xxx', //代理标识符
// target: 'xxx', //代理目标地址
// }],
}))
10.gulp-file-include //引入组件
.pipe(fileInclude({
prefix: '@-@', //自定义标识符
basepath: './src/components/' //组件的目录
}))
html中导入组件, 可以在第二个参数传参,json格式
@-@include('./header.html',{title:'首页'}) //基于basepath后的目录
在header.html(即组件中)使用变量 @-@title, 变量也可用在属性的值中
也可以引入一些固定的模板, 本质就是复制
接下来就是对各种格式的文件进行打包,我就不一一赘述了,可以参考下面的一些配置,还是比较好懂的。
自己的一个gulpfile.js文件
const gulp = require('gulp')
const cssmin = require('gulp-cssmin');
const autoprefixer = require('gulp-autoprefixer');
const sass = require('gulp-sass')(require('node-sass'))
const uglify = require('gulp-uglify');
const babel = require('gulp-babel')
const htmlmin = require('gulp-htmlmin')
const del = require('del');
const webserve = require('gulp-webserver');
const fileInclude = require('gulp-file-include');
//gulp@3的写法
//1. 创建一个打包css的任务
// gulp.task('cssHandler', () => {
// return gulp.src('./src/assets/css/*.css') //找到源文件
// .pipe(cssmin()) //压缩文件
// .pipe(gulp.dest('./dist/assets/css/')) //输出到指定目录
// })
//gulp@4的写法 区别 需要自行导出
// 打包压缩css
const cssHandler = () => {
return gulp.src('./src/assets/css/*.css') //找到源文件
.pipe(autoprefixer()) //处理浏览器和跨平台兼容
.pipe(cssmin()) //压缩文件
.pipe(gulp.dest('./dist/assets/css/'))
}
//打包压缩sass
const sassHandler = () => {
return gulp.src('./src/assets/sass/*.scss') //找到源文件
.pipe(sass())
.pipe(autoprefixer()) //处理浏览器和跨平台兼容
.pipe(cssmin()) //压缩文件
.pipe(gulp.dest('./dist/assets/css/'))
}
//打包压缩js
const jsHandler = () => {
return gulp
.src('./src/assets/js/*.js')
.pipe(babel({
//7写法presets:['es2015']
presets: ['@babel/env'] //babel@8写法
}))
.pipe(uglify()) //压缩
.pipe(gulp.dest('./dist/assets/js/'))
}
//打包压缩html
const htmlHandler = () => {
return gulp
.src('./src/pages/*.html')
.pipe(fileInclude({
prefix: '@-@', //自定义标识符
basepath: './src/components/' //组件的目录
}))
.pipe(htmlmin({
collapseWhitespace: true, //移除空格换行
removeEmptyAttributes: true, //移除空的原生属性
collapseBooleanAttributes: true, //移除 checked 类似的布尔值, 例如checked="checked"变成checked
removeAttributeQuotes: true, //移除属性上的双引号(单个值时)
minifyCSS: true, //压缩内嵌的css(不能添加前缀)
minifyJS: true, //压缩内嵌js代码 且不认识es6
removeStyleLinkTypeAttributes: true, //移除 style 和 link 标签上的type属性
removeScriptTypeAttributes: true, //移除 script 标签上的type属性
}))
.pipe(gulp.dest('./dist/pages/'))
}
//打包images文件
const imgHandler = () => {
return gulp
.src('./src/assets/img/**')
.pipe(gulp.dest('./dist/assets/img/'))
}
//同理,如果有音频和视频,直接放到dist目录下就好,不用压缩
//删除dist目录下的文件
const delHandler = () => {
return del(['./dist/']) //删除dist目录下的所有文件
}
//创建一个启动 服务器 的任务
const webHandler = () => {
return gulp
.src('./dist')
.pipe(webserve({
host: 'localhost',
port: '8080',
livereload: true, //文件修改时,自动刷新 热重启
open: './pages/index.html', //默认自动打开哪个文件(从dist目录中)
// proxies:[{ //代理 如果没代理, 就不要写此项
// source: 'xxx', //代理标识符
// target: 'xxx', //代理目标地址
// }],
}))
}
//创建一个监控任务, 每次修改文件就重新打包
const watchHandler = () => {
gulp.watch('./src/assets/css/*.css', cssHandler)
gulp.watch('./src/assets/sass/*.scss', sassHandler)
gulp.watch('./src/assets/js/*.js', jsHandler)
gulp.watch('./src/assets/img/**', imgHandler)
gulp.watch('./src/pages/*.html', htmlHandler)
}
//配置一个默认任务, 一起执行上面所有任务
//可以用gulp.series() 或者gulp.parallel()
//这两个方法都是返回一个函数, 可以直接调用
//方式1
// gulp.task('default', () => {
// //执行所有任务
// })
// 方式2 采用异步方式
// module.exports.default = gulp.parallel(cssHandler, sassHandler, jsHandler, htmlHandler, imgHandler)
//然后执行 gulp default就好了, 或者当任务名为default时,直接执行 gulp就好
//同步方式+异步方式, 因为删除原来的文件一定要在最前面执行
module.exports.default = gulp.series(
delHandler,
gulp.parallel(cssHandler, sassHandler, jsHandler, htmlHandler, imgHandler),
webHandler,
watchHandler,
)
gulp与webpack的区别
gulp是一个基于流的打包工具,打包的过程就像流水线一样一个步骤一个步骤走下去(当然其中可以同步也可以异步),gulp和webpack一样是依赖于node环境开发的,这时候就不得不做一个比较了,webpack和gulp区别在哪里?
官网的描述我就不再叙述了,两者都是打包工具,然而侧重点有所不同。gulp在使用过程中,很明显能感受到一种自动化的流程,你可以控制其中每一个步骤(task),gulp按照定义顺序执行task,最终把成品输出到打包目录中;而webpack中最凸显的就是一个模块化,你可以下载很多的loader、plugin,需要什么模块就加入什么模块,配置一下就好了,他也能完成打包的工作。而与gulp最大不同的是,webpack可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源,还可以将按需加载的模块进行代码分割,等到实际需要的时候再异步加载,配合单页面(SPA)应用简直天衣无缝,并且可以减少http请求,在大型应用中是迫切需要的。
所以,在单页面应用开发中,首选webpack,而在多页面开发中可以选择gulp,gulp也比较容易上手和编写。
如果有什么错误,欢迎提出和我交流~