gulp简介
本内容仅针对复习gulp知识,如果你还没有学习过gulp,建议先进行学习
安装好node.js,使用npm命令安装gulp
安装
$ npm install --global gulp
检测
gulp --version
CLI version:2.3.0
Local version:Unknown
卸载
$ npm uninstall --global gulp
Q:gulp是什么?gulp能干嘛?
A:前端打包工具;打包:把文件压缩,整合,移动,混淆
gulp是依赖于node环境进行开发,底层封装的内容就是node里面的读写文件
gulp基本使用
- 在你的项目下,包含src和dist两个源代码和输出的目录。
- 在你的项目下,创建一个gulpfile.js
- 在你的项目下,再次安装gulp
gulp注意事项
在你的项目下再次安装gulp,是以第三方模块的形式出现的
全局依赖环境gulp
- 一台电脑安装一次,以后使用就可以
- 在命令行提供gulp xxx的能力
- 指令
$ npm install --global gulp
项目依赖第三方gulp
- 每一个项目都要安装一次
- 作为第三方包出现,在你导入后,可以使用gulp.xxx方法
- 切换到项目目录,输入指令
$ npm install gulp
常用API
因为gulp是依赖于node环境运行的将来的运行也是以node为基础运行的书写gulpfile.js文件就按照node的模块化语法进行书写(CommonJS)
可以使用node gulpfile.js
命令查看常用API,使用API的前提是下载gulp第三方,导入后使用
1. gulp.task()
语法:gulp.task(任务名称,任务处理函数)
作用:创建一个基于流的任务
举例:gulp.task('htmlHandler',function(){})
2. gulp.src()
语法:gulp.src(路径信息)
作用:找到源文件
举例:gulp.src('./a/b.html') --找到指定的文件
gulp.src('./a/*.html') --指定目录下的指定后缀文件
gulp.src('./a/**') --a目录的下的所有文件
gulp.src('./a/** /*') --a目录下所有子目录里面的所有文件
gulp.src('./a/** /*.html') --a目录下所有子目录里面的所有html文件
3. gulp.dest
语法:gulp.dest(路径信息)
作用:把一个内容放进指定目录
例子:gulp.dest('./abc') --把接收到的内容放进abc目录
4. gulp.watch()
语法:gulp.watch(路径信息,任务名称)
作用:监控指定目录下的文件,一旦发生变化,重新执行后面的任务
例子:gulp.watch('./src/*.html',htmlHandler) --当指定目录下的html目录发生变化时就执行htmlHandler这个任务
5. gulp.series()
语法:gulp.series(任务1,任务2,任务3,...)
作用:逐渐执行多个任务,前一个任务结束,第二个任务开始
6. gulp.parallel()
语法:gulp.parallel(任务1,任务2,任务3,...)
作用:并行开始多个任务
7. pipe()
作用:管道函数,所有gulp API都是基于流,接收当前流,进入下一个流过程的管道函数
例子:gulp.src().pipe(压缩任务).pipe(转码).pipe(gulp.dest('abc'))
添加css任务
gulp插件
gulp的各种插件就是用来执行各种各样的压缩混淆转码任务的
gulp-cssmin
- 下载:
npm i gulp-cssmin -D
- 导入:
const cssmin = require('gulp-cssmin')
- 导入以后得到一个处理流文件的函数,直接在管道函数执行即可
- 下载:
gulp-autoprefixer
- 下载:
npm i gulp-autoprefixer -D
- 导入:
const autoPrefixer = require('gulp-autoprefixer')
- 导入以后得到一个处理流文件的函数直接再管道函数里面使用,需要传递参数
- 下载:
const gulp = require('gulp')
//导入gulp-cssmin
const cssmin = require('gulp-cssmin')
//导入autoPrefixer
const autoPrefixer = require('gulp-autoprefixer')
//创建一个打包css的任务 gulp@3的标准书写语法
gulp.task('cssHandler',function(){
return gulp
.src('./src/css/*.css')//找到源文件
.pipe(autoPrefixer({ browsers:['last 2 versions']}))//兼容,自动添加前缀
//或者你在package.json加入另外的处理
"browserslist":[
"last 2 versions",
"FireFox < 20",
"IOS < 7"
]
//还有其他更多的写法可以去看https://github.com/browserslist/browserslist
//代码就可以变成
.pipe(autoPrefixer())
.pipe(cssmin())//压缩css
.pipe(gulp.dest('./dist/css'))//把压缩好的内容放到指定目录下
})
//创建一个打包css的任务 gulp@4的标准书写语法,需要在文件里面把这个函数名导出
const cssHandler = function(){
return gulp
.src('./src/css/*.css')
.pipe(cssmin())
.pipe(gulp.dest('./dist/css/'))
}
//导出任务
module.exports.cssHandler = cssHandler
接下来,执行一个gulp配置好的任务,例如在vscode编辑器中,打开终端,输入命令 $ gulp 任务名称
添加sass/scss任务
下载gulp-sass插件,用来将sass/scss转换为css
使用命令npm i gulp-sass -D
下载,很容易报错,基本下载不成功,因为gulp-sass依赖另一个第三方node-sass ,node-sass很难下载成功,以前都是再一个地方下载,后来 node-sass 自己单独有一个下载地址,如果你不进行单独的node-sass下载地址配置,就很容易失败
解决: 给 node-sass 单独配置一个下载地址,下载node-sass从这个单独的地址下载,下载其他的东西还是统一地址
命令:
$ set SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass
$ npm i node-sass -D
$ npm i gulp-sass -D
const gulp = require('gulp')
//导入gulp-cssmin
const cssmin = require('gulp-cssmin')
//导入gulp-sass
const sass = require('gulp-sass')
const sassHandler = function(){
return gulp
.src('./src/sass/*.sass')
.pipe(sass( ))
.pipe(cssmin())
.pipe(gulp.dest('./dist/css/'))
}
//导出任务
module.exports.sassHandler = sassHandler
添加js任务
安装gulp-uglify,用于把js文件压缩
命令:npm i -D gulp-uglify
const gulp = require('gulp')
const uglify = require('gulp-uglify')
const babel = require('gulp-babel')
const jsHandler = function(){
return gulp
.src('./src/js/*.js')
//.pipe(babel({presets:['@babel/env']}))//转换ES语法
.pipe(uglify())//压缩js
.pipe(gulp.dest('./dist/js/'))
}
//导出任务
module.exports.jsHandler = jsHandler
gulp-babel专门进行ES6转ES5的插件,安装还需要安装另外两个依赖
命令:
$ npm i -D gulp-babel
$ npm i -D @babel/core
$ npm i -D @babel/preset-env
添加html任务
安装gulp-htmlmin
下载:npm i -D gulp-htmlmin
const gulp = require('gulp')
const htmlmin = require('gulp-htmlmin')
const htmlHandler = function(){
return gulp
.src('./src/html/*.html')
.pipe(htmlmin({
collapseWhitespace:ture,//清除空格
removeEmptyAttributes:true,//表示移除空的属性(仅限原生)
collapseBooleanAttributes:true,//移除checked类似的布尔值属性
removeAttributeQuotes:true,//移除属性上的双引号
minifyCSS:true,//压缩内嵌式css代码(仅基本压缩,不能添加前缀)
minifyJS:true,//压缩内嵌式js代码(基本压缩,不能转码)
removeStyleLinkTypeAttributes:true,//移除style和link标签上的type属性
removeScriptTypeAttributes:true,//移除Script标签上的type属性
}))
.pipe(gulp.dest('./dist/html/'))
}
//导出任务
module.exports.htmlHandler = htmlHandler
其他
配置国内镜像解决下载慢的问题
默认情况下,npm 从一个名为 https://registry.npmjs.org/ 的服务器上下包
腾讯云镜像
$ npm config set registry https://mirrors.cloud.tencent.com/npm/
淘宝镜像
$ npm config set registry https://registry.npm.taobao.org/
华为云镜像
$ npm config set registry https://mirrors.huaweicloud.com/repository/npm/
gulp插件
图片压缩插件gulp-imagemin(无损压缩,最高7级)
命令:npm i -D gulp-imagemin
使用:.pipe(imagemin()),
删除任务插件del
命令:npm i -D del
作用:删除文件目录
使用:del(['./dist/'])
创建监控任务
const watchHandler = function (){
gulp.watch('./src/css/*.css',cssHandler)
}
配置默认任务
要么使用gulp.series(),要么使用glup.parallel()
module.exports.default = gulp.parallel(,,,)
用不上的,可自查
gulp-file-include,配置代理,gulp-webserver
Gulp进阶教程
在 Gulp 中,cb()
函数(通常称为 "callback" 函数)用于告诉 Gulp 当前任务已经完成。当你调用cb()
时,Gulp 会继续执行下一个任务。
例如在 buildMainJs 函数中,cb()
是在设置文件流之后立即调用的:
export const buildMainJs = (cb) => {
src([paths.lib.js, paths.js.src, paths.js.exclude]) // 找到源文件
.pipe(concat("MainJs.js")) // 合并
.pipe(uglify()) // 压缩js
.pipe(rename({ basename: "script", suffix: ".min", extname: ".js" }))
.pipe(dest(paths.dist)); // 设置保存位置;
cb(); // 立即调用cb
};
这样做的问题是异步操作未完成,因为src()
和后续的.pipe()
方法是异步的,调用 cb()
会在文件流开始处理后立即返回。这意味着 Gulp 认为当前任务已经完成,而实际上文件处理可能还没有完成。
下一个任务提前开始:如果你在 buildJs 中使用 series 或 parallel 来执行多个任务,调用 cb()
会导致下一个任务(例如 buildCss 或 buildJs)在文件处理完成之前就开始执行,从而可能导致错误或不一致的结果。
解决方案:为了确保所有异步操作都正确完成,你应该返回文件流,而不是调用 cb():
export const buildMainJs = () => {
return src([paths.lib.js, paths.js.src, paths.js.exclude]) // 找到源文件
.pipe(concat("MainJs.js")) // 合并
.pipe(uglify()) // 压缩js
.pipe(rename({ basename: "script", suffix: ".min", extname: ".js" }))
.pipe(dest(paths.dist)); // 设置保存位置;
};
通过返回流,Gulp 会在文件处理完成后自动继续执行下一个任务,这样就不会出现任务顺序错误的问题。