精益 React 学习指南 (Lean React)- 2.3 gulp
2.3 Gulp
在前端工程化中最重要的就是流程管理,借用 gulp 可以很方便的基于流的方式定义流程任务,并将任务串联起来,本节中将详细介绍 gulp ,包括:
2.3.1 Gulp 介绍
Gulp 是一个基于 Node.js 的开源前端工作流构建工具,目前最新的版本为 3.9.1 ,最新的维护分支已经到了 4.0,更具体一下 Gulp 是:
Gulp 核心思想和特点
Gulp 能够解决哪些问题通常的一个前端构建流程包括:
这些构建任务在 Gulp 中都可以利用插件很容易的配置出来 一个 Gulp 配置示例Gulp 通过定义 gulpfile.js 配置文件的方式定义流程,gulp.js 会通过调用 Node.js 来执行 一个简单的流程定义文件为: var gulp = require('gulp'); var less = require('gulp-less'); var babel = require('gulp-babel'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); var rename = require('gulp-rename'); var cleanCSS = require('gulp-clean-css'); var del = require('del'); var paths = { styles: { src: 'src/styles/**/*.less',dest: 'assets/styles/' },scripts: { src: 'src/scripts/**/*.js',dest: 'assets/scripts/' } }; /** * 并非所有的任务都是基于流,例如删除文件 * 一个 gulpfile 只是一个 Node 程序,在 gulpfile 中可以使用任何 npm 中的模块或者其他 Node.js 程序 */ function clean() { // del 也可以和 `gulp.src` 一样可以基于模式匹配的文件路径定义方式 return del([ 'assets' ]); } /* * 通过 Javascript 函数的方式定义任务 */ function styles() { return gulp.src(paths.styles.src) .pipe(less()) .pipe(cleanCSS()) // 传递一些配置选项到 stream 中 .pipe(rename({ basename: 'main',suffix: '.min' })) .pipe(gulp.dest(paths.styles.dest)); } /** * 编译 coffee 文件,然后压缩代码,然后合并到 all.min.js * 并生成 coffee 源码的 sourcemap */ function scripts() { return gulp.src(paths.scripts.src,{ sourcemaps: true }) .pipe(babel()) .pipe(uglify()) .pipe(concat('main.min.js')) .pipe(gulp.dest(paths.scripts.dest)); } /** * 监控文件,当文件改变过后做对应的任务 * @return {[type]} [description] */ function watch() { gulp.watch(paths.scripts.src,scripts); gulp.watch(paths.styles.src,styles); } /* * 使用 CommonJS `exports` 模块的方式定义任务 */ exports.clean = clean; exports.styles = styles; exports.scripts = scripts; exports.watch = watch; /* * 确定任务是以并行还是串行的方式定义任务 */ var build = gulp.series(clean,gulp.parallel(styles,scripts)); /* * 除了 export 的方式,也可以使用 gulp.task 的方式定义任务 */ gulp.task('build',build); /* * 定义默认任务,默认任务可以直接通过 gulp 的方式调用 */ gulp.task('default',build); 2.3.2 Gulp 安装$ cd your-project // 安装最新版本的 gulp-cli $ npm install gulpjs/gulp-cli -g // 安装最新版本的 gulp 4.0 $ npm install gulpjs/gulp.git#4.0 --save-dev // 检查 gulp 版本 $ gulp -v --- [10:48:35] CLI version 1.2.1 [10:48:35] Local version 4.0.0-alpha.2 2.3.3 Gulp 配置与 API任务定义定义任务有两种方法 第一种方法为 Node.js 模块 exports 的方式: function someTask() { ... } exports.someTask = SomeTask 第二种方法为调用 gulp.task API 的方式 function someTask() { ... } // api 定义方式 1 gulp.task('someTask',someTask) // ap1 定义方式 2 gulp.task(function someTask() { ... }); // 获取 var someTask = gulp.task('someTask') 任务内容 通常一个任务会以如下方式定义 function someTask() { return gulp.src(...) // 流的输入 .pipe(someplugin()) // 插件处理流 .pipe(someplugin2()) // 插件处理流 .dest(...) // 输出流 } 任务的异步 task 的执行时异步的,可以基于回调函数 或 promise 或 stream 等方式 回调函数 var del = require('del'); // 传入 done 回调函数 gulp.task('clean',function(done) { del(['.build/'],done); }); 返回流 gulp.task('somename',function() { return gulp.src('client/**/*.js') .pipe(minify()) .pipe(gulp.dest('build')); }); 返回 Promise var Promise = require('promise'); var del = require('del'); gulp.task('clean',function() { return new Promise(function (resolve,reject) { del(['.build/'],function(err) { if (err) { reject(err); } else { resolve(); } }); }); }); 返回子进程 gulp.task('clean',function() { return spawn('rm',['-rf',path.join(__dirname,'build')]); }); 返回 RxJS observable var Observable = require('rx').Observable; gulp.task('sometask',function() { return Observable.return(42); }); 流的入口 gulp.src/** * @param globs [String | Array] * @param options [Object { * // 默认: process.cwd() * // 描述: 工作目录 * cwd: String,* * // 默认:在模式匹配之前的路径 a/b/ ** / *.js 路径为 a/b/ * // 描述:gulp.dest 目录会添加 base 目录 * base: String | Number,* ... * }] */ gulp.src(globs[,options]) gulp.src 方法是流的入口,方法的方法返回的结果为一个 Vinyl files 的 node stream ,可以被 piped 到别的插件中。 gulp.src('client/templates/*.jade') .pipe(jade()) .pipe(minify()) .pipe(gulp.dest('build/minified_templates')); 匹配模式gulp.src 的参数 globs 中的 glob 是一种匹配模式,可以使用 **,* 这些通配符来匹配文件,globs 参数可以为一个 glob 匹配字符串,也可以是 glob 匹配字符串数组 假定我们的项目目录结构如下: . └── src ├── d1 │ ├── d1-1 │ │ └── f1-1-1.js │ └── f1-1.js ├── f1.js ├── f2.js └── f3.js 下面是一些匹配的示例:
|