gulp入门指南
2016-08-19 11:47 西不肚 阅读(92) 评论(0) 收藏 举报2014年4月21日更新,使用更新的 2014年8月11日更新,使用取代原有的,更新 2015年5月20日更新,更新语句 2015年11月2日更新,更新语句 2015年1月16日更新,舍弃,改用
gulp-livereload delgulp-cleangulp-livereload gulp-ruby-sassdelgulp-minify-cssgulp-cssnano
让一让Grunt,有个新的建构工具来了。Gulp 是一种直觉的、code-over-configuration、串流的建构系统,它非常的快。
为什么我该感到兴趣?好问题。Gulp的code-over-configuration不只容易撰写,也更容易阅读及维护。
Glup使用node.js的串流(streams),让建构更加快速,你再也不需要写到磁碟暂存档或目录。如果你想更了解有关串流--虽然不是必要的--你可以阅读这篇文章。Gulp让你用一个或多个来源档案作为输入(input),串流(pipe)这些档案经过一些外挂(plugins),最后获得输出的结果,而非逐一配置每个外挂的输入与输出--就像Grunt。让我们来看看分别在Gulp及Grunt基本建构Sass的示范:
Grunt:
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
'dist/assets/css/main.css': 'src/styles/main.scss',
}
}
},
autoprefixer: {
dist: {
options: {
browsers: [
'last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'
]
},
src: 'dist/assets/css/main.css',
dest: 'dist/assets/css/main.css'
}
},
grunt.registerTask('styles', ['sass', 'autoprefixer']);
Grunt 需要配置各个外挂,指定来源与目的路径。例如,我们将一个档案作为Sass 外挂的输入,并储存其输出结果。同样在设置Autoprefixer 里,需要将Sass 的输出结果作为输入,产生出另一个档案。来看看同样在Gulp 里的配置:
Gulp:
gulp.task('sass', function() {
return sass('src/styles/main.scss', { style: 'expanded' })
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
.pipe(gulp.dest('dist/assets/css'))
});
Gulp 我们只需要输入一个档案即可。经过Sass 外挂的处理,再串流到Autoprefixer 外挂,取得最终的档案。这样的流程可加快建构程序,省去不必要的档案读取及写出,只需要最终的一个档案。
所以,你有兴趣了,接下来呢?让我们来安装gulp 并且建立一个基本的gulpfile,包含几个核心任务来作为开始吧。
安装gulp
在我们钻研设置任务之前,需要先安装gulp:
$ npm install gulp -g
这会将gulp安装到全域环境下,让你可以存取gulp的CLI 。接着,我们需要安装在本地端专案。cd切换到你的专案根目录,执行下述指令(请先确定你已有package.json档):
$ npm install gulp --save-dev
上述指令将gulp安装到本地端的专案内,并纪录于package.json内的devDependencies属性。
安装gulp 外挂
接着安装一些外挂,以便执行下列任务:
- 编译Sass(gulp-ruby-sass)
- Autoprefixer(gulp-autoprefixer)
- 缩小化(minify)CSS(gulp-cssnano)
- JSHint(gulp-jshint)
- 串接(gulp-concat)
- 丑化(Uglify)(gulp-uglify)
- 压缩图档(gulp-imagemin)
- 即时重整(LiveReload)(gulp-livereload)
- 快取图片,只有变更的图档才会压缩处理(gulp-cache)
- 通知更动(gulp-notify)
- 清除档案,有个干净的建构环境(del)
执行下列指令来安装这些外挂:
$ npm install gulp-ruby-sass gulp-autoprefixer gulp-cssnano gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-livereload gulp-cache del --save-dev
指令将会安装必要的外挂,并纪录于package.json内的devDependencies属性。完整的gulp外挂清单可以在这里找到。
载入外挂
接下来,我们需要建立一个gulpfile.js档案,并且载入这些外挂:
var gulp = require('gulp'),
sass = require('gulp-ruby-sass'),
autoprefixer = require('gulp-autoprefixer'),
cssnano = require('gulp-cssnano'),
jshint = require('gulp-jshint'),
uglify = require('gulp-uglify'),
imagemin = require('gulp-imagemin'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
notify = require('gulp-notify'),
cache = require('gulp-cache'),
livereload = require('gulp-livereload'),
del = require('del');
呼!看起来比Grunt 有更多的事要做,对吧?Gulp 外挂跟Grunt 外挂有些许差异-- 它被设计成只做一件事并且做好这一件事。例如;Grunt 的imagemin 利用快取来避免重复压缩已经压缩好的图片。在Gulp 中,这必须透过一个快取外挂来达成,当然,快取外挂也可以拿来快取其他东西。这让建构过程中增加了额外的弹性层面。蛮酷的,哼?
我们也可以像Grunt一样自动载入所有已安装的外挂,但这不在此文章目的,所以我们将维持在手动的方式。
建立任务
编译Sass、Autoprefix 及缩小化
首先,我们设置编译Sass 。我们将编译Sass,接着通过Autoprefixer,最后储存结果到我们的目的地。最后产生一个缩小化的.min版本、自动重新整理页面并且通知任务已经完成:
gulp.task('styles', function() {
return sass('src/styles/main.scss', { style: 'expanded' })
.pipe(autoprefixer('last 2 version'))
.pipe(gulp.dest('dist/assets/css'))
.pipe(rename({suffix: '.min'}))
.pipe(cssnano())
.pipe(gulp.dest('dist/assets/css'))
.pipe(notify({ message: 'Styles task complete' }));
});
再继续下去之前,一个小小的说明。
gulp.task('styles', function() { ... )};
这个gulp.taskAPI用来建立任务。可以透过终端机输入$ gulp styles指令来执行上述任务。
return sass('src/styles/main.scss', { style: 'expanded' })
这是新的gulp-ruby-sassAPI,这里我们定义了来源档案,并且带入任意选项。许多其他外挂,你会用gulp.srcAPI,稍 后我们将会在此文章中用到(return gulp.src(...))。它允许使用glob样式,例如/**/*.scss比对多个符合的档案。传回的串流(stream)让它成为非同步机制,在我们收到完成通知之前,必须确保该任务已经全部完成。
.pipe(autoprefixer('last 2 version'))
我们使用pipe()来串流来源档案到另个外挂。外挂的选项通常在它们各自的Github页面中找到。上面列表中我有 留下各个外挂的连结,让你方便使用。串流是可串链的,所以你可以串流各式各样的外挂在上面。
.pipe(gulp.dest('dist/assets/css'));
这个gulp.dest()API是用来设定目的路径。一个任务可以有多个目的地,一个用来输出扩展的版本,一个用来输出缩小化的版本。这个在上述的styles任务中已经有展示。
建议阅读gulp的API文件,以了解这些函式方法。它们并不像看起来的那样可怕!
JSHint、拼接及缩小化JavaScript
希望你现在对于如何建立一个新的gulp 任务有好想法。接下来,我们将设定脚本任务,包括lint、拼接及丑化:
gulp.task('scripts', function() {
return gulp.src('src/scripts/**/*.js')
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter('default'))
.pipe(concat('main.js'))
.pipe(gulp.dest('dist/assets/js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('dist/assets/js'))
.pipe(notify({ message: 'Scripts task complete' }));
});
这里我们使用gulp.srcAPI来指定输入来源档案。一件事提醒,我们需要指定JSHint一个reporter。这里我使用预设的reporter,适用于大多数人。更多有关此设定,你可以从JSHint网站取得。
图片压缩
接着,我们将设定图片压缩:
gulp.task('images', function() {
return gulp.src('src/images/**/*')
.pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))
.pipe(gulp.dest('dist/assets/img'))
.pipe(notify({ message: 'Images task complete' }));
});
这会将对所有来源图片进行imagemin处理。我们可以稍微更进一步,利用快取保存已经压缩过的图片,以便每次进行此任务时不需要再重新压缩。这里只需要gulp-cache外挂--稍早已经安装。我们需要额外设置才能使用这个外挂,因此修改这段程式码:
.pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))
成为这段:
.pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
现在只有新的或更动过的图片会被压缩。干净俐落!
收拾干净!
在我们进行布署之前,清除目的地目录并重建档案是一个好主意--以防万一任何已经被删除的来源档案遗留在目的地目录之中:
gulp.task('clean', function() {
return del(['dist/assets/css', 'dist/assets/js', 'dist/assets/img']);
});
在这里我们不需要外挂,我们可以在gulp中直接使用Node模组。使用回呼函式(cb)来确保离开前任务已经完成。
预设任务
我们可以建立一个预设任务,当只输入$ gulp指令时执行的任务,这里执行三个我们所建立的任务:
gulp.task('default', ['clean'], function() {
gulp.start('styles', 'scripts', 'images');
});
注意额外传入gulp.task的阵列。这里我们可以定义任务相依(task dependencies)。在这个范例中,gulp.start开始任务前会先执行清理任务。Gulp中所有的任务都是并行(concurrently)处理,并没有先后顺序哪个任务会先完成,所以我们需要确保clean在其他任务开始之前执行完毕。
注意 :透过相依任务阵列来执行clean而非gulp.start是经过考虑的,在这个情境来看是最好的选择,以确保清理任务全部完成。
看守
为了能够看守档案,并在更动发生后执行相关任务,首先需要建立一个新的任务,使用gulp.watchAPI来看守档案:
gulp.task('watch', function() {
// 看守 .scss 檔
gulp.watch('src/styles/**/*.scss', ['styles']);
// 看守 .js 檔
gulp.watch('src/scripts/**/*.js', ['scripts']);
// 看守圖片檔
gulp.watch('src/images/**/*', ['images']);
});
透过gulp.watch指定想要看守的档案,并且透过相依任务阵列定义任务。执行$ gulp watch来开始看守档案,任何.scss、.js或图片档案一旦有了更动,便会执行相对应的任务。
即时重整(LiveReload)
Gulp也可以在处理档案更动后,自动重新整理页面。我们需要修改watch任务,设置即时重整伺服器。
gulp.task('watch', function() {
// 建立即時重整伺服器
livereload.listen();
// 看守所有位在 dist/ 目錄下的檔案,一旦有更動,便進行重整
gulp.watch(['dist/**']).on('change', livereload.changed);
});
为了让这个功能有效,除了伺服器之外,还需要安装并启用LiveReload的浏览器外挂。或者你也可以手动加上这个程式码片段。
全部放在一起
这里是完整的gulpfile,直接嵌入这个gist :
| /*! | |
| * gulp | |
| * $ npm install gulp-ruby-sass gulp-autoprefixer gulp-cssnano gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-livereload gulp-cache del --save-dev | |
| */ | |
| // Load plugins | |
| var gulp = require ( ' gulp ' ), | |
| sass = require ( ' gulp-ruby-sass ' ), | |
| autoprefixer = require ( ' gulp-autoprefixer ' ), | |
| cssnano = require ( ' gulp-cssnano ' ), | |
| jshint = require ( ' gulp-jshint ' ), | |
| uglify = require ( ' gulp-uglify ' ), | |
| imagemin = require ( ' gulp-imagemin ' ), | |
| rename = require ( ' gulp-rename ' ), | |
| concat = require ( ' gulp-concat ' ), | |
| notify = require ( ' gulp-notify ' ), | |
| cache = require ( ' gulp-cache ' ), | |
| livereload = require ( ' gulp-livereload ' ), | |
| del = require ( ' del ' ); | |
| // Styles | |
| gulp . task ( ' styles ' , function () { | |
| return sass ( ' src/styles/main.scss ' , { style : ' expanded ' }) | |
| . pipe ( autoprefixer ( ' last 2 version ' )) | |
| . pipe ( gulp . dest ( ' dist/styles ' )) | |
| . pipe ( rename ({ suffix : ' .min ' })) | |
| . pipe ( cssnano ()) | |
| . pipe ( gulp . dest ( ' dist/styles ' )) | |
| . pipe ( notify ({ message : ' Styles task complete ' })); | |
| }); | |
| // Scripts | |
| gulp . task ( ' scripts ' , function () { | |
| return gulp . src ( ' src/scripts/**/*.js ' ) | |
| . pipe ( jshint ( ' .jshintrc ' )) | |
| . pipe ( jshint . reporter ( ' default ' )) | |
| . pipe ( concat ( ' main.js ' )) | |
| . pipe ( gulp . dest ( ' dist/scripts ' )) | |
| . pipe ( rename ({ suffix : ' .min ' })) | |
| . pipe ( uglify ()) | |
| . pipe ( gulp . dest ( ' dist/scripts ' )) | |
| . pipe ( notify ({ message : ' Scripts task complete ' })); | |
| }); | |
| // Images | |
| gulp . task ( ' images ' , function () { | |
| return gulp . src ( ' src/images/**/* ' ) | |
| . pipe ( cache ( imagemin ({ optimizationLevel : 3 , progressive : true , interlaced : true }))) | |
| . pipe ( gulp . dest ( ' dist/images ' )) | |
| . pipe ( notify ({ message : ' Images task complete ' })); | |
| }); | |
| // Clean | |
| gulp . task ( ' clean ' , function () { | |
| return del ([ ' dist/styles ' , ' dist/scripts ' , ' dist/images ' ]); | |
| }); | |
| // Default task | |
| gulp . task ( ' default ' , [ ' clean ' ], function () { | |
| gulp . start ( ' styles ' , ' scripts ' , ' images ' ); | |
| }); | |
| // Watch | |
| gulp . task ( ' watch ' , function () { | |
| // Watch .scss files | |
| gulp . watch ( ' src/styles/**/*.scss ' , [ ' styles ' ]); | |
| // Watch .js files | |
| gulp . watch ( ' src/scripts/**/*.js ' , [ ' scripts ' ]); | |
| // Watch image files | |
| gulp . watch ( ' src/images/**/* ' , [ ' images ' ]); | |
| // Create LiveReload server | |
| livereload . listen (); | |
| // Watch any files in dist/, reload on change | |
| gulp . watch ([ ' dist/** ' ]). on ( ' change ' , livereload . changed ); | |
| }); |
我也将相同任务的Gruntfile放在同一个gist,方便你做比较。
浙公网安备 33010602011771号