开始写gulp任务
写gulp任务的基本语法1
2
3gulp.task('task-name',function(){
//do sth here
});
一般的gulp任务包含2个gulp方法,和不同的Gulp插件。
一个真正的任务看起来像这样:1
2
3
4
5gulp.task('task-name',function(){
return gulp.src('source-files') //get source files with gulp.src
.pipe(someGulpPlugin()) //send it through a gulp plugin
.pipe(gulp.dest('destination'))//output the file in the destination folder
})
一般真正的任务需要2个额外的方法 — gulp.src 和 gulp.test。
gulp.src告诉Gulp任务处理什么文件,gulp.dest告诉Gulp,当任务完成时候,输出的文件放哪里。
用gulp预处理(preprocessing)
使用gulp-sass插件可以将sass编译为css。
先安装。1
npm install gulp-sass --save-dev
从node_modules文件夹require gulp-sass,才能使用。1
2
3var gulp = require('gulp');
// Requires the gulp-sass plugin
var sass = require('gulp-sass');
用sass()方法使用gulp-sass。1
2
3
4
5gulp.task('sass',function(){
return gulp.src('source-files')
.pipe(sass()) //using gulp-sass
.pipe(gulp.dest('destination'))
});
我们需要给sass任务一个源文件和目标文件。在app/scss文件夹创建一个styles.scss。这个文件会被gulp.src添加到sass任务。1
2
3
4
5gulp.task('sass',function(){
return gulp.src('app/scss/styles.scss')
.pipe(sass())
.pipe(gulp.dest('app/css'))
})
在命令行运行 gulp sass,可以看见在app/css下创建了一个styles.css。
Gulp-sass使用LibSass将Sass编译成CSS。比基于ruby的方法快。
Glob in Node
Globs是匹配模式,允许你添加多个文件到gulp.src。有点像正则表达式,但只是针对文件路径。
当你使用glob,电脑会为这个模式检查文件名和路径。如果模式存在,文件就匹配上了。
大部分的Gulp工作流只需要4种不同的globbing patterns:
*.scss
: *就是通配符,匹配当前目录下的任何模式。在这种情况下,我们匹配根目录下任意以.scss
结尾的文件。**/*.scss
: 这是一个更极端的版本。匹配根目录下或者任意子目录下的.scss
结尾的文件。!not-me.scss
: “!”表示Gulp需要从匹配中排除该模式。如果你不需要匹配的模式中的某一个文件,这很有用。这个例子中,not-me.scss
会从匹配中移除。*.+(scss|sass)
: 加号和括号允许Gulp匹配多个模式。不同的模式用pipe|
分隔开。这个例子,Gulp会匹配根目录下任意以.scss
和.sass
结尾的文件。
知道了golbbing,可以将原来的 app/scss/styles.scss
替换为 scss/**/*.scss
模式。这样就可以匹配任意在根目录下或者子目录下文件扩展名为 .scss
的文件了。1
2
3
4
5gulp.task('sass',function(){
return gulp.src('app/scss/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('app/css'))
});
任意在app/scss目录下的sass文件,会被自动添加到这个任务。
现在,我们只用一个命令就可以将所有的sass文件编译成css。
可是,每次想要把sass编译为css都要手动运行一遍 gulp sass
,这样太麻烦了。
幸运的是,每当文件发生变化,Gulp可以自动运行 sass
任务,如果这个文件被一个叫做’watching’的进程。
Watching Sass files for changes(监视sass文件的改变)
Gulp提供了一个 watch
方法看一个文件是否保存。 watch
方法的语法如下:1
2// Gulp watch syntax
gulp.watch('files-to-watch',['task', 'to', 'run']);
想要监视所有Sass文件并在每次一个Sass 文件保存的时候运行 sass
任务,只需要将 files-to-watch
换成 app/scss/**/*.scss
,把 ['tasks', 'to', 'run']
换成 ['sass']
。1
gulp.watch('app/scss/**/*.scss',['sass']);
然而大多数时候,我们需要一次监视多种类型的文件。
我们可以将多个监视任务组合成一个 watch
任务:1
2
3
4gulp.task('watch',function(){
gulp.watch('app/scss/**/*.scss',['sass'])
// other watchers
})
可以运行 gulp watch
立刻运行监视任务。
每次保存一个 .scss
文件,都会运行 sass
任务。
Live-reloading with Browser Sync
先安装:1
npm install browser-sync --save-dev
注意安装的时候没有 gulp-
前缀。这是因为Gulp和Browser Sync一起工作,所以不需要使用插件。
使用前需要require:1
var browserSync = require('browser-sync').create();
告诉 watch
任务,必须在 browserSync
完成之后才能运行。
我们可以给 watch
任务添加一个参数来达到这个目的:1
gulp.task('watch',['arrays', 'of', 'tasks', 'to', 'complete', 'before', 'watch'],function(){})
比如:1
2
3
4gulp.task('watch',['browserSync'],function(){
gulp.task('app/scss/**/*.scss',['scss']);
// other watchers
})
保证 sass
任务在 watch
之前运行,这样,无论什么时候运行gulp命令css都是最新的。1
2
3
4gulp.task('watch',['browserSync','sass'],function(){
gulp.watch('app/scss/**/*.scss',['scss']);
// other watchers
});
现在在命令行运行 gulp watch
,gulp会同时开启 sass
和 browserSync
任务。当这两个任务都完成了, watch
才开始运行。
同时,指向 app/index.html
的浏览器窗口会弹出。如果修改 styles.scss
文件, 浏览器会自动重载。
当html和js文件保存的时候,也重载。1
2
3
4
5
6gulp.task('watch',['browserSync', 'sass'],function(){
gulp.watch('app/scss/**/*.scss',['sass']);
// reload the browser whenever HTML or JS files change
gulp.watch('app/*.html',browserSync.reload);
gulp.watch('app/js/**/*.js',browserSync.reload);
});
目前为止,做成了3件事情:
- 生成开发服务器
- 使用Sass预处理程序
- 每当文件发生改变,重载浏览器。
接下来优化资源,先从css和js文件开始。
优化CSS和JS文件
优化css和js的时候,开发者需要做2件事情:minification and concatenation。
开发者经常遇到的问题是不能按照正确的顺序来连接这些文件。
比如:1
2
3
4
5
6<body>
<!-- stuff -->
<script src"js/lib/a-xxx.js"></script>
<script src"js/lib/b-xxx.js"></script>
<script src"js/main.js"></script>
</body>
这些文件不在同一个目录下。很难用传统的插件比如gulp-concatenate串联。
很幸运,现在有一个插件,叫做gulp-useref能够解决这个问题。
Gulp-useref将任意数量的css和js文件并为一个文件。
语法如下:1
2
3<!-- build:<type> <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->
<type>
可以是 js
, css
, 或者 remove
。最好是把type设置为试图串联的文件类型。如果把 type
设置为 remove
,Gulp会删除整段代码,不会生成文件。<path>
只得是生成文件的目标路径。
我们想要js文件到 js
文件夹,名字为 main.min.js
,标记可以这样写:1
2
3
4
5<!-- build:js js/main.min.js -->
<script src"js/lib/a-xxx.js"></script>
<script src"js/lib/b-xxx.js"></script>
<script src"js/main.js"></script>
<!-- endbuild -->
现在来配置gulp-useref。先安装,再在gulpfile中require。1
npm install gulp-useref --save-dev
1 | var useref=require('gulp-useref'); |
设置 useref
任务:1
2
3
4
5gulp.task('useref',function(){
return gulp.src('app/*html')
.pipe(useref())
.pipe(gulp.dest('dist'))
})
运行useref任务,Gulp会把这三个文件串联为一个,放到 dist/js/main.min.js
。
现在文件还没有压缩。使用gulp-uglify插件压缩js文件,还需要gulp-if保证只压缩js。1
npm install gulp-uglify --save-dev
1 | // other requires... |
现在每次运行 useref
,都会自动压缩js。
可以用同样的方法串联css文件。1
2
3
4<!-- build:css css/style.min.css -->
<link ref="stylesheet" href="css/styles.css">
<link ref="stylesheet" href="css/another-styles.css">
<!-- end build -->
用gulp-cssnano插件压缩css文件:1
npm install gulp-cssnano --save-dev
1 | var cssno=require('gulp-cssnano'); |
现在每次运行 useref
就优化css和js文件。
接下来,我们优化图片。
优化图片
使用gulp-imagemin优化图片。1
npm install gulp-imagemin --save-dev
1 | var imagemin = require('gulp-imagemin'); |
可以用gulp-imagemin压缩png,jpg,gif甚至是svg文件。1
2
3
4
5gulp.task('images',function(){
return gulp.src('app/images/**/*.+(png|jpg|gif|svg)')
.pipe(imagemin())
.pipe(gulp.dest('dist/images'))
});
不同的文件类型优化得不同,所以可能需要给不同的文件类型配置不同的优化选项。
比如:1
2
3
4
5
6
7
8gulp.task('images',function(){
return gulp.src('app/images/**/*.+(png|jpg|jpeg|gif|svg')
pipe(imagemin({
// setting interlaced to true
interlaced:true
}))
.pipe(gulp.dest('dist/images'))
});
优化图片很慢,没有必要每次都优化。用gulp-cache来达到这个目的:1
npm install gulp-cache --save-dev
1 | var cache=require('gulp-cache'); |
基本搞定。还有一个需要到’dist’文件夹的东西:fonts。
复制字体到dist文件夹
字体已经优化了。我们不需要再做什么。
用gulp复制文件:1
2
3
4gulp.task('fonts',function(){
return gulp.src('app/fonts/**/*')
.pipe(gulp.dest('dist/fonts'))
})
现在每次运行 gulp fonts
都会将字体从app文件夹复制到dist文件夹。
现在已经有6个不同任务了。每个任务都单独地在命令行运行,这样有点繁琐。
自动清除生成到文件
确保不用到文件不会保留在我们不知道到地方。1
npm install del --save-dev
1 | var del=require('del'); |
del
任务删除任意数组的node globs文件夹。1
2
3gulp.task('clean:dist',function(){
return del.sync('dist');
})
现在每次运行 gulp clean:dist
就会删除dist文件夹。
不用担心回删除 dist/images
,因为gulp-cache已经在本地系统保存了图片的缓存。
要删除本地系统的缓存,可以创建一个清除缓存的任务。1
2
3gulp.task('cache:clear',function(callback){
return cache.clearAll(callback)
})
Combing Gulp Tasks(组合gulp任务)
总结一下,目前我们做了2种不同类型gulp任务。
第一种是开发过程中,把sass编译为css,监视变化,每次重载浏览器。
第二中是优化过程,此时我们已经准备好了所有生产网站所需的文件。我们优化好css,js和图片,复制字体。
第一组任务用 gulp watch
命令行合为一个工作流了。1
2
3gulp.task('watch',['browserSync','sass'],function(){
// ...watchers
})
第二组任务包含创建生产网站的任务: clean:dist
, sass
, useref
, images
, 和 fonts
。
要保证cleans在其他任务完成之前完成,我们需要一个插件Sequence。1
npm install run-sequence --save-dev
语法如下:1
2
3
4var runSequence=require('run-sequence');
gulp.task('task-name',function(callback){
runSequence('task-one','task-two','task-three',callback);
});
当调用 task-name
的时候,gulp会先运行 task-one
,task-one
运行完成,gulp会自动开始运行 task-two
,task-two
完成,运行 task-three
。
如果把任务放在一个数组里面,会同时运行这些任务。1
2
3gulp.task('task-name',function(callback){
runSequence('task-one',['tasks','two','in','run','in','parallel'],'task-three',callback);
});
这样,gulp先运行 task-one
,当第一个任务运行完成,gulp会同时运行第二个参数里面的任务。当数组里面所有的任务都运行完成,才会开始运行 task-three
。
现在可以创建一个任务,保证 dist:clean
先运行,然后再运行其他的任务。1
2
3
4
5
6gulp.task('build',function(callback){
runSequence('clean:dist',
['sass','useref','images','fonts'],
callback
)
})
为了保证一致性,第一组任务我们也可以创建顺序。1
2
3
4
5gulp.task('default',function(callback){
runSequence(['sass','browserSync','watch'],
callback
)
})
用 default
,你只需要键入 gulp
在命令行。
[原文链接]: (https://css-tricks.com/gulp-for-beginners/ )