Gulp 介绍及插件的使用
基于 node 平台开发的前端构建工具,主要用来设定程序自动处理静态资源的工作。简单的说,gulp就是用来打包项目的。
将机械化操作编写成任务,想要执行机械化操作时执行一个命令行命令任务就能自动执行了。
用机器代替手工,提高开发效率。
中文官网:https://www.gulpjs.com.cn/docs/
Gulp 使用
1.使用 npm install gulp 下载 gulp 库文件
2.在项目根目录下建立 gulpfile.js 文件
3.重构项目的文件夹结构 src 目录放置源代码文件,dist 目录放置构建后文件
4.在 gulpfile.js 文件中编写任务
5.在命令行工具中执行 gulp 任务
Gulp 中提供的方法:
gulp.src(): 获取任务要处理的文件
gulp.dest(): 输出文件
gulp.task(): 建立 gulp 任务
gulp.watch(): 监控文件的变化
语法示例:
const gulp = require('gulp'); // 使用 gulp.task() 方法建立任务 gulp.task('first', () => { // 获取要处理的文件 gulp.src('./src/css/base.css') // 将处理后的文件输出到 dist 目录 .pipe(gulp.dest('./dist/css')); })
项目示例:
1.新建 gulp-demo 文件夹,通过命令行工具安装库文件:
npm install gulp
2.在项目根目录下建立 gulpfile.js 文件
3.在项目根目录下建立 src 文件夹,里面复制粘贴一些文件:
4.在 gulpfile.js 文件中编写任务:
// 引用 gulp 模块 const gulp = require('gulp'); // 使用 gulp.task() 方法建立任务 // 1.任务的名出 // 2.任务的回调函数 gulp.task('first', () => { console.log('第一个gulp任务'); // 1.使用 gulp.src() 获取要处理的文件 gulp.src('./src/css/base.css') // 2.将处理后的文件输出到 dist/css 目录 .pipe(gulp.dest('./dist/css')); });
5.在命令行工具中执行 gulp 任务
我们想执行 gulpfile.js 中的 first 任务,需要安装 gulp 同名的命令行工具:
npm install gulp-cli -g
下面要执行 first 任务,在命令行输入:
gulp first
输入结果:
然后会看到项目根目录下的 dist 目录,多了一个 css 文件夹,里面有个 base.css 文件。
Gulp 插件
我们要处理文件的合并、压缩等操作,接口中没有提供,都放在了插件中。
插件下载:
npm install 插件名 --save
gulp-concat : 合并文件(js/css)
gulp-rename : 文件重命名
gulp-htmlmin:压缩 html 文件
gulp-csso:压缩优化css
gulp-clean-css : 压缩 css
gulp-babel:JavaScrtipt 语法转化
gulp-less : 编译 less
gulp-sass:编译 sass
gulp-uglify : 压缩混淆 js 文件
gulp-file-include:公共文件包含
browsersync:浏览器时间同步
gulp-livereload : 实时自动编译刷新
gulp-connect:热加载,配置一个服务器
gulp-load-plugins:打包插件(里面包含了其他所有插件)
下面我们需要做一个任务示例1:
1、先打开命令行工具,安装 gulp-htmlmin 插件:
npm install gulp-htmlmin --save-dev
2、引用插件
打开 gulpfile.js 文件:
// 引用 gulp-htmlmin 插件 const htmlmin = require('gulp-htmlmin'); // HTML 任务 gulp.task('htmlmin', () => { });
继续编辑 htmlmin 任务:
// 1.html 文件中代码的压缩操作 gulp.task('htmlmin', () => { // 使用 gulp.src() 获取 src 目录下的所有 html 文件 gulp.src('./src/*.html') // 压缩 html 文件中的代码,collapseWhitespace:压缩折叠空格 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('./dist')); });
3、回到命令行工具中执行任务:
gulp htmlmin
然后打开项目下 dist 目录,可以看到2个压缩后的 html 文件,再打开该文件,可以看到压缩后的代码。
4、使用 gulp-file-includ 插件,抽取 html 中的公共代码
安装 gulp-file-includ 插件:
npm install --save-dev gulp-file-include
引用插件:
打开 gulpfile.js 文件:
// 引用 gulp-file-include 插件 const fileinclude = require('gulp-file-include');
添加 fileinclude 代码使用:
// HTML 任务 // 1.html 文件中代码的压缩操作 // 2.抽取 html 文件中的公共代码 gulp.task('htmlmin', () => { // 使用 gulp.src() 获取 src 目录下的所有 html 文件 gulp.src('./src/*.html') // 抽离公共代码 .pipe(fileinclude()) // 压缩 html 文件中的代码,collapseWhitespace:压缩折叠空格 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('./dist')); });
抽取公共代码:
在 src 目录下新建 common 文件夹,创建 header.html 文件,并把头部的公共代码粘贴过来:
<!-- 头部框架开始 --> <div class="header"> <div class="w1100"> <!-- 网站logo开始 --> <h1 class="logo fl"> <a href="index.html"><img src="images/logo.png" alt="黑马程序员"></a> </h1> <!-- 网站logo结束 --> <!-- 网站导航开始 --> <ul class="navigation fr"> <li> <a href="index.html">首页</a> </li> <li> <a href="#">登录</a> </li> </ul> <!-- 网站导航结束 --> </div> </div> <!-- 头部框架结束 -->
再把 default.html 和 article.html 的头部代码部分删除掉,修改为:
@@include('./common/header.html')
回到命令行工具中,重新执行 htmlmin 任务:
gulp htmlmin
打开 dist 目录下的 html 文件,可以查看代码,发现有 header 部分代码。
任务示例2:
less 语法转换为 css 语法、把 css 代码进行压缩。
1、打开 gulpfile.js 文件,建立 Css 任务:
// Css 任务 gulp.task('cssmin', () => { // 使用 gulp.src() 获取 css 目录下的所有 less 文件 gulp.src('./src/css/*.less') });
2、安装 gulp-less 插件:
npm install gulp-less
3、gulpfile.js 文件,引用 gulp-less:
// 引用 gulp-less 插件 const less = require('gulp-less'); // Css 任务 gulp.task('cssmin', () => { // 使用 gulp.src() 获取 css 目录下的所有 less 文件 gulp.src('./src/css/*.less') // 将 less 语法进行转换 .pipe(less()) // 将处理后的文件输出到 dist/css 目录 .pipe(gulp.dest('./dist/css')) });
4、在 src/css 目录下,新建 a.less 文件:
.headers { width: 100px; .logo { height: 200px; background-color: red; } }
5、在命令行执行任务:
gulp cssmin
然后就可以在 dist/css 目录下看到 a.css 文件了。
.headers{ width: 100px } .headers .logo{ height: 200px; background-color: red }
6、把 css 文件进行压缩
怎么把 css 目录下的 less 文件和 css 文件同时选中呢?
语法修改为数组,数组里面可以写多个路径:
// 使用 gulp.src() 获取 css 目录下的所有 less 文件及 css 文件 gulp.src(['./src/css/*.less', './src/css/*.css'])
7、安装 gulp-csso 插件:
npm install gulp-csso --save-dev
8、在 gulpfile.js 文件,引用 gulp-csso:
// 引用 gulp-csso 插件 const csso = require('gulp-csso');
9、实现 css 代码的压缩:
// Css 任务 // 1. less 语法转换 // 2. css 代码压缩 gulp.task('cssmin', () => { // 使用 gulp.src() 获取 css 目录下的所有 less 文件及 css 文件 // gulp.src('./src/css/*.less') gulp.src(['./src/css/*.less', './src/css/*.css']) // 将 less 语法进行转换 .pipe(less()) // 压缩 css 文件中的代码 .pipe(csso()) // 将处理后的文件输出到 dist/css 目录 .pipe(gulp.dest('./dist/css')) });
回到命令行工具中执行任务:
gulp cssmin
在 dist/css 目录下,可以发现压缩后的 css 文件,打开a.css发现代码已经进行了压缩:
.headers{width:100px}.headers .logo{height:200px;background-color:red}
任务示例3:
实现 es6 代码的转换、js 代码的压缩
1、打开 gulpfile.js 文件,建立 Js 任务:
// Js 任务 gulp.task('jsmin', () => { // 使用 gulp.src() 获取 js 目录下的所有 js 文件 gulp.src('./src/js/*.js') });
2、安装 gulp-babel 插件:
npm install --save-dev gulp-babel @babel/core @babel/preset-env
gulp-babel 后面@部分,表示它所依赖的插件。
3、在 gulpfile.js 文件中引用 gulp-babel:
// 引用 gulp-babel 插件 const babel = require('gulp-babel');
4、调用该插件:
// Js 任务 gulp.task('jsmin', () => { // 使用 gulp.src() 获取 js 目录下的所有 js 文件 gulp.src('./src/js/*.js') // es6 转换 .pipe(babel({ // 它可以判断当前代码的运行环境,将代码转换为当前运行环境所支持的代码 presets: ['@babel/env'] })) .pipe(gulp.dest('./dist/js')) });
5、在 src/js 目录下,新建 base.js 文件,写一些 es6 的语法:
const x = 100; let y = 200; const fn = () => { console.log(1234); }
6、在命令行执行任务:
gulp jsmin
然后就可以看到 dist/js 目录下的 base.js 文件:
"use strict"; var x = 100; var y = 200; var fn = function fn() { console.log(1234); };
已经转换为了 es5 的代码。
7、安装 gulp-uglify 插件:
npm install --save-dev gulp-uglify
8、在 gulpfile.js 文件中引用 gulp-uglify:
// 引用 gulp-uglify 插件 const uglify = require('gulp-uglify');
9、调用该插件:
// Js 任务 // 1. ES6 代码转换 // 2. js 代码压缩 gulp.task('jsmin', () => { // 使用 gulp.src() 获取 js 目录下的所有 js 文件 gulp.src('./src/js/*.js') // es6 转换 .pipe(babel({ // 它可以判断当前代码的运行环境,将代码转换为当前运行环境所支持的代码 presets: ['@babel/env'] })) // 压缩 js 文件 .pipe(uglify()) .pipe(gulp.dest('./dist/js')) });
10、回到命令行工具中执行任务:
gulp jsmin
重新打开 dist/js 目录下的 base.js 文件,发现代码已经进行了压缩:
"use strict";var x=100,y=200,fn=function(){console.log(1234)};
任务示例4:
把 src 目录下的 images 文件夹和 lib 文件夹,拷贝到 dist 目录下
1、打开 gulpfile.js 文件,建立 copy 任务:
// 复制文件夹 gulp.task('copy', () => { // 使用 gulp.src() 获取 src 目录下的 images 文件夹 gulp.src('./src/images/*') .pipe(gulp.dest('./dist/images')) // 使用 gulp.src() 获取 src 目录下的 lib 文件夹 gulp.src( './src/lib/*') .pipe(gulp.dest('./dist/lib')) });
2、回到命令行工具中执行任务:
gulp copy
完成后,可以看到 dist 目录下多了 images 文件夹和 lib 文件夹。
任务示例5:
执行一个任务,其他的任务也一起执行
1、打开 gulpfile.js 文件,建立构建任务:
// 构建任务 // 当在命令行执行 default 任务时,会依次执行后面的任务 gulp.task('default', ['htmlmin', 'cssmin', 'jsmin', 'copy']);
2、回到命令行工具中执行任务:
gulp default
这里执行报错:
百度了问题,发现是4.0版本的原因。
3、构建任务的代码要修改为:
// 构建任务 // 当在命令行执行 default 任务时,会依次执行后面的任务 // gulp.series|4.0 依赖顺序执行 // gulp.parallel|4.0 多个依赖嵌套'html','css','js'并行 gulp.task('default', gulp.series(gulp.parallel('htmlmin','cssmin','jsmin','copy')));
4、重新回到命令行工具执行任务:
gulp default
此时执行成功了。
注意:如果说任务名称叫 default,那么执行任务的时候就可以只输入:gulp,会自动地去找一个名字叫 default 的任务。
文件匹配:
往往我们在使用src方法的时候需要输入多个或者一类文件,而不仅仅是某个具体的文件,这时我们就可以使用gulp提供的匹配规则来处理。
"src/file.js"
:单个文件["src/file1,src/file2.js"]
:多个文件*
: 所有文件- **:0或者多个文件夹
- {}:多个属性
- !:排除
示例:
src('src/*.js') // src自身目录所有的js文件,不含后代文件夹中 src('src/a*c.js') src('src/**/*.js') // src目录所有的js文件,含后代文件夹中的 src('src/*.{jpg,png,gif}') // src自身目录下的所有jpg、png和gif文件 src(['**/*.js', '!node_modules/**']) // 所有的js文件,但是node_modules下的除外
注意:src 接收的文件匹配字符串会顺序解释,所以你可以写成这样 gulp.src(['.js', '!b.js', 'bad.js'])
(排除所有以 b 开头的 JS 文件但是除了 bad.js
)
gulp4.0相比3.0有一些改变的地方:
1、gulp4.0分离了cli和核心部分
gulp -v # 输出 CLI version: 2.0.1 Local version: 4.0.2
2、Task
task分为两种:
- Private tasks:配置文件中的一个function,仅能在该文件中使用
- Public tasks:将Private tasks导出,可以供gulp命令执行
const { series, parallel } = require('gulp'); // Private tasks function clean(cb) { // body omitted cb(); } // Private tasks function build(cb) { // body omitted cb(); } exports.build = build; // Public tasks, 执行gulp build exports.default = series(clean, parallel(css, javascript)); // Public tasks, 执行gulp
注意:
在task中,操作完成时,我们必须要通过cb()或者return的方式来告知gulp此任务已完成。
// cb function clean(cb) { del(['dist]); cb(); }); // return function minifyjs() { return src('src/**/*.js') .pipe(minify()) .pipe(dest('dist')); }); function promiseTask() { return new Promise(function(resolve, reject) { // body omitted resolve(); }); });
所以可以把 gulpfile.js 文件整体修改为:
// 引用 gulp 模块 const gulp = require('gulp'); // 引用 gulp-htmlmin 插件 const htmlmin = require('gulp-htmlmin'); // 引用 gulp-file-include 插件 const fileinclude = require('gulp-file-include'); // 引用 gulp-less 插件 const less = require('gulp-less'); // 引用 gulp-csso 插件 const csso = require('gulp-csso'); // 引用 gulp-babel 插件 const babel = require('gulp-babel'); // 引用 gulp-uglify 插件 const uglify = require('gulp-uglify'); // 使用 gulp.task() 方法建立任务 // 1.任务的名出 // 2.任务的回调函数 gulp.task('first', () => { console.log('第一个gulp任务'); // 1.使用 gulp.src() 获取要处理的文件 gulp.src('./src/css/base.css') // 2.将处理后的文件输出到 dist/css 目录 .pipe(gulp.dest('./dist/css')); }); // HTML 任务 // 1. html 文件中代码的压缩操作 // 2. 抽取 html 文件中的公共代码 gulp.task('htmlmin', (cb) => { // 使用 gulp.src() 获取 src 目录下的所有 html 文件 gulp.src('./src/*.html') // 抽离公共代码 .pipe(fileinclude()) // 压缩 html 文件中的代码,collapseWhitespace:压缩折叠空格 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('./dist')); cb(); }); // Css 任务 // 1. less 语法转换 // 2. css 代码压缩 gulp.task('cssmin', (cb) => { // 使用 gulp.src() 获取 css 目录下的所有 less 文件及 css 文件 // gulp.src('./src/css/*.less') gulp.src(['./src/css/*.less', './src/css/*.css']) // 将 less 语法进行转换 .pipe(less()) // 压缩 css 文件中的代码 .pipe(csso()) // 将处理后的文件输出到 dist/css 目录 .pipe(gulp.dest('./dist/css')); cb(); }); // Js 任务 // 1. ES6 代码转换 // 2. js 代码压缩 gulp.task('jsmin', (cb) => { // 使用 gulp.src() 获取 js 目录下的所有 js 文件 gulp.src('./src/js/*.js') // es6 转换 .pipe(babel({ // 它可以判断当前代码的运行环境,将代码转换为当前运行环境所支持的代码 presets: ['@babel/env'] })) // 压缩 js 文件 .pipe(uglify()) .pipe(gulp.dest('./dist/js')) cb(); }); // 复制文件夹 gulp.task('copy', () => { // 使用 gulp.src() 获取 src 目录下的 images 文件夹 return gulp.src('./src/images/*') .pipe(gulp.dest('./dist/images')) // 使用 gulp.src() 获取 src 目录下的 lib 文件夹 return gulp.src('./src/lib/*') .pipe(gulp.dest('./dist/lib')) }); // 构建任务 // 当在命令行执行 default 任务时,会依次执行后面的任务 // gulp.series|4.0 依赖顺序执行 // gulp.parallel|4.0 多个依赖嵌套'html','css','js'并行 gulp.task('default', gulp.series('htmlmin','cssmin','jsmin','copy'));
此时在命令行执行任务后的效果图:(发现前面执行的任务都只是开始,没有告知完成)
3、series:序列(顺序执行)
// task1执行完再执行task2 exports.taskName = series(task1, task2)
4、parallel:并行(同时执行)
// task1和task2同时执行 exports.taskName = parallel(task1, task2)
5、 混用:
exports.taskName = series(clean, parallel(css, javascript))
6、输入与输出
gulp提供了src及dest方法分别来进行文件读入、输出操作,同时提供了pipe管道方法来链式执行其他操作。
const { src, dest } = require('gulp'); // 将src目录下的所有js输出到output目录 exports.default = function() { return src('src/*.js') .pipe(dest('output/')); }
如果我们想在中途添加文件可以采用如下方式:
const { src, dest } = require('gulp'); const uglify = require('gulp-uglify'); exports.default = function() { return src('src/*.js') .pipe(uglify()) .pipe(src('vendor/*.js')) // 添加文件 .pipe(dest('output/')); }
当然我们也可以进行多次输出:
const { src, dest } = require('gulp'); const babel = require('gulp-babel'); const uglify = require('gulp-uglify'); exports.default = function() { return src('src/*.js') .pipe(babel()) .pipe(dest('temp/')) .pipe(uglify()) .pipe(dest('output/')); }
7、监听文件:
我们可以使用watch方法来监听文件的改动,以便在改动时执行相应的处理任务。
const { watch, series } = require('gulp'); function clean(cb) { // body omitted cb(); } function javascript(cb) { // body omitted cb(); } function css(cb) { // body omitted cb(); } exports.default = function() { watch('src/*.css', css); watch('src/*.js', series(clean, javascript)); };
监听方法会返回一共实例,该实例提供了如下几个方法:
watcher.on(eventName, eventHandler)
eventName[string]
:事件名称,可以是add
,addDir
,change
,unlink
,unlinkDir
,ready
,error
, orall
eventHandler[function]
:事件处理函数,该函数接收path和stats两个参数。
const { watch } = require('gulp'); const watcher = watch(['input/*.js']); watcher.on('change', function(path, stats) { console.log(`File ${path} was changed`); }); watcher.on('add', function(path, stats) { console.log(`File ${path} was added`); }); watcher.on('unlink', function(path, stats) { console.log(`File ${path} was removed`); }); watcher.close();
watcher.close()
:关闭文件监听器
watcher.add(globs)
:添加文件到监听器
globs[string|array]
: 要添加的文件
watcher.unwatch(globs)
:移除监听器中的文件
globs[string|array]
: 要移除的文件
常用插件
- gulp-clean:用于清理;
- gulp-notify:用于打印消息文本;
- gulp-rename:用于修改名字;
- gulp-concat:用于合并文件;
- gulp-zip:用于生成一个zip压缩包;
- gulp-minify-css:用于压缩css;
- gulp-autoprefixer:用于给css添加前缀;
- gulp-imagemin:用于给图片进行优化;
- gulp-uglify:用于压缩js;
- amd-optimize:用于amd模块引用编译;
- gulp-import-css:如果css文件是通过import导入的可以使用此插件进行合并优化;
- gulp-rev-replace:用于替换;
- gulp-useref:引入使用build标记,进行替换;
- gulp-rev:生成md5文件名;
- gulp-filter:对文件进行过滤;
- gulp-header:压缩之后将注释写入到文件的头部
- gulp-if:进行逻辑判断
- gulp-size:获取文件大小
- gulp-less:编译less文件
- gulp-sass:编译sass文件
- gulp-file-include:对文件进行引入
- gulp-sourcemaps:生成map文件
- gulp-livereload:自动刷新
- gulp-clean-css:css压缩
- browserSync:启动server并启动热更新
- gulp-plumber : 监测工作流,报错,防止遇到错误时直接退出gulp
- gulp-rev : 文件名添加版本号
- gulp-css-spritesmith:根据css文件自动生成雪碧图
如果要查找gulp插件,一般有两个地方: