gulp是什么?
- 一款node.js应用。
- 是前端开发过程中一种基于流的代码构建工具,帮助优化打包、压缩、合并、git、远程操作......是自动化项目的构建利器。
为什么要用gulp?
如下的前端已经今非昔比,纯粹的HTML+CSS+JS已不足于应付现在的复杂需求,并且随着服务端模块化和自动化慨念的引入,掌握一些自动化工具提高开发效率就变得很重要。
Gulp的安装
npm install gulp -g
全局安装gulp。
如果安装速度太慢,也可以使用国内淘宝的镜像源。
npm install -g gulp --registry=https://registry.npm.taobao.org
为了检验安装完成,我们可以打印测试一下。
gulp -v
开始使用
在目录中初始化npm配置文件。
npm init
{
"name": "stydy-gulp",
"version": "1.0.0",
"description": "gulp,demo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
然后本地安装一次gulp并作为依赖,之前的全局安装是让gulp的命令可以被使用。
npm install gulp --save
安装完成后,当前目录下就会生成node_modules,并将gulp及其依赖的包下载到目录中。
建立gulpfile.js文件
gulp需要一个文件作为它的主文件,在gulp中这个文件叫做gulpfile.js
。新建一个gulpfile.js文件在目录下,之后便是在主文件中定义需求任务了。
gulp中有4个重要的API:gulp.task()
,gulp.src()
,gulp,dest()
,gulp.watch()
。
gulp.task(name[, deps], fn)
定义一个使用 Orchestrator 实现的任务(task)。
name:任务的名字,如果需要在命令中运行某些任务,不要在名字中使用空格。
deps:类型array
,一个包含任务列表的数组,任务会在当前任务运行之前完成。
gulp.task("hello",function() {
console.log("hello");
})
这样就定义了一个最简单的任务,使用gulp hello
让任务运行。
并且gulp也在任务执行时打印了执行开始结束时间等参数供查看任务执行状态等。
一个最基本简单的gulp就运行起来了。
来实现一个拷贝操作的任务。
这里会用到一个新的API。
gulp读写文件:
- gulp.src(globs[, options])
输出(Emits)符合所提供的匹配模式(glob)或者匹配模式的数组(array of globs)的文件。 将返回一个 Vinyl files 的 stream 它可以被 piped 到别的插件中。
globs:类型array
或string
,所要读取的glob或者包含globs的数组。
options:类型object
,通过 glob-stream 所传递给 node-glob 的参数。
- gulp.dest(path[, options])
gulp.dest()方法是用来写文件的
path:string
orfunction
,文件将被写入的路径(输出目录)。也可以传入一个函数,在函数中返回相应路径,这个函数也可以由 vinyl 文件实例 来提供。
options:object options.cwd:
string,默认值:process.cwd(),输出目录的 cwd 参数,只在所给的输出目录是相对路径时候有效。 options.mode:
string,默认值:
0777`,八进制权限字符,用以定义所有在输出目录中所创建的目录的权限。
现在只需简单的理解可以用这个方法来读取和写入你需要操作的文件就行了。
创建一个src文件夹用于模拟生产环境时的文件情况。
在index.html中随意写了些东西。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>将要被拷贝进入dist的文件,模拟拷贝操作</h1>
</body>
</html>
然后在gulpfile.js中写入操作。
gulp.task("dest",function() {
gulp.src("src/index.html")
.pipe(gulp.dest("dist/"));
});
用gulp.src读取文件流,通过pipe API“流”入到dist文件夹内。
当执行任务结束后,目录就会多出一个dist目录和一个index.html文件,一个gulp拷贝操作就这样完成了。
这里要介绍一个文件匹配功能,比如刚才的操作中,如果存在多个html文件需要拷贝,可以这样:
gulp.task("dest",function() {
gulp.src("src/*.html")
.pipe(gulp.dest("dist/"));
});
*.html
表示所有的html文件都会被选中执行。
如果要取所有的html、css、js文件呢?
gulp.task("dest",function() {
gulp.src("src/**/*.*")
.pipe(gulp.dest("dist/"));
});
src/**/*.*
表示:src目录下的任意文件或src的任意目录下的任一文件。
包括多层级的目录使用这个通配符也能拷贝过去。
gulp.src("src/**/*.*","src2/*.*","!src/demo.html")
上面的代码表示,匹配的文件为:
- src目录下任意文件,src目录下任意目录的任意文件
- src2目录下的任意文件。
- 不会选择src目录下的demo.html文件。
关于匹配语法,gulp使用的是node-glob语法。可以根据此查询学习。
还有一个任务名较为特殊。
gulp.task("default",function() {
console.log("默认任务");
})
上面的任务,除了gulp default
能执行外,直接输入gulp
也能执行,稍微注意。
gulp.watch(glob [, opts], tasks)
监视文件,并且可以在文件发生改动时候做一些事情。它总会返回一个 EventEmitter 来发射(emit) change 事件。
glob:一个 glob 字符串,或者一个包含多个 glob 字符串的数组,用来指定具体监控哪些文件的变动。
opts:object
,传给gaze
的参数。
tasks:array
,需要在文件变动后执行的一个或者多个通过 gulp.task() 创建的 task 的名字。
gulp.watch(glob [, opts, cb])
cb(event):
function
,每次变动需要执行的 callback。
gulp.watch('js/**/*.js', function(event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
callback 会被传入一个名为 event 的对象。这个对象描述了所监控到的变动:
event.type:string
,发生的变动的类型:added, changed 或者 deleted。
event.path:string
,触发了该事件的文件的路径。
简单来说,watch方法用于监视文件,当文件发生变化可以执行操作。
gulp.task("dest",function() {
console.log("src目录有变动!");
})
gulp.task("default", function () {
console.log("这是默认任务");
// 当src目录下文件发生变化,自动执行后面任务。
gulp.watch("src/*", ['dest']);
})
输入块出现表明default任务执行完后,任务并没有结束。
现在,对src目录下文件的任意操作都会再次触发dest任务。
随便CRUD一下文件后:
这就是watch方法的一个简单使用。
现在,gulp最基本的4个API的简单介绍使用完成了。
gulp功能型插件
gulp本身不支持任何功能(如编译less,压缩),只提供最基础API。
gulp-less
在src目录下新建一个less目录,创建style.less文件,输入一些test用的less代码做准备。
// src/less/style.css
@baseColor: #f40;
body {
background-color: @baseColor;
div {
height: 100px;
}
}
gulpfile.js的大致逻辑
gulp.task("style",function() {
gulp.src("src/**/*.less")
// 让less编译为css
.pipe(gulp.dest("dist/"));
})
编译less的的插件我们需要重新安装,名字叫:gulp-less
npm install gulp-less --save
// gulpfile.js
const gulp = require("gulp");
const less = require("gulp-less");
gulp.task("style",function() {
gulp.src("src/**/*.less")
// 让less编译为css
.pipe(less())
// 链式调用
.pipe(gulp.dest("dist/"));
})
现在我们在执行任务。
执行后,新创建的dist目录下的less文件夹内,就会出现编译好的css文件了。
body {
background-color: #f40;
}
body div {
height: 100px;
}
也可以使用watch来监视less文件,这样你每更改一次监视的文件,gulp都会立即编译并将更改呈现在你面前。
// gulpfile.js
const gulp = require("gulp");
const less = require("gulp-less");
gulp.task("style",function() {
gulp.src("src/**/*.less")
// 让less编译为css
.pipe(less())
// 链式调用
.pipe(gulp.dest("dist/"));
})
gulp.task("watch",function() {
gulp.watch("src/**/*.less",['style']);
})
less你写啥,cssu也会立即更新。这样就能达到实时编写,实时查看编译代码的效果了。
gulp-connect
gulp创建本地服务器
首先还是安装。
npm install gulp-connect --save
const gulp = require("gulp");
const connect = require("gulp-connect");
// 定义一个HTTP服务器
gulp.task("server",function() {
// 创建一个服务器,默认端口:8080
connect.server({
// 指定根目录
root: "public",
// 文件更改后刷新
livereload: true
})
gulp.watch("public/**/*.*",['reload']);
});
gulp.task("reload",function() {
gulp.src("./public/**/*.*")
.pipe(connect.reload());
});
启动服务器
gulp server
这样就能实时查看效果了,类似的插件其实还有很多。
压缩js、css、img
首先是文件目录:
src文件夹是生产目录,gulp
之前的静态资源都存放在这。
index.html
文件在根目录下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./dist/css/index.min.css">
</head>
<body>
<img src="./dist/img/1.png" alt="" srcset="">
<img src="./dist/img/2.jpg" alt="" srcset="">
<img src="./dist/img/3.jpg" alt="" srcset="">
<script src="./dist/js/main.min.js"></script>
</body>
</html>
可以事先将压缩后的文件引入先写好。
重点看gulpfile.js
// 引用gulp
const gulp = require("gulp");
// gulp plugin
// compress js
const uglify = require("gulp-uglify");
// compress css
const minifycss = require("gulp-minify-css");
// compress image
const imagemin = require("gulp-imagemin");
// gulp concat js
const concat = require("gulp-concat");
// gulp server
const connect = require("gulp-connect");
// gulp rename files
const rename = require("gulp-rename");
// 压缩JS
gulp.task('script', function() {
gulp.src('./src/js/*.js')
// 压缩JS
.pipe(uglify())
// 合并JS
.pipe(concat("main.js"))
// 当前处理的文件都添加.min.js后缀
.pipe(
rename({suffix: '.min'})
)
// 写入文件夹
.pipe(gulp.dest('./dist/js'))
})
// 压缩CSS
gulp.task("css",function() {
gulp.src("./src/css/index.css")
.pipe(minifycss())
.pipe(rename("index.min.css"))
.pipe(gulp.dest("./dist/css/"))
});
// 压缩image
gulp.task("image",function() {
gulp.src("./src/img/*")
.pipe(imagemin({progressive:true}))
.pipe(gulp.dest("./dist/img/"))
})
// auto任务监听文件,如有变化调用任务再次执行
gulp.task("auto",function() {
gulp.watch("./src/js/*.js",["script"]);
gulp.watch("./src/css/*.css",["css"]);
gulp.watch("./src/image/*",["image"]);
})
// 合并运行任务
gulp.task('default',['script','css','image','auto']);
// -----------------------------------开启gulp服务器,并监听文件变化,随时重新压缩更新
// server任务开启服务器
gulp.task("server",function() {
connect.server({
root: "",
livereload: true
})
gulp.watch("./dist/**/*.*",["reload"]);
})
// reload任务重加载server(受watch触发)
gulp.task("reload",function() {
gulp.src("./dist/**/*.*")
.pipe(connect.reload())
})
组合了一些任务函数,并开启一个gulp服务器,使得我们之后在src文件夹下做的任何更改都会触发gulp的watch功能,会重新执行压缩,并可以在服务器上看到更新。
执行gulp
tips:因为gulp.task('default',['script','css','image','auto']);
,default
不需要跟任务名,直接运行。
命令行并没有执行完毕,因为它现在监听着src文件夹下的文件,一旦有更新会立即重新执行一次对应的任务。
压缩成功了,dist目录下出现了更名后被压缩好的文件。
新建一个CLI,执行gulp server
,开启服务器
浏览器打开8080
端口。
成功打开html页面,css、image、js也都正常,且这些文件都已经压缩、合并处理过。
现在回到开发目录src下,修改css文件,更改背景色。
ctrl+s
后,会发现CLI有更新,此时gulp再次将更新后的css文件压缩了一次,同时不需要刷新页面就会呈现修改后的页面。
推荐文章