Home >Web Front-end >JS Tutorial >Detailed introduction to the build tool Gulp
Similar to grunt, gulp is also a build tool, but compared to grunt’s frequent IO operations, gulp’s stream operations can complete the build work faster and more conveniently. Gulp draws on the pipe idea of the Unix operating system. The output of the previous level directly becomes the input of the next level, making the operation very simple. Through this article, we will learn how to use Gulp to change the development process, so as to make development faster and more efficient
If you can use grunt, learn gulp and Not difficult. It mainly includes the following steps
1. Install gulp globally
$ npm install --global gulp
2. Install it as the project’s development dependencies (devDependencies)
$ npm install --save-dev gulp
3. Create a file named gulpfile.js
in the project root directory:
var gulp = require('gulp'); gulp.task('default', function() { // 将你的默认的任务代码放在这});
4. Run gulp:
$ gulp
The default task named default will be run. Here, this The task doesn't do anything.
To execute a specific task alone, please enter gulp <task> <othertask>
Before learning the configuration of gulp, you first need to understand the API involved in gulp
[gulp.src(globs[, options])]
Specify the path of the source file that needs to be processed , returns the current file stream to the available plug-in, the parameters are as follows
globs: The path of the source file matcher that needs to be processed. Type (required): String or StringArray;
Wildcard path matching example:
“src/a.js”:指定具体文件; “*”:匹配所有文件 例:src/*.js(包含src下的所有js文件); “**”:匹配0个或多个子文件夹 例:src/**/*.js(包含src的0个或多个子文件夹下的js文件); “{}”:匹配多个属性 例:src/{a,b}.js(包含a.js和b.js文件)src/*.{jpg,png,gif}(src中所有jpg/png/gif文件) “!”:排除文件 例:!src/a.js(不包含src下的a.js文件);
var gulp = require('gulp'), less = require('gulp-less'); gulp.task('testLess', function () {//gulp.src('less/test/style.less')gulp.src(['less/**/*.less','!less/{extend,page}/*.less']) .pipe(less()) .pipe(gulp.dest('./css')); });
options: Type (optional): Object , has 3 attributes buffer, read, base;
options.buffer:类型:Boolean 默认true,设为false将返回file.content的流且不缓冲文件,处理大文件时有用 options.read: 类型:Boolean 默认:true 设置false,将不执行读取文件操作,返回null; options.base: 类型:String 设置输出路径以某个路径的某个组成部分为基础向后拼接
gulp.src('client/js/**/*.js')//匹配'client/js/somedir/somefile.js'且将`base`解析为`client/js/` .pipe(minify()) .pipe(gulp.dest('build')); // 写入 'build/somedir/somefile.js'gulp.src('client/js/**/*.js', { base: 'client' }) .pipe(minify()) .pipe(gulp.dest('build')); // 写入 'build/js/somedir/somefile.js'
【gulp.dest(path[, options])】
Specify The path to the file output after processing. It can be piped to multiple folders. If a folder does not exist, it will be created automatically
[Note] The path to which the file is written is calculated based on the given relative path and the given target directory. Similarly, the relative path can also be calculated based on the given base
gulp.src('./client/templates/*.jade') .pipe(jade()) .pipe(gulp.dest('./build/templates')) .pipe(minify()) .pipe(gulp.dest('./build/minified_templates'));
The parameters of this method are as follows
path: 类型(必填):String or Function 指定文件输出路径,或者定义函数返回文件输出路径亦可 options: 类型(可选):Object,有2个属性cwd、mode; options.cwd:类型:String 默认:process.cwd():前脚本的工作目录路径 文件输出路径为相对路径会用到 options.mode:类型:String 默认:0777 指定被创建文件夹的权限
【gulp.task( name[, deps], fn)】
Define a gulp task with the following parameters
name: 类型(必填):String 指定任务的名称(不应该有空格); deps: 类型(可选):StringArray,该任务依赖的任务列表 fn: 类型(必填):Function 该任务调用的插件操作
By default, the task will be executed with the maximum number of concurrencies, that is to say , gulp will run all tasks at once and do not wait for anything. If you want to create a serialized task queue and execute it in a specific order, you need to do two things: 1. Give a prompt to tell when the task has been executed; 2. Give another prompt to tell One task depends on the completion of another task.
For this example, assume that there are two tasks, "one" and "two", and you want them to be executed in this order:
In "one", add a prompt to Tell when it will complete: you can return a callback when it is completed, or return a promise or stream, so that the system will wait for it to complete.
In "two", you need to add a hint to tell the system that it needs to rely on the first task to complete
var gulp = require('gulp');// 返回一个 callback,因此系统可以知道它什么时候完成gulp.task('one', function(cb) {// 做一些事 -- 异步的或者其他的cb(err); // 如果 err 不是 null 或 undefined,则会停止执行,且注意,这样代表执行失败了});// 定义一个所依赖的 task 必须在这个 task 执行之前完成gulp.task('two', ['one'], function() {// 'one' 完成后}); gulp.task('default', ['one', 'two']);
gulp.task('testLess', function () {return gulp.src(['less/style.less']) .pipe(less()) .pipe(gulp.dest('./css')); }); gulp.task('minicss', ['testLess'], function () { //执行完testLess任务后再执行minicss任务gulp.src(['css/*.css']) .pipe(minifyCss()) .pipe(gulp.dest('./dist/css')); });
[gulp. watch(glob [, opts], tasks)】
【gulp.watch(glob [, opts, cb])】
The watch method is used to monitor file changes. Once the file is modified, it The specified task will be executed with the following parameters
event.path: 类型:String 触发了该事件的文件的路径
gulp.task('watch1', function () { gulp.watch('less/**/*.less', ['testLess']); });
gulp.watch('js/**/*.js', function(event) { console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); });
var watcher = gulp.watch('js/**/*.js', ['uglify','reload']); watcher.on('change', function(event) { console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); });
[Parameter Marker]
-v 或 --version 会显示全局和项目本地所安装的gulp版本号--require <module path> 将会在执行之前reqiure一个模块。可以使用多个--require--gulpfile <gulpfile path> 手动指定一个gulpfil 的路径,会将CWD设置到该gulpfile所在目录--cwd <dir path> 手动指定CWD。定义gulpfile查找的位置,所有的相应依赖会从这里开始计算相对路径-T 或 --tasks 会显示所指定 gulpfile 的 task 依赖树--tasks-simple 会以纯文本的方式显示所载入的 gulpfile 中的 task 列表--color 强制 gulp 和 gulp 插件显示颜色,即便没有颜色支持--no-color 强制不显示颜色,即便检测到有颜色支持--silent 禁止所有的 gulp 日志
The command line will record where it was run from in process.env.INIT_CW
[Tasks]
Task can be executed through gulp <task> <othertask>. If you only run the gulp command, the registered task named default will be executed. If there is no such task, gulp will report an error
1 , js related plug-ins
[concat] merge files
var gulp = require('gulp'), concat = require('gulp-concat'); gulp.task('testConcat', function () { gulp.src('src/js/*.js') .pipe(concat('all.js'))//合并后的文件名.pipe(gulp.dest('dist/js')); });
[uglify]compress javascript files
var gulp = require('gulp'), uglify= require('gulp-uglify'); gulp.task('jsmin', function () {//压缩src/js目录下的所有js文件//除了test1.js和test2.js(**匹配src/js的0个或多个子文件夹)gulp.src(['src/js/*.js', '!src/js/**/{test1,test2}.js']) .pipe(uglify()) .pipe(gulp.dest('dist/js')); });
[requirejs] Package modular js files
var gulp = require('gulp'), requirejs = require('gulp-requirejs'); gulp.task('script',function(){//将js模块打包成一个文件return requirejs({ baseUrl: 'src/js', paths:{'jquery':'../../dist/js/jquery' }, out:'main.js', name: 'main', exclude: ['jquery'] }) .pipe(gulp.dest('dist/js')); })
[jshint] js code detection
gulp = require('gulp'= require('gulp-jshint''script','src/js/*.js'.pipe(jshint('.jshintrc'.pipe(jshint.reporter('default'
2. CSS related plug-ins
【clean-css】Compress css files
var gulp = require('gulp');var cleanCSS = require('gulp-clean-css'); gulp.task('css', function() { gulp.src('src/css/*.css') .pipe(cleanCSS({compatibility: 'ie8'})) .pipe(gulp.dest('dist/css')); });
【sass】将scss文件编译成css
gulp-sass的安装并不是一个简单的事
1、如果gulp-sass安装不成功,可能出现以下提示
Cannot download https://github.com/sass/node-sass/releases/download/v3.4.2/win32-x64-46_binding.node
这是因为gulp-sass依赖于node-sass,而由于网络原因,node-sass的服务器无法访问,可以有如下解决方法
先使用淘宝的镜像安装node-sass
npm install node-sass --sass-binary-site= http://n pm.taobao.org/mirrors/node-sass/
再安装gulp-sass
npm install gulp-sass
2、安装成功后,也可能无法正确使用。在使用sass编译css文件时,可能会出现' %1 is not a valid win32 application'这样的错误,这是因为gulp-sass依赖于node-sass,而node-sass版本太高,可以安装3.*.*版本,此时,依然要使用淘宝cnpm进行镜像安装
cnpm install node-sass@3.11.0
var gulp = require('gulp'), sass = require('gulp-sass'); gulp.task('sass',function(){ gulp.src('src/sass/*.scss') .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('dist/css')); });
【autoprefixer】根据设置浏览器版本自动处理浏览器前缀
var gulp = require('gulp'), autoprefixer = require('gulp-autoprefixer'); gulp.task('css',function(){ gulp.src('src/css/*.css') .pipe(autoprefixer({ browsers: ['last 2 versions', 'Android >= 4.0'], cascade: true, //是否美化属性值 默认:true 像这样://-webkit-transform: rotate(45deg);// transform: rotate(45deg);remove:true //是否去掉不必要的前缀 默认:true })) .pipe(gulp.dest('dist/css')) });
gulp-autoprefixer的browsers参数详解
last 2 versions: 主流浏览器的最新两个版本 last 1 Chrome versions: 谷歌浏览器的最新版本 last 2 Explorer versions: IE的最新两个版本 last 3 Safari versions: 苹果浏览器最新三个版本 Firefox >= 20: 火狐浏览器的版本大于或等于20 iOS 7: IOS7版本 Firefox ESR: 最新ESR版本的火狐> 5%: 全球统计有超过5%的使用率
【csslint】检测CSS代码
var gulp = require('gulp'), csslint = require('gulp-csslint'); gulp.task('css',function(){ gulp.src('src/css/*.css')//设置css检测规则,并检测css代码.pipe(csslint('.csslintrc'))//对代码进行报错提示 .pipe(csslint.formatter()) });
【concat】合并文件
var gulp = require('gulp');var concat = require('gulp-concat'); gulp.task('css', function() { gulp.src('src/css/*.css') .pipe(concat('all.css')) .pipe(gulp.dest('dist/css')); });
3、HTML相关插件
【htmlmin】压缩html
var gulp = require('gulp');var htmlmin = require('gulp-htmlmin'); gulp.task('html', function() { gulp.src('*.html') .pipe(htmlmin({collapseWhitespace: true})) .pipe(gulp.dest('dist/html')); });
var gulp = require('gulp'), htmlmin = require('gulp-htmlmin'); gulp.task('testHtmlmin', function () {var options = { removeComments: true,//清除HTML注释collapseWhitespace: true,//压缩HTMLcollapseBooleanAttributes: true,//省略布尔属性的值 <input checked="true"/> ==> <input />removeEmptyAttributes: true,//删除所有空格作属性值 <input id="" /> ==> <input />removeScriptTypeAttributes: true,//删除<script>的type="text/javascript"removeStyleLinkTypeAttributes: true,//删除<style>和<link>的type="text/css"minifyJS: true,//压缩页面JSminifyCSS: true//压缩页面CSS }; gulp.src('src/html/*.html') .pipe(htmlmin(options)) .pipe(gulp.dest('dist/html')); });
4、图片相关插件
【imagemin】压缩图片文件
var gulp = require('gulp'), imagemin = require('gulp-imagemin'); gulp.task('testImagemin', function () { gulp.src('src/img/*.{png,jpg,gif,ico}') .pipe(imagemin()) .pipe(gulp.dest('dist/img')); });
var gulp = require('gulp'), imagemin = require('gulp-imagemin'); gulp.task('testImagemin', function () { gulp.src('src/img/*') .pipe(imagemin()) .pipe(gulp.dest('dist/img')); });
【spritesmith】制作雪碧图
[注意]该插件与别的插件有所不同,它的使用方式是gulp.spritesmith,而不是gulp-spritesmith
var gulp = require('gulp');var spritesmith = require('gulp.spritesmith'); gulp.task('img', function() {return gulp.src('src/img/*') .pipe(spritesmith({'imgName':'sprite.png','cssName':'sprite.css','padding':5 //合并时两张图片的距离 })) .pipe(gulp.dest('dist/img')); });
5、文件相关插件
【rename】重命名
var gulp = require('gulp');var rename = require('gulp-rename'); gulp.task('file', function() { gulp.src('src/css/all.css') .pipe(rename('a.css')) .pipe(gulp.dest('dist/css')); });
var gulp = require('gulp');var rename = require('gulp-rename'); gulp.task('file', function() { gulp.src('src/css/all.css') .pipe(rename(function(path){ path.basename += "-min"; path.extname = ".scss"})) .pipe(gulp.dest('dist/css')); });
【clean】删除文件
var gulp = require('gulp');var clean = require('gulp-clean'); gulp.task('clean', function () {return gulp.src('dist/img/*') .pipe(clean()); });
[注意]由于gulp中的任务是同步的,如果并列写,完全可能出现边编译边删除的情况
gulp.task('default', ['clean', 'less', 'images', 'js', 'watch']);//错误
所以需要配置一个异步,非常简单,加个回调
//正确gulp.task('default', ['clean'], function(){ gulp.start('less', 'images', 'js', 'watch'); });
【zip】将文件变成zip压缩文件
[注意]如果gulp.src()的路径设置为'dist/*',则压缩包只包含dist空文件夹,而不包含实际内容
var gulp = require('gulp');var zip = require('gulp-zip'); gulp.task('file', function() { gulp.src('dist/**/*') .pipe(zip('project.zip')) .pipe(gulp.dest('out')); });
6、Hash相关插件
【useref】解析构建块在HTML文件来代替引用未经优化的脚本和样式表
//index.html<!-- build:css /css/all.css --> <link rel="stylesheet" href="src/css/style1.css?1.1.11"> <!-- endbuild -->
var gulp = require('gulp');var useref = require('gulp-useref'); gulp.task('file', function() { gulp.src('*.html') .pipe(useref()) .pipe(gulp.dest('dist')); });
//dist/index.html<link rel="stylesheet" href="/css/all.css?1.1.11">
【rev】给文件名添加hash值
gulp = require('gulp' rev = require('gulp-rev''file', '*.html''dist'
【rev-repalce】重写被gulp-rev重命名的文件名
//index.html<!-- build:css /css/all.css --> <link rel="stylesheet" href="src/css/style1.css?1.1.11"> <!-- endbuild -->
var gulp = require('gulp');var rev = require('gulp-rev');var useref = require('gulp-useref');var revReplace = require('gulp-rev-replace'); gulp.task('file', function() { gulp.src('*.html') .pipe(useref()) .pipe(rev()) .pipe(revReplace()) .pipe(gulp.dest('dist')); });
//index-bc596e88c8.html<link rel="stylesheet" href="/css/all-ef5462562d.css?1.1.11">
7、其他插件
【connect】生成一个服务器
var gulp = require('gulp');var connect = require('gulp-connect'); gulp.task('connect', function() { connect.server(); });
【babel】将ES6代码编译成ES5
var gulp = require('gulp');var babel = require('gulp-babel'); gulp.task('es6', function(){return gulp.src('src/js/*.js') .pipe(babel({ presets: ['es2015'] })) .pipe(gulp.dest('dist/js')); });
在实际开发中,并不会直接使用原生javascript进行开发,使用库或框架开发会更高效,以requiejs和jquery的配置为例。项目目录结构如下
【img】
将'src/img'中的普通图片压缩保存到'dist/img'中,将'src/img/sprite'中的图片制作雪碧图
gulp = require('gulp' imagemin = require('gulp-imagemin' spritesmith = require('gulp.spritesmith''img', gulp.src('src/img/*.{png,jpg,gif,ico}''dist/img' gulp.src('src/img/sprite/*''imgName':'sprite.png''cssName':'sprite.css''padding':5'src/css/temp''default',['img']);
【css】
css部分由sass编译成对应的css存储在'src/css'中,然后,对css文件进行检测、合并、自动添加前缀、压缩后,存储在'dist/css'中
var gulp = require('gulp');var concat = require('gulp-concat');var csslint = require('gulp-csslint');var sass = require('gulp-sass');var autoprefixer = require('gulp-autoprefixer');var cleancss = require('gulp-clean-css');var concat = require('gulp-concat'); gulp.task('css', function() { gulp.src('src/css/sass/*.scss')//将sass编译为css代码 .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('src/css/temp')); gulp.src('src/css/temp/*.css')//设置css检测规则,并检测css代码.pipe(csslint('.csslintrc'))//对代码进行报错提示 .pipe(csslint.formatter())//合并文件.pipe(concat('style.css'))//根据设置浏览器版本自动处理浏览器前缀 .pipe(autoprefixer({ browsers: ['last 2 versions', 'Android >= 4.0'] })) //压缩css文件.pipe(cleancss({compatibility: 'ie8'}))//输出到目标目录.pipe(gulp.dest('dist/css')); }); gulp.task('default',['sass','css']);
【js】
js部分由gulp-requirejs打包为'main.js'之后,进行压缩,最后存储在'dist/js'中,所依赖的框架requirejs和jquery不打包,直接存储在'dist/js'中
var gulp = require('gulp');var requirejs = require('gulp-requirejs');var uglify = require('gulp-uglify'); gulp.task('js', function() {//将js模块打包成一个文件return requirejs({ baseUrl: 'src/js', paths:{'jquery':'../../dist/js/jquery' }, out:'main.js', name: 'main', exclude: ['jquery'] })//压缩文件 .pipe(uglify()) .pipe(gulp.dest('dist/js')); }); gulp.task('default',['js']);
【版本号】
为文件设置版本号
<!-- build:css dist/css/style.css --> <link rel="stylesheet" href="dist/css/style.css?1.1.11"> <!-- endbuild -->
var gulp = require('gulp');var rev = require('gulp-rev');var useref = require('gulp-useref');var revReplace = require('gulp-rev-replace'); gulp.task('file', function() { gulp.src('*.html') .pipe(useref()) .pipe(rev()) .pipe(revReplace()) .pipe(gulp.dest('')); }); gulp.task('default',['file']);
<link rel="stylesheet" href="dist/css/style-0f788265cc.css?1.1.11">
【监控】
/**image**/var gulp = require('gulp');var imagemin = require('gulp-imagemin');var spritesmith = require('gulp.spritesmith'); gulp.task('img', function () {//压缩图片gulp.src('src/img/*.{png,jpg,gif,ico}') .pipe(imagemin()) .pipe(gulp.dest('dist/img'));//制作雪碧图gulp.src('src/img/sprite/*') .pipe(spritesmith({'imgName':'sprite.png','cssName':'sprite.css','padding':5 })) .pipe(gulp.dest('src/css/temp')); gulp.src('src/css/temp/sprite.png') .pipe(gulp.dest('dist/img')); });/**css**/var concat = require('gulp-concat');var csslint = require('gulp-csslint');var sass = require('gulp-sass');var autoprefixer = require('gulp-autoprefixer');var cleancss = require('gulp-clean-css');var concat = require('gulp-concat'); gulp.task('css', function() { gulp.src('src/css/sass/*.scss')//将sass编译为css代码 .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('src/css/temp'));/*}); gulp.task('css', function() { */ gulp.src('src/css/temp/*.css')//设置css检测规则,并检测css代码 // .pipe(csslint('.csslintrc'))//对代码进行报错提示 // .pipe(csslint.formatter())//合并文件.pipe(concat('style.css'))//根据设置浏览器版本自动处理浏览器前缀 .pipe(autoprefixer({ browsers: ['last 2 versions', 'Android >= 4.0'] })) //压缩css文件.pipe(cleancss({compatibility: 'ie8'}))//输出到目标目录.pipe(gulp.dest('dist/css')); });/**js**/var requirejs = require('gulp-requirejs');var uglify = require('gulp-uglify'); gulp.task('js', function() {//将js模块打包成一个文件return requirejs({ baseUrl: 'src/js', paths:{'jquery':'../../dist/js/jquery' }, out:'main.js', name: 'main', exclude: ['jquery'] })//压缩文件 .pipe(uglify()) .pipe(gulp.dest('dist/js')); });/**版本号**/var rev = require('gulp-rev');var useref = require('gulp-useref');var revReplace = require('gulp-rev-replace'); gulp.task('file',['css'],function() { gulp.src('*.html') .pipe(useref()) .pipe(rev()) .pipe(revReplace()) .pipe(gulp.dest('dist/')); });/**监控**/gulp.task('auto',function(){ gulp.watch('src/img',['img']); gulp.watch('src/css/**/*',['css']); gulp.watch('src/js**/*',['js']); gulp.watch('dist/css/*.css',['file']); }) gulp.task('default',['js','img','css','file','auto']);
The above is the detailed content of Detailed introduction to the build tool Gulp. For more information, please follow other related articles on the PHP Chinese website!