gulp的使用
一、了解gulp
1、前端自动化打包工具
gulp是前端自动化打包工具,gulp运行时依赖node环境。使用gulp先手动编辑好步骤,gulp会根据步骤自动对代码进行压缩/混淆/合并。
2、流(stream)/了解/
当你使用代码读取磁盘上的内容时,不是立即把磁盘上的内容给你看,而是处理成我们不认识的二进制形式,当这个二进制的格式被包裹以后,就是一个可以直接使用方法的二进制,我们将这个东西叫做二进制流。
3、gulp版本问题
目前市面上流行两种gulp版本:
-
gulp@3.x.x —>gulp3
== 以前的版本,检测时会出现gulp的版本号,比如你安装的是3.9.1版本,检测时会显示3.9.1 -
gulp@4.x.x —>gulp4
== 最新的版本,版本检测时显示的是cli版本,比如你安装的是4.0.2,检测时显示 cli-version2.2.0
二、安装gulp
因为gulp也是一个全局工具,直接使用npm安装
安装命令:
npm install --global gulp
简写命令:
npm i gulp -g
检测命令:
gulp --version 或者 gulp -v
出现版本号:
CLI version: 2.3.0
Local version: Unknown
卸载gulp
npm uninstall --global gulp
简写:
npm un gulp -g
安装完毕后,就可以使用gulp xxx的相关命令了。
三、使用gulp配置打包步骤
在使用gulp之前需要手动写一个配置文件,用来告诉gulp按照这个配置文件来进行打包,每个项目的配置文件都可能不同,在使用gulp打包每一个项目时,使用的都是当前这个项目的配置文件。
gulp使用前的准备:
1、先准备项目文件夹
- pm 我的整个项目文件夹
+ src/ 我所有的原始代码,开发阶段写的代码
* pages/ 放我所有的html文件
* css/ 放我所有的css文件
* js/ 放我所有的js文件
* images/ 放我所有的图片文件
* lib/ 放我所有的第三方文件
+ package.json 用来记录我项目信息的的描述文件
+ gulpfile.js 当前项目的打包配置文件
2、使用 npm init 初始化一个项目
因为项目中会用到很多第三方工具,使用npm下载第三方工具,最后使用npm init 生成一个package.json文件记录用到的第三方工具,同时记录下项目的信息
3、在项目根目录创建gulpfile.js文件
- 名字必须是 gulpfile.js
- 我们项目的打包配置规则就写在这个文件中
- 在使用gulp 进行打包时会默认读取根目录下的gulpfile.js文件规则进行打包
四、书写打包配置文件
1、书写配置文件需要借助gulp的API来帮我们进行打包
- 在项目中本地安装gulp,作为开发依赖
- 输入指令安装开发依赖: npm install gulp --save-dev
- 在gulpfile.js文件中将这个第三方模块引入
2、准备一个一个书写打包规则
- 因为打包css、打包js和打包html规则都不一样
- 我能需要一个一个的书写
3、执行各种压缩代码的方式
都是借助第三方模块进行压缩,所以我们需要下载导入使用
- gulp-cssmin 是专门用来压缩css文件的
- gulp-uglify 是专门用来压缩js文件的
== 注意:这第三方包不认识es6语法,不能转换压缩es6语法 - gulp-babel 是专门把es6转成es5使用的
== 注意: 这个第三方模块依赖另外两个第三方模块
---- @babel/core 和 @babel/preset-env - gulp-htmlmin 是专门用来压缩html文件的
- del 是专门用来删除目录使用的
- gulp-webserver 是专门用来开发服务器的
4、 书写gulpjfile/s文件
// 在这里书写cyrshop这个项目的打包配置文件
/*
gulp 里面提供的方法
1 src()
== 用来找到你要打包的文件的
== src('你要打包的文件地址')
== 返回值是一个二进制流,就可以继续去调用别的方法
2 pipe()
== 用来帮你做事情的
== pipe(你要做的事情)
== 返回值是一个二进制流,就可以继续去调用别的方法
3 dest()
== 用来写入文件的
== 你要把已经压缩好的代码放在哪一个文件夹里面
== 如果你指定的文件夹不存在,会自动创建一个这个名字的文件夹
4 parallel()
== 用来并行执行多个任务的
== 语法: gulp.parallel(你定义好的任务1,你定义好的任务2,....)
== 他就会把这些任务都给你执行了
== 返回值:是一个任务流
== 只要这个返回值一执行,就能把你准备好的几个任务同时开始执行
5 series()
== 用来逐个执行多个任务的
== 语法: gulp.series(你定义好的任务1,你定义好的任务2,....)
== 返回值:是一个任务流
== 只要这个返回值一执行,就能把你准备好的几个任务逐个执行
== 前一个任务完成再执行后一个任务
6 watch()
== 用来监控文件的编号的
== gulp.watch(你要监控的文件目录,你要执行的任务)
*/
// 1 导入gulp这个第三方模块
const gulp = require('gulp');
// 6 导入gulp-cssmin这个第三方模块
const cssmin = require('gulp-cssmin');
// 9 导入gulp-autoprefixer这个第三方模块
const autoprefixer = require('gulp-autoprefixer');
// 10 导入gulp-uglify这个第三方模块
const uglify = require('gulp-uglify');
// 13 导入gulp-babel这个第三方模块
const babel = require('gulp-babel');
// 14 导入gulp-htmlmin这个第三方模块
const htmlmin = require('gulp-htmlmin');
// 16 导入del这个第三方模块
const del = require('del');
// 18 导入gulp-webserver这个第三方模块
const webserver = require('gulp-webserver');
// 2 书写一个移动lib文件夹的方法
const libHandler = ()=>{
return gulp.src('./src/lib/**').pipe(gulp.dest('./dist/lib'))
}
// 4 书写一个移动images文件夹的方法
const imagesHandler = ()=>{
return gulp.src('./src/images/**').pipe(gulp.dest('./dist/images'))
}
// 7 书写一个压缩然后移动css文件的方法
const cssHandler = ()=>{
return gulp.src('./src/css/**')
.pipe(autoprefixer())
.pipe(cssmin())
.pipe(gulp.dest('./dist/css'))
}
// 11 书写一个压缩然后移动js文件的方法
const jsHandler = ()=>{
return gulp.src('./src/js/**')
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(uglify())
.pipe(gulp.dest('./dist/js'))
}
// 14 书写一个压缩然后移动html文件的方法
const htmlHandler = ()=>{
return gulp.src('./src/pages/**')
.pipe(htmlmin({
// 压缩空格
collapseWhitespace: true ,
// 移除属性上的引号
removeAttributeQuotes:true,
// 移出注释
removeComments:true,
// 把页面的style里面的css样式也去除空格
minifyCSS:true,
// 把页面的script里的js也去除空格
minifyJS:true,
// 把值为布尔值的属性简写
collapseBooleanAttributes:true
}))
.pipe(gulp.dest('./dist/pages'))
}
// 17 书写一个删除dist文件夹的方法
const delHandler = ()=>{
return del(['./dist'])
}
// 19 书写一个配置服务器的任务
// 再开发过程中直接把我写的代码再服务器上打开
// 因为我要一边写一边修改一边测试
// 因为gulp是基于node运行
// 这里就是使用node给我们开启一个服务器,不是apache也不是nginx
// 自动刷新: 当dist目录里面的代码有改变以后,就会自动刷新浏览器
const webserverHandler = ()=>{
// 要把页面再服务器上打开
return gulp.src('./dist') // 找到我要打开的页面的文件夹,把这个文件夹作为网站根目录
.pipe(webserver({
port:8080, // 端口号,0-65535,尽量不要用0-1023
open:"./pages/index.html",//你默认要打开的首页,从dist下面的目录开始书写
livereload:true, // 自动刷新浏览器-热重启
proxies:[
// 每一个代理配置就是一个对象
{
source:"/aaa" ,// 源,你的代理表示符
// 你直接请求下面的地址压根拿不到东西,因为跨域了
target:"https://way.jd.com/jisuapi/weather"
}
]
}))
}
// 20 自动监控文件
// 监控src下面的文件,只要一修改就执行对应的任务
// 比如src下面的css文件夹,只要里面的文件一修改,就执行cssHandler任务
// 比如src下面的js文件夹,只要里面的文件一修改,就执行jsHandler任务
const watchHanlder = ()=>{
gulp.watch('./src/css/*.css',cssHandler);
gulp.watch('./src/js/*.js',jsHandler);
gulp.watch('./src/pages/*.html',htmlHandler);
gulp.watch('./src/images/**',imagesHandler);
gulp.watch('./src/lib/**',libHandler)
}
// 3 导出libHandler这个方法
// libHandler就是要执行的方法
// // 这个任务的名称就叫做lib
// // 使用指令: gulp 任务名 就可以执行这个任务
// module.exports.lib = libHandler;
// // 5 导出imagesHandler这个方法
// module.exports.images = imagesHandler;
// // 8 导出cssHandler这个方法
// module.exports.css = cssHandler;
// // 12 导出jsHandler这个方法
// module.exports.js = jsHandler;
// // 15 导出htmlHandler这个方法
// module.exports.html = htmlHandler;
// // 18 导出delHandler这个方法
// module.exports.del = delHandler;
// 把上面的方法导出成一个默认任务
// 当我将来再命令行执行gulp default的时候,就会自动把我写在series里面的几个任务都执行了
// 小细节:当你命令行执行gulp default的时候,可以不写default
// 你再命令行执行gulp,其实就是执行gulp default
module.exports.default = gulp.series(
delHandler,
gulp.parallel(libHandler,imagesHandler,cssHandler,jsHandler,htmlHandler),
webserverHandler,
watchHanlder
)
编辑package.json文件,表明项目适配的浏览器版本
{
"name": "cyrshop",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.14.3",
"@babel/preset-env": "^7.14.2",
"del": "^6.0.0",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^7.0.1",
"gulp-babel": "^8.0.0",
"gulp-cssmin": "^0.2.0",
"gulp-htmlmin": "^5.0.1",
"gulp-uglify": "^3.0.2",
"gulp-webserver": "^0.9.1"
},
"browserslist":[
"last 2 versions",
"iOS>7",
"Firefox < 20",
"last 2 Explorer versions"
]
}
5、拓展
5.1 npx
npx可以把本地安装的包在项目中当全局命令使用,
例如在全局安装的情况下运行gulp是 gulp xxx,在本地安装当全局命令使用是 npx gulp xxx
5.2 开发依赖
我本地安装了gulp,jquery后,在package.json中都有记录,但这两个第三方工具是有区别的:
- gulp是为了我的项目代码压缩使用
- jquery使我们需要在项目中使用的第三方
- 当代码压缩完毕上线以后,gulp就不需要了,而jquery还是需要的
所以在记录的时候最好分开记录,现在都是记录在deoendcies中,对于一些开发依赖,我们下载时使用命令 npm install --save-dev 包名 ,简写 npm i -D 包名,这个方式下载和npm install 包名 下载没有区别,唯一区别就是在package.json中记录的位置不同,这个方式下载的包是记录在devDependencies中。
五、gulpfile.js文件书写
// 1 导入第三方模块
const gulp = require('gulp');
const cssmin = require('gulp-cssmin'); // 压缩css
const autoprefixer = require('gulp-autoprefixer'); // 给css的属性加前缀
const htmlmin = require('gulp-htmlmin'); // 压缩html
const uglify = require('gulp-uglify'); // 压缩js
const babel = require('gulp-babel'); // es6转es5语法的
const del = require('del');// 删除文件的
const webserver = require('gulp-webserver');//开启服务的
// 2 书写任务
// 2-1 移动lib文件夹
const libHandler = ()=>{
return gulp.src('./src/lib/**')
.pipe(gulp.dest('./dist/lib'))
}
// 2-2 移动images文件夹
const imagesHandler = ()=>{
return gulp.src('./src/images/**')
.pipe(gulp.dest('./dist/images'))
}
// 2-3 压缩css文件
const cssHandler = ()=>{
return gulp.src('./src/css/*.css')
.pipe(autoprefixer())
.pipe(cssmin())
.pipe(gulp.dest('./dist/css'))
}
// 2-4 压缩html文件
const htmlHandler = ()=>{
return gulp.src('./src/pages/**')
.pipe(htmlmin({
collapseBooleanAttributes:true,
collapseWhitespace:true,
removeComments:true,
removeAttributeQuotes:true,
minifyJS:true,
minifyCSS:true
}))
.pipe(gulp.dest('./dist/pages'))
}
// 2-5 压缩js文件
const jsHandler = ()=>{
return gulp.src('./src/js/**')
.pipe(babel({
presets:['@babel/env']
}))
.pipe(uglify())
.pipe(gulp.dest('./dist/js'))
}
// 2-6 删除dist文件夹
const delHandler = ()=>{
return del(['./dist'])
}
// 2-7 开启热更新的服务器
const webserverHandler = ()=>{
return gulp.src('./dist')
.pipe(webserver({
port:8080,
open:"./pages/index.html",
livereload:true,
proxies:[
{
source:'/aaa',
target:"https://way.jd.com/jisuapi/weather"
}
]
}))
}
// 2-8 监测src里面的文件
const watchHandler = ()=>{
gulp.watch('./src/css/*.css',cssHandler)
gulp.watch('./src/js/*.js',jsHandler)
gulp.watch('./src/pages/**',htmlHandler)
gulp.watch('./src/lib/**',libHandler)
gulp.watch('./src/images/**',imagesHandler)
}
// 3 导出默认任务
module.exports.default = gulp.series(
delHandler,
gulp.parallel(cssHandler,jsHandler,htmlHandler,libHandler,imagesHandler),
webserverHandler,
watchHandler
)