分享 Gulp 基础任务配置 [好的吧~这样会不会好一些~]

dandananddada · 2015年05月07日 · 最后由 fiery 回复于 2015年06月14日 · 11167 次阅读
本帖已被管理员设置为精华贴

与 Grunt 的比较

和 Grunt 类似,Gulp 也是一个前端自动化构建工具。 Gulp 和 Grunt 最显著的区别就是 Gulp 采用编码大于配置,而 Grunt 相反配置大于编码。Gulp 是基于流的构建系统,相对更侧重各任务之间的衔接,而 Grunt 侧重于一些通用的任务。另外 Gulp 更易读,但是 Grunt 相对插件要多。

安装与配置

安装全局 gulp $ npm install --global gulp 创建项目,在项目目录下安装 gulp $ npm install --save-dev gulp 创建 gulpfile.js 文件,配置 gulp

var gulp = require('gulp');

gulp.task('default', function() {
  // place code for your default task here
});

运行 gulp $ gulp

定制简单的任务

这次的侧重点放在自动化任务上,而非 gulp 本身。 首先说明下采用的目录结构为app/css下存放 scss 和 css 样式文件,app/js目录下存放 js 脚本文件,app根目录下存放 html 结构文件,在 dist 目录下存放 build 后的资源文件。 首先说明 Build Css 文件用到的一些插件: gulp-ruby-sass:用来将 scss 文件编译为 css 文件 gulp-autoprefixer:用来给 css 样式自动添加浏览器前缀 gulp-minify-css:用于 css 文件的压缩 流程如下:首先将 css 目录下 scss 文件编译为 css 文件,对 css 文件添加浏览器前缀,重命名为*.min.css,然后压缩输出到dist/css目录。

gulp.task('css', function() {
  return sass('app/css/', { style: 'expanded' })
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(gulp.dest('app/css'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(minifycss())
    .pipe(gulp.dest('dist/css'))
    .pipe(livereload())
    .pipe(notify({ message: 'css task complete' }));
});

然后说明 Build Js 文件用到的插件 gulp-concat:用来合并文件,这里主要合并 js 文件 gulp-uglify:混淆压缩 js 流程如下:首先合并 app 目录下 js 文件(我这里想保留 js 目录结构所以注释掉了合并任务),修改前缀为*.min.js,执行混淆压缩命令 输出到dist/js目录。

gulp.task('js', function() {
  return gulp.src('app/js/**/*.js')
    //.pipe(concat('main.js'))
    .pipe(gulp.dest('dist/js'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest('dist/js'))
    .pipe(livereload())
    .pipe(notify({ message: 'js task complete' }));
});

接下来说下非常有用的监视任务 gulp-webserver:用于在本地启动 Http 服务 gulp-livereload:livereload 用于浏览器自动刷新 首先创建一个 watch 任务,监测所有资源文件是否发生修改,然后创建一个 webserver 任务,启动 watch 任务,webserver 任务启动时会自动打开浏览器加载当前 app 目录下 html 文件,当 watch 任务监测到文件修改时就会通知 livereload,浏览器就会实时刷新,省去了手动刷新的操作。

//Watch
gulp.task('watch', function() {

  // Watch .scss files
  gulp.watch('app/css/**/*.scss', ['css']);
  // Watch .js files
  gulp.watch('app/js/**/*.js', ['js']);
  // Watch image files
  gulp.watch('app/images/**/*', ['images']);
  // Create LiveReload server
  livereload.listen();
  // Watch any files in dist/, reload on change
  gulp.watch(['dist/**']).on('change', livereload.changed);

});
//Server
gulp.task('server', function() {
  gulp.src('app')
    .pipe(webserver({
      livereload: true,
      open: true
    }));
  gulp.start('watch');
});

最后说下 clean 任务 当你执行 build 任务,或者想删除 build 后的文件时,可以用 del 删除指定目录文件

var del = require('del');
// Clean
gulp.task('clean', function(cb) {
    del(['dist/','app/css/**/*.css'], cb)
});

有关于我的配置 可参考项目 helloGlup https://github.com/dandananddada/helloGulp.git 给出配置文件如下:

// Load plugins
var gulp = require('gulp'),
    sass = require('gulp-ruby-sass'),
    autoprefixer = require('gulp-autoprefixer'),
    minifycss = require('gulp-minify-css'),
    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'),
    webserver = require('gulp-webserver'),
    del = require('del');

//html
gulp.task('html', function() {
    return gulp.src("app/*.html")
        .pipe(gulp.dest('dist/'))
        .pipe(livereload())
        .pipe(notify({ message: 'html task complete' }));
}); 

// css
gulp.task('css', function() {
  return sass('app/css/', { style: 'expanded' })
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(gulp.dest('app/css'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(minifycss())
    .pipe(gulp.dest('dist/css'))
    .pipe(livereload())
    .pipe(notify({ message: 'css task complete' }));
});

// js
gulp.task('js', function() {
  return gulp.src('app/js/**/*.js')
    //.pipe(concat('main.js'))
    .pipe(gulp.dest('dist/js'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest('dist/js'))
    .pipe(livereload())
    .pipe(notify({ message: 'js task complete' }));
});

// Images
gulp.task('images', function() {
  return gulp.src('app/images/**/*')
    .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
    .pipe(gulp.dest('dist/images'))
    .pipe(livereload())
    .pipe(notify({ message: 'Images task complete' }));
});

// Clean
gulp.task('clean', function(cb) {
    del(['dist/','app/css/**/*.css'], cb)
});


// Watch
gulp.task('watch', function() {

  //Watch .html files
  gulp.watch('app/**/*.html', ['html']);

  // Watch .scss files
  gulp.watch('app/css/**/*.scss', ['css']);

  // Watch .js files
  gulp.watch('app/js/**/*.js', ['js']);

  // Watch image files
  gulp.watch('app/images/**/*', ['images']);

  // Create LiveReload server
  livereload.listen();

  // Watch any files in dist/, reload on change
  gulp.watch(['dist/**']).on('change', livereload.changed);

});

//Build
gulp.task('build', ['clean'], function() {
    gulp.start('html','css', 'js', 'images');
});

//Server
gulp.task('server', function() {
  gulp.src('app')
    .pipe(webserver({
      livereload: true,
      open: true
    }));
  gulp.start('watch');
});

// Default task
gulp.task('default', ['build']);

Nice!最近管理员页面都在迁移 angularjs 加 java rest,gulp 学习了。

赞分享精神,一天之内从 Grunt 切换到 Gulp,真棒!

#2 楼 @lgn21st 哈哈哈。。我也感觉这么做会很好玩,所以就做了。。

有一个小技巧,用 npm 的 package.json 来管理项目的 gulp 依赖,并在 package.json 文件中添加 coffee-script 依赖,然后就可以把 Gulpfile.js 改成 Gulpfile.coffee,并可以用 coffee 来写 Gulp 的配置了,这对于写惯了 coffee 的人来说方便一点。

npm install coffee-script --save-dev

明天期待 webpack

Good job, 赞学习精神!

#4 楼 @lgn21st 好技巧,话说 angularjs 应用可以全部用 coffee 来写么,我有编辑器但是每次都要生成对应 js 文件特烦,类似于 rails 那种 xxx.js.coffee,npm 直接编译成 js 的那种。这样开发就能抛弃纯手写 js 了。。

#7 楼 @ryan https://github.com/wearefractal/gulp-coffee 其实我是还不太习惯 coffee 的写法,所以没有关于 coffee 的插件。。。

#9 楼 @dandananddada 👏 感谢分享 😃 :plus1:

赞楼主转型速度 😄 昨天是 Grunt,今天已经转到 Glup Gulp 👍

#11 楼 @kgen 不要被楼主误导了,是 gulp,不是 glup。

#12 楼 @seabornlee 这两个真像:)

#12 楼 @seabornlee 真的被误导了,我一开始打的是 gulp,后来看见标题是 glup,想想会不会自己错了,就顺手改成 glup 提交了 😪

请问楼主,js 各个模块之间的依赖关系如何处理呢? 比如:b.js 引用 a.js 和 c.js,最终 b.js 怎么生成呢?有没有自动化的武器呢?

@dandananddada 感谢,在你回复之前,我找到百度出品一个方案,你看看http://fis.baidu.com/docs/more/fis-standard-require.html#js

@rei 好吧,搞半天还是 Rails 的方案最经考验,不搞 前端 那套了。

#20 楼 @rei 这位大哥辛辛苦苦答了那么多,最后加深了我对 Asset Pipeline 的理解。不知道 Turbolinks 以及要出的 Turbolinks 3 这样的技术在其他社区有没有类似方案。

楼主好帖!坐等中高级配置

Grunt 是一个 task manager,作为 pipeline 有很多问题。Ember.js 社群在构建 ember-cli 的时候使用了 broccoli 构建 pipeline。可以单独使用也可以配合 grunt。

百度的 fis 用着还不错

懒得看全文的人推荐使用 yeoman 给的 generator-gulp-webapp

#7 楼 @ryan 可以,我经常这样干

#29 楼 @shatle 哎?你是研一么。。。

@dandananddada 显然,现已经不是,不过,至少我看起来还是很年轻的。据说,我大一到研究生毕业,顔值一直没有变化。今天说话有点多,:bowtie:

我推荐装一个 gulp help plugin,这样可以很方便的列出所有的 task, 并且可以对每个 task 加上一些描述。 https://github.com/chmontgomery/gulp-help

前几个月一直用 gulp 做自动化,不过到了后来因为需要控制多进程而不是简单的 cp.exec,只好回头学习使用 Rake 了,其实优势在于 Ruby 比异步 node 对 work flow 有更多控制能力。一开始用 gulp 想多利用一下 non-blocking IO,结果发现使用逻辑中需要同步执行的还是不少,js 的异步反而成了问题。github 上大概找了一下没找到关于 gulp 进程/线程控制的,反而都是让所有 call 都异步的库很多,达不到目的。。。相反的 Rake 的 multitask 和-j 参数都是直接拿来用,结果也是一天之内从 gulp 转到 Rake。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号