前端自动化构建

张兵(Brianbzhang)
QQ邮箱Web前端工程师

主要分享点

历史驱动力

常用工具

QQ邮箱实践经验

衣食住行


压缩,合并,混淆

技术变革


  • Less  && Sass
  • Seajs  && Requirejs 
  • CoffeeScript
解放双手

速度与激情


80%工程,20%技术
  • 技术
  • 流程
  • 效率

Ant
Python  or  Ruby
Nodejs

执行流程图

图片来自(http://slides.com/contra/gulp)
插件开发
 // 插件框架
module.exports = function(grunt){

	grunt.registerMultiTask('test', 'test for create a grunt plugin', function(){

		var options = this.options();

		// 输入的文件对象
		// files(inputs)
		this.files.forEach(function(file){

			// 读取文件
			var srcContent = grunt.file.read(file.src);

			// build函数表示具体的任务执行
			var destContent = build(source);

			// 写回文件
			grunt.file.write(file.dest, dest)

		});
	});
};
配置文件
 module.exports = function(grunt){

	// init grunt task config
	grunt.initConfig({
    
    coffee : {
			target : {
				files : [{
                    expand : true,
					cwd : 'scripts',
					src : '**/*.coffee',
					dest : 'build/coffee',
					ext : '.js'
				}]
			}
		},

		concat : {

			target : {
				src : ['<%= coffee.target.files.dest %>/*.js'],
				dest : 'build/scripts/all.js'
			}
		},

		uglify : {

			target : {

				files : {

					'build/dist/all.min.js' : ['<%= concat.target.dest %>']
				}
			}
		},

		htmlmin : {

			target : {

				files : [{
					expand : true,
					cwd : 'tpl',
					src : '**/*.html',
					dest : 'build/tpl',
					ext : '*.html'
				}]
			}
		},

		watch : {

			scripts : {

				files : ['scripts/**/*.js'],

				tasks : ['scripts']
			},

			html : {

				files : ['tpl/**/*.html'],

				tasks : ['htmlmin']
			}
		}
	});

	// load npm task
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-coffee');

	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-htmlmin');


	// register task alias
	grunt.registerTask('scripts', ['coffee', 'concat', 'uglify']);

	grunt.registerTask('debug', ['htmlmin', 'scripts', 'watch']);

	grunt.registerTask('release', ['htmlmin', 'scripts']);

};
痛点

  • 上手比较慢
  • 配置太多,乱的管理问题
  • 临时文件的管理,频繁IO的性能消耗
  • 原生不支持任务并行执行
  • 复杂构建支持太差,task不得不融入业务逻辑

 
图片来自(http://slides.com/contra/gulp)
执行流程图
插件开发
var es = require('event-stream');
module.exports = function (opts) {
  
  // task config
  opts = opts || {};

  // through streams
  // file(inputs)
  return es.map(function (file, cb) {

    //what task do?

    // transport data to next task(ouputs)
    cb(null, file);
  });
};
Transport Object
 // https://github.com/wearefractal/vinyl
var File = require('vinyl');

var htmlTpl = new File({
  cwd: "/",
  base: "/test/",
  path: "/test/item.html"
  contents: new Buffer("<div></div>")
});
gulp-htmlmin
// https://github.com/jonschlinkert/gulp-htmlmin
var es = require('event-stream');
var htmlmin = require('html-minifier');
var gutil = require('gulp-util');

module.exports = function (opts) {
  'use strict';

  opts = opts || {
    showStack: false
  };

  return es.map(function (file, cb) {
    try {
      file.contents = new Buffer(htmlmin.minify(String(file.contents), opts));
    } catch (err) {
      return cb(new gutil.PluginError('gulp-htmlmin', err, opts));
    }
    cb(null, file);
  });
};
配置文件
 // gulp example config

var gulp = require('gulp');

var htmlmin = require('gulp-htmlmin');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

gulp.task('html', function(){

  return gulp.src('tpl/**/*.html').pipe(htmlmin()).pipe(gulp.dest('build/tpl'));

});

gulp.task('scripts', function(){

  return gulp.src('scripts/**/*.coffee')
        .pipe(coffee())
        .pipe(uglify())
        .pipe(concat('all.min.js'))
        .pipe(gulp.dest('build/scripts'));
});

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

  gulp.watch('tpl/**/*.html', ['html']);

  gulp.watch('scripts/**/*.coffee', ['scripts']);
});

// task alias
gulp.task('debug', ['watch']);

gulp.task('release', ['scripts', 'html']);
对比Grunt
编程型的,任务间stream传输,没有临时文件的产生
构建速度提升。


产生的痛点:
任务的调试比较麻烦
目前社区支持不够


社区讨论:
1,区别不大,社区才是王道
2,小项目随便用吧,复杂的构建流程还是使用编程的方式。
QQ邮箱的开发上线流程
旧系统的痛点

新的系统技术选型

重构过程中经验分享
  1. grunt的日志实时收集展示
  2. 多个用户同时同步的问题
  3. 同步文件的日志分析
Q&A

webmaildev@qq.com

前端自动化构建

By bing zhang

前端自动化构建

前端自动化构建的必要性;自动化构建的常用工具;Grunt 以及Gulp构建工具的简单介绍,插件编写,优缺点对比;QQ邮箱前端工程化建设的一些实践经验

  • 5,897