抛开Grunt,又有一个新的自动化构建系统成为新的领跑者。那就是Gulp。css
Gulp是一种直观、自动化构建的工具。html
为何前端er会这么感兴趣Gulp?我相信你们都有个思想:要么不作事,要作事就要把事情作得最好!前端
Gulp就是帮你把前端的事情作好的一个工具!Gulp是基于Node和NPM,安装教程点这里。node
Gulp使用了node.js的流控制系统,使其(Gulp)构建更快,由于它不须要将临时文件/文件夹写入磁盘。android
若是你想了解更多关于流控制系统——这不是必需的——这篇文章页是很值得推荐大家去看的。ios
Gulp容许你去指定你的源文件是哪些,而后用管道的方式传输你的源文件到一堆的插件中进行编译,最后得出你想要的结果,这比Grunt的设置每一个插件的输入输出的繁琐操做简单多了。git
咱们要修改编译、合并或者压缩的文件都放在一块儿,而后经过管道流,管道流里面含有多种的插件,这些插件会按照你指定的操做顺序的方法进行对文件的操做,操做事后生成新的目标文件。github
Error: Cannot find module 'jshint/src/cli
我认为开发人员在最新版本中改变了gulp-jshint的结构致使了这个问题,解决问题的办法:npm
$ npm install --save-dev jshint gulp-jshint
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须要单独配置每个插件,为每一个插件指定源文件和结果输出的路径。(贼麻烦好吗。)json
例如:咱们输入一个文件到Sass编译的插件里,而后保存输出。在这以后咱们还要配置Autoprefixer来输入Sass的输出,而后输出另外一个文件。让咱们看一看一样的配置在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了,如今来安装Gulp和开始建立一些例子吧!
在咱们配置文件以前,咱们须要全局安装gulp:
$ npm install gulp -g
在这里咱们是要全局安装gulp,由于咱们须要给权限到gulp的CLI上。安装完成后咱们须要进入到咱们的项目根目录下。
$ cd XXX
$ npm install gulp --save-dev
运行完这两条命令咱们在package.json中的devDependencies看到了有gulp。
咱们将安装一些的插件来完成如下的任务:
运行如下命令安装这些插件(建议用cnpm,插件太多):
$ npm install gulp-ruby-sass gulp-autoprefixer gulp-cssnano gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-cache gulp-livereload del --save-dev
这条命令将会安装全部必须的插件和保存在package.json的devDependencies中。更多的插件在这里。
下一步,咱们须要建立一个gulpfile.js文件和引入插件:
var gulp = require('gulp'), sass = require('gulp-ruby-sass'), cssnano = require('gulp-cssnano'),
autoprefixer = require('gulp-autoprefixer'); jshint = require('gulp-jshint'), uglify = require('gulp-uglify'), imagemin = require('gulp-imagemin'),
rename = require('gulp-rename'), concat = require('gulp-concat'),
cache = require('gulp-cache'), notify = require('gulp-notify'), livereload = require('gulp-livereload'), del = require('del');
Gulp插件与Grunt插件有一点不一样——它们被设计成只能够作一件事和这件事必定要作到最好。
来个示例;Grunt的imagemin使用缓存,以免压缩已经压缩的图像。对于gulp,这将用一个缓存插件来完成,它也能够用来缓存其余的东西。这为构建过程增长了额外的灵活性。
其实咱们能够像Grunt同样使用自动加载全部已安装的插件,但为了这篇文章的目的,咱们将坚持手动方法。
首先,咱们将配置Sass编译。咱们将编译Sass做为扩展,经过自动修复程序运行它并将它保存到咱们的目的地。而后咱们会建立一个小型的: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任务完成' })); });
在这里再作点解释再往前走。
gulp.task('styles', function() { ... )};
这个gulp.task是用来建立gulp任务的API。上面能够用 $ gulp styles 从终端运行。
return sass('src/styles/main.scss', { style: 'expanded' })
这是gulp-ruby-sass的API,咱们定义源文件并传递任何选项。对于不少其余插件,你可使用gulp.src的API来控制文件。好比:*.scss能够匹配全部以.scss为结尾的文件。经过返回流控制系统使他具备异步性,在咱们收到通知以前,确保任务已经完成。
.pipe(autoprefixer('last 2 version'))
咱们用.pipe()经过管道传输方式把源文件传输到插件上。一般各类插件的选项是在他们各自的GitHub页面上找到的。为了方便起见,我把它们连在一块儿了。管道是可连接的,所以您能够在流控制系统中添加尽量多的插件。
.pipe(gulp.dest('dist/assets/css'));
gulp.dest的API为咱们设定最终输出文件的位置。一个任务能够有多个目的地,一个能够输出扩展版本,另外一个能够输出压缩版本。这在上面的styles任务中演示。
我建议去看看gulp的API文档,以更好地了解这些方法。英文文档其实看起来也没那么吓人!
经过以上解释我但愿大家能掌握怎么使用gulp了,接下来咱们把脚本任务设为规范+合并+压缩:
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任务完成' })); });
在这里咱们经过gulp.src的API把咱们要修改的文件放到管道流中。详细流程见下图(如看不清鼠标右键->在新标签页中打开图片):
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任务完成' })); });
这个任务会把images文件夹下的全部图片文件经过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插件,由于咱们能够在gulp中直接利用节点模块。咱们使用返回来确保任务在退出前完成。
咱们也能够建立一个默认任务,能够在命令行中直接 $ gulp 就可使用,下面的例子就是运行咱们已经建立好的三个任务:
gulp.task('default', function() { gulp.start('styles', 'scripts', 'images'); });
注意在gulp . task中附加的数组。在这里,咱们能够定义任务依赖项。在这个示例中,clean任务将在任务开始以前运行。在Gulp中,任务同时运行,没有顺序完成,因此咱们须要确保在运行额外任务以前完成clean的任务。
为了查看咱们的文件并在它们发生变化时执行必要的任务,咱们首先须要建立一个新任务,而后使用gulp.watch的API监测文件:
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']); });
当咱们运行 $ gulp task 的时候它就会自动监测这些文件。
gulp也能够在游览器上监测文件变化实时刷新页面,不过在这里须要游览器安装插件。另外我会专门写个博客是专对于gulp的实时刷新:
gulp.task('watch', function() { // Create LiveReload server livereload.listen(); // Watch any files in dist/, reload on change gulp.watch(['dist/**']).on('change', livereload.changed); });
为了能让任务能执行,你要在游览器中安装LiveReload插件。
在这里我收集了我平时须要的全部gulp插件:GitHub地址
以上。