前端工作流

主要操作包含:

CSS 前缀补全, LESS/SASS 编译, CSS 压缩, JS 合并压缩 ,图片压缩, 部署发布

流程分解

主要分为

开发过程

部署过程

开发过程

要求每一次编辑都能在页面上即时相应

部署过程

  • CSS Autoprefixer
  • Less/Sass => CSS
  • CSS 压缩合并
  • CSS Sprite
  • Retina @2x & @3x 自动生成适配
  • imagemin 图片压缩
  • JS 合并压缩

项目目录结构

project //项目目录
|dev //开发目录
| |
html
| |images
| |
scripts
| |slice //合成的雪碧图
| |
styles
|dist //生产目录
| |
html
| |images
| |
scripts
| |sprite //仅从 src 复制
| |
styles
|gulpfile.js
|
src //源文件目录
| |html
| |
images
| |scripts
| |
slice //雪碧图素材
| |____styles

Gulp 能够解决哪些问题

通常一个前端构建流程包括:

  • 文件清理: gulp-clear
  • 文件拷贝: gulp-copy
  • 文件转换: gulp-webpack
  • 文件合并: gulp-concat
  • 文件压缩: gulp-minify
  • 文件服务: gulp-connect
  • 文件监控: gulp-watch
  • css 相关:
    • less, sass 转换(gulp-less, gulp-sass)
    • css 自动添加前缀(gulp-autoprefixer)
  • js 相关:
    • jslint(gulp-jshint)
  • html 转换
    • html 模板(gulp-jade, gulp-ejs)
    • html prettify
    • html validator
    • html min

Gulp 通过定义gulpfile.js配置文件的方式定义流程, gulp.js 会通过调用 Node.js 来执行流程.

引入插件

var gulp = require("gulp"), ...
`</pre>

### 设定路径

<pre>`var paths = {
  styles:{
    src: "src/styles/**/*.less",
    dest: "assets/styles/"
  },
  scripts:{
    src: "src/scripts/**/*.js",
    dest: "assets/scripts/"
  }
};
`</pre>

### 设定任务

<pre>`gulp.task("taskName", function(){
  gulp.src(paths.styles.src)
      .pipe(task())
      .pipe(gulp.dest(paths.styles.dest));
});
`</pre>

一个 gulpfile.js 文件只是一个 Node 程序, 在 gulpfile 中可以使用任何 npm 中的模块或者其他 Node.js
并非所有的任务都是基于流, 例如删除文件

<pre>`function clean(){
  //del 也可以和 gulp.src 一样基于模式匹配的文件路径定义方式
  return del(["assets"]);
}
`</pre>

如果要控制 task 顺序, 可以通过回调函数实现
gulp.task(taskName, function(fn){})
现在新增加了串行和并行 API
- gulp.parallel: 并行执行
- gulp.series: 串行执行
e.g.

<pre>`gulp.task("one", function(done){
  //do stuff
  done(); //回调函数
})
gulp.task("two", function(done){
  //do stuff
  done();
});
//并行执行任务, 执行完后可以添加回调函数
gulp.task("parallelTask", gulp.parallel("one", "two", function(done){
  done();
}));
//串行任务
gulp.task("seriesTask", gulp.series("one", "two", function(done){
  done();
}));
`</pre>

### 前端常用插件
  • gulp-sass: 编译 SASS
  • browser-sync: 保持多浏览器, 多设备同步
  • gulp-imagemin: 压制 png/jpg/git/svg 图片
  • gulp-minify-css: 压缩 CSS
  • gulp-rename
  • gulp-concat: 合并 JS
  • gulp-uglify: 压缩 JS
  • gulp-autoprefixer: 添加前缀
  • gulp-css-spriter: 生成雪碧图
  • gulp-htmlmin
  • gulp-server-livereload

    拥有live-reloading的服务器

    使用 BrowserSync 和 gulp, 你可以轻松创建一个开发服务器, 然后同一个WiFi 中的任何设备都可以方便访问.
    BrowserSync 同时集成了 live-reload, 所以不需要做另外的配置.

    首先安装模块
    npm install brower-sync --save-dev
    假设目前目录结构为

    `gulpfile.js
    app/
        styles/
                main.css
            scripts/
                main.js
            index.html
    `

    配置 gulpfile.js, 将 app 目录中的文件加入到服务器中, 并且所有的浏览器会在文件发生变化后自动刷新

    `var gulp = requrie("gulp");
    var browserSync = require("browser-sync").create();
    var reload = browerSync.reload;
    
    //监视文件改动并重新载入
    gulp.task("browser-sync", function(){
        browserSync.init({
                server:{
                        baseDir: 'app'
                    }
            });
    
            gulp.watch(['*.html', 'styles/**/*.css', 'scripts/**/*.js'], {cwd: 'app'}, browserSync.reload);
    });
    `

    CSS 预处理

    指定浏览器无需刷新即可重载 CSS
    假设目录如上

    `var gulp = require(“gulp”);
    var sass = require(“gulp-ruby-sass”);
    var browserSync = require(“browser-sync”).create();

    gulp.task(“sass”, function(){

    return sass("styles/**/*.scss")
                 .pipe(gulp.dest("app/css")
                         .pipe(reload({stream:true}));
    

    {);
    /*
    gulp.task(“sass”, function(){

    gulp.src("styles/**/*.scss")
        .pipe(sass({outputstyle: 'compressed'}).on('error',sass.logError))
        .pipe(gulp.dest("app/css");
    

    });
    */
    gulp.task(“browser-sync”, [“sass”], function(){

    browserSync({
            server: {
                    baseDir: "app";
                }
        });
        gulp.watch("app/styles/**/*.scss", ["sass"], browserSync.reload);
    

    });

设置tunnel: true 来使用一个公开的 URL 来访问本地站点

Gulp 自动化部署快速入门

  1. $ npm install —g gulp全局安装
  • 安装前保证已经安装了 ruby
  1. $ npm install —save-dev- gulp作为项目的开发依赖( devDependence)安装到项目目录

  2. 在项目根目录下创建一个名为gulpfile.js的文件:

    //引用 gulp plugin
    

    var gulp = require(‘gulp’);
    //建立 gulp task
    gulp.task(‘default’, function(){
    //任务代码
    })
    </pre> 在项目根目录运行 gulp 时, gulp 会直接读取gulpfile.js`中定义的任务并执行.

  • gulp 可以将每一个你要执行的工作命名, 而默认运行的task 名为default
  1. $ gulp`运行 gulp, 运行默认的名为’ default’ 的任务( task)
  • gulp &lt;task&gt; &lt;othertask&gt;运行指定 task
  1. gulp 基本 API
  • gulp.src(globs[, options])

    *   `glob`参考 [node-glob 语法](https://github.com/isaacs/node-glob), 也可以直接写文件的路径
    
    • options:略
  • gulp.dest(path[,options])

    *   能被`pipe`进来, 并能写文件到文件夹, 如果文件夹不存在, 则自动创建文件夹.
    
    • path: String 或 Function, 可以直接写输出目录, 也可以传入一个返回路径的函数
    • options:略
  • gulp.task(name[, deps], fn)

    *   <pre>`gulp.task('script',function(){
    

    //待执行
    })
    `

    • name: 赋予任务名称
    • deps: 任务列表数组, 这些任务会在当前任务运行之前完成

          *   task 默认以最大并发数执行, 也就是说 gulp 会一次性执行所有 task 并不做任何等待, 如果要以特定顺序执行, 需要:
      
                  *   给出一个提示, 告知 task 什么时候执行完毕
      *   再给出一个提示, 告知 task 依赖另一个 task 的完成
      *   
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      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']);
    • fn:要执行的操作

  • gulp.watch(glob [, opts], tasks)

    *   监听文件, 并可以在文件发生改动的时候做一些事情, 他总会返回一个 EventEmiiter 来发射`change`事件.
    
    • glob: 指定具体监听哪些文件的变动
    • tasks: 需要在文件变动后执行的任务

      *   <pre>`var watcher = gulp.watch('js/**/*.js', ['uglify', 'reload']);
      

      watcher.on(‘change’, function(event){
      console.log(‘File’+event.path+’ was ‘+event.type+’, running tasks…’);
      });
      `

  1. 工作流程
  • 设定任务

    *   gulp 可以对不同的 task 命名, 而 default 是默认的人物名称, 如果执行 gulp 的时候没有指定任务名称, 则会执行`default` 任务.
    
    • `//载入 gulp plugin
      var gulp = require('gulp');
      //定义名称为 default 的 gulp 任务
      gulp.task('default', function(){
      console.log('Hello Gulp Default Task');
      });
      //定义名称为 other 的 gulp 任务
      gulp.task('other', function(){
      console.log('Hello Gulp Other Task');
      })
      `
  • 执行指定的 gulp 任务

    *   <pre>`$ gulp
    

    `

    *   执行默认的 default 任务
    
    • `$ gulp other
      `
      *   执行任务`other`
      
    • `$ gulp.task('default', ['other', 'script']);
      `
      *   在 default 任务中设定要执行的任务队列可以执行多个任务
      
  • 监听

    *   比如我们使用`gulp-uglify`最小化 JS 时, 希望可以在每次改动 JS 的时候自动执行 gulp 最小化动作
    
            *   <pre>`var gulp = require('gulp'),
    

    gulpUglify = require(‘gulp-uglify’);
    gulp.task(‘script’, function(){
    gulp.src(‘javascript/original/*.js’) //指定要处理的原始 JS 目录
    .pipe(gulpUglify()) //执行最小化
    .pipe(gulp.dest(‘javascript/minify’)); //最小化后部署到 JS 目录
    })
    `

    • 添加监听

      *   <pre>`gul.task('watch', function(){
      

      gulp.watch(‘javascript/original/*.js’, [‘script’]);
      })
      `

      • `$ gulp watch //执行监听
        `
        *   执行监听后, 每次改动 javascript/origin/*.js 中所有 JS 文件时都会重新执行 script 任务.
        
        • 可以用**监听所有文件
        • 可以将watch添加到任务列表, 这样只需要指令gulp就可以执行监听
  • 例外处理

    *   经历例外错误记录任务
    
            *   由于例外错误可能会在很多地方出现, 最好是定义为可调用的函数
    *   <pre>`function errorLog(error){
    

    console.error(error);
    this.emit(‘end’);
    }
    gulp.task(‘script’, function(){
    gulp.src(‘…’)
    .on(‘error’,errorLog)
    .pipe(gulpUglify())
    .pipe(gulp.dest(‘…’));
    });
    `

  1. 常用插件
  • gulp-uglify

    *   `$ npm install —save-dev gulp-uglify`
    
    • 将要最小化的 JS 文件放在 javascript/original 下
    • 将最小化后的 JS 文件放在 javascript/minify 下
    • `var gulp = require('gulp'),
      gulpUgligy = require('gulp-uglify');
      gulp.task('script', function(){
      gulp.src('javascript/original/*js')
      .pipe(gulpUglify())
      .pipe(gulp.dest('javascript/minify'));
      })
      `
  • gulp-sass

    *   `$ npm install —save-dev gulp-sass`
    
            *   将要编译的 Scss 文件放在 scss 目录下
    *   将编译后的 CSS 文件放在 css 目录下
    *   <pre>`var gulp = require('gulp'),
    

    gulpSass = required(‘gulp-sass’);
    gulp.task(‘styles’,function(){
    gulp.src(‘scss/*.scss’)
    .pipe(gulpSass())
    .pipe(gulp.dest(‘css’));
    })
    `

    *   向 gulpSass()传入参数`{outputStyle:'compressed'}`输出压缩后的 CSS 文件
    
  • gulp-imagemin

    *   压缩图片, 支持格式有 gif, jpg, png, svg
    
    • $ npm install --save-dev gulp-imagemin
    • 指定 images/origin下所有图片都压缩, 并把压缩后的图片放到images 中
    • `var gulp = require('gulp'),
      gulpImagemin = require('gulp-imagemin');
      gulp.task('image', function(){
      gulp.src('images/original/**')
      .pipe(gulpImagemin())
      .pipe(gulp.dest('images'));
      })
      `
  • gulp-plumber

    *   `$ npm install —save-dev gulp-plumber`
    
    • pipe(gulpPlumber())一定要在编译 scss 及最小化 js 之前就加入(注意顺序)
    • `var gulp = require('gulp'),
      gulpUglify = require('gulp-uglify');
      gulp.watch('watch', function(){
      gulp.watch('javascript/original/*.js', ['script']);
      });
      gulp.task('script', function(){
      gulp.src('javascript/original/*.js')
      .pipe(gulpPlumber())
      .pipe(gulpUglify())
      .pipe(gulp.dest('javascript/minify'));
      });
      `
    • gulp-autoprefixer
    • gulp-minify-css
    • gulp-clean
    • gulp-livereload
  1. 工作范例
  • 明确任务

    *   检查 JS
    
    • 编译 Scss
    • 合并 JS
    • 压缩并重命名合并后的 JS
  • 安装依赖

    *   `$ npm install gulp-jshint gulp-sass gulp-concat gulp-uglify gulp-rename —save-dev`
    
    • 新建gulpfile.js

      *   <pre>`//引入 gulp 及插件
      

      var gulp = require(‘gulp’),
      gulpJshint = require(‘gulp-jshint’),
      gulpSass = require(‘gulp-sass’),
      gulpConcat = require(‘gulp-concat’),
      gulpUglify = require(‘gulp-uglify’),
      gulpRename(‘gulp-rename’);
      //检查 JS, 该任务会检查 js/下的 js 文件有没有报错或警告
      gulp.task(‘lint’,function(){
      gulp.src(‘./js/.js’)
      .pipe(gulpJshint())
      .pipe(gulpJshint.reporter(‘default’));
      });
      //编译 Scss, 该任务会编译 scss/下的 scss 文件, 并把编译后的 css 文件保存到 /css 中
      gulp.task(‘sass’, function(){
      gulp.src(‘./scss/
      .scss’)
      .pipe(gulpSass())
      .pipe(gulp.dest(‘./css’));
      });
      //合并, 压缩 JS 文件, 该任务会合并 js/下的所有 js 文件, 并输出到 dist/目录, 然后重命名为.min.js, 并压缩再输出到 dist/下
      gulp.task(‘scripts’, function(){
      gulp.src(‘./js/.js’)
      .pipe(gulpConcat(‘all.js’))
      .pipe(gulp.dest(‘./dist’))
      .pipe(gulpRename(‘all.min.js’)).
      pipe(gulpUglify())
      .pipe(gulp.dest(‘./dist’));
      });
      //默认任务, 默认任务基于其他任务, 使用.run()方法关联和运行我们之前定义的方法, 使用.watch()方法监听指定目录的文件
      gulp.task(‘default’, function(){
      gulp.run(‘lint’, ‘sass’, ‘scripts’);
      //监听文件
      gulp.watch(‘./js/
      .js’, function(){
      gulp.run(‘lint’,’sass’,’scripts’);
      });
      });

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×