gulp入门之常见处理方式(三)
整合 streams 来处理错误
默认情况下,在 stream 中发生一个错误的话,它会被直接抛出,除非已经有一个时间监听器监听着 error
时间。 这在处理一个比较长的管道操作的时候会显得比较棘手。
这里是一个在 gulpfile 中使用它的例子:
var combiner = require('stream-combiner2');
var uglify = require('gulp-uglify');
var gulp = require('gulp'); gulp.task('test', function() {
var combined = combiner.obj([
gulp.src('bootstrap/js/*.js'),
uglify(),
gulp.dest('public/bootstrap')
]); // 任何在上面的 stream 中发生的错误,都不会抛出,
// 而是会被监听器捕获
combined.on('error', console.error.bind(console)); return combined;
});
删除文件和文件夹
最好的一个选择就是使用一个原生的 node 模块。
$ npm install --save-dev gulp del
假想有如下的文件结构:
.
├── dist
│ ├── report.csv
│ ├── desktop
│ └── mobile
│ ├── app.js
│ ├── deploy.json
│ └── index.html
└── src
在 gulpfile 中,我们希望在运行我们的编译任务之前,将 mobile
文件的内容先清理掉:
var gulp = require('gulp');
var del = require('del'); gulp.task('clean:mobile', function (cb) {
del([
'dist/report.csv',
// 这里我们使用一个通配模式来匹配 `mobile` 文件夹中的所有东西
'dist/mobile/**/*',
// 我们不希望删掉这个文件,所以我们取反这个匹配模式
'!dist/mobile/deploy.json'
], cb);
}); gulp.task('default', ['clean:mobile']);
在管道中删除文件
你可能需要在管道中将一些处理过的文件删除掉。
我们使用 vinyl-paths 模块来简单地获取 stream 中每个文件的路径,然后传给 del
方法。
$ npm install --save-dev gulp del vinyl-paths
假想有如下的文件结构:
.
├── tmp
│ ├── rainbow.js
│ └── unicorn.js
└── dist
var gulp = require('gulp');
var stripDebug = require('gulp-strip-debug'); // 仅用于本例做演示
var del = require('del');
var vinylPaths = require('vinyl-paths'); gulp.task('clean:tmp', function () {
return gulp.src('tmp/*')
.pipe(stripDebug())
.pipe(gulp.dest('dist'))
.pipe(vinylPaths(del));
}); gulp.task('default', ['clean:tmp']);
只有在已经使用了其他的插件之后才需要这样做,否则,请直接使用 gulp.src
来代替。
增量编译打包,包括处理整所涉及的所有文件
在做增量编译打包的时候,有一个比较麻烦的事情,那就是你常常希望操作的是 所有 处理过的文件,而不仅仅是单个的文件。举个例子,你想要只对更改的文件做代码 lint 操作,以及一些模块封装的操作,然后将他们与其他已经 lint 过的,以及已经进行过模块封装的文件合并到一起。如果不用到临时文件的话,这将会非常困难。
使用 gulp-cached 以及 gulp-remember 来解决这个问题。
var gulp = require('gulp');
var header = require('gulp-header'); //给文本文件头部追加内容
var footer = require('gulp-footer');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint'); //js代码校验
var cached = require('gulp-cached');
var remember = require('gulp-remember'); //gulp-remember
is a gulp plugin that remembers files that have passed through it.gulp-remember
adds all the files it has ever seen back into the stream. var scriptsGlob = 'src/**/*.js'; gulp.task('scripts', function() {
return gulp.src(scriptsGlob)
.pipe(cached('scripts')) // 只传递更改过的文件 A temp file based caching proxy task for gulp.
.pipe(jshint()) // 对这些更改过的文件做一些特殊的处理...
.pipe(header('(function () {')) // 比如 jshinting ^^^
.pipe(footer('})();')) // 增加一些类似模块封装的东西
.pipe(remember('scripts')) // 把所有的文件放回 stream
.pipe(concat('app.js')) // 做一些需要所有文件的操作
.pipe(gulp.dest('public/'));
}); gulp.task('watch', function () {
var watcher = gulp.watch(scriptsGlob, ['scripts']); // 监视与 scripts 任务中同样的文件
watcher.on('change', function (event) {
if (event.type === 'deleted') { // 如果一个文件被删除了,则将其忘记
delete cached.caches.scripts[event.path]; // gulp-cached 的删除 api
remember.forget('scripts', event.path); // gulp-remember 的删除 api
}
});
});
在 gulp 中运行 Mocha 测试
运行所有的测试用例
// npm install gulp gulp-mocha var gulp = require('gulp');
var mocha = require('gulp-mocha'); gulp.task('default', function() {
return gulp.src(['test/test-*.js'], { read: false })
.pipe(mocha({
reporter: 'spec',
globals: {
should: require('should')
}
}));
});
在文件改动时候运行 mocha 测试用例
// npm install gulp gulp-mocha gulp-util var gulp = require('gulp');
var mocha = require('gulp-mocha');
var gutil = require('gulp-util'); gulp.task('mocha', function() {
return gulp.src(['test/*.js'], { read: false })
.pipe(mocha({ reporter: 'list' }))
.on('error', gutil.log);
}); gulp.task('watch-mocha', function() {
gulp.watch(['lib/**', 'test/**'], ['mocha']);
});
仅仅传递更改过的文件
默认情况下,每次运行时候所有的文件都会传递并通过整个管道。通过使用 gulp-changed 可以只让更改过的文件传递过管道。这可以大大加快连续多次的运行。
// npm install --save-dev gulp gulp-changed gulp-jscs gulp-uglify var gulp = require('gulp');
var changed = require('gulp-changed');
var jscs = require('gulp-jscs');
var uglify = require('gulp-uglify'); // 我们在这里定义一些常量以供使用
var SRC = 'src/*.js';
var DEST = 'dist'; gulp.task('default', function() {
return gulp.src(SRC)
// `changed` 任务需要提前知道目标目录位置
// 才能找出哪些文件是被修改过的
.pipe(changed(DEST))
// 只有被更改过的文件才会通过这里
.pipe(jscs())
.pipe(uglify())
.pipe(gulp.dest(DEST));
});
从命令行传递参数
// npm install --save-dev gulp gulp-if gulp-uglify minimist var gulp = require('gulp');
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify'); var minimist = require('minimist'); var knownOptions = {
string: 'env',
default: { env: process.env.NODE_ENV || 'production' }
}; var options = minimist(process.argv.slice(), knownOptions); gulp.task('scripts', function() {
return gulp.src('**/*.js')
.pipe(gulpif(options.env === 'production', uglify())) // 仅在生产环境时候进行压缩
.pipe(gulp.dest('dist'));
});
$ gulp scripts --env development
gulp入门之常见处理方式(三)的更多相关文章
- 【转】Gulp入门基础教程
Gulp入门基础教程 原文在此 前言最近流行前端构建工具,苦于之前使用Grunt,代码很难阅读,现在出了Gulp, 真是摆脱了痛苦.发现了一篇很好的Gulp英文教程,整理翻译给大家看看. 为什么使用G ...
- 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)
前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...
- Hibernate入门6.Hibernate检索方式
Hibernate入门6.Hibernate检索方式 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv Hibernate的整体框架已经 ...
- (转)前端构建工具gulp入门教程
前端构建工具gulp入门教程 老婆婆 1.8k 2013年12月30日 发布 推荐 10 推荐 收藏 83 收藏,20k 浏览 本文假设你之前没有用过任何任务脚本(task runner)和命令行工具 ...
- 《Gulp 入门指南》 : 使用 gulp 压缩 JS
<Gulp 入门指南> : 使用 gulp 压缩 JS 请务必理解如下章节后阅读此章节: 安装 Node 和 gulp 访问论坛获取帮助 压缩 js 代码可降低 js 文件大小,提高页面打 ...
- Gulp入门与解惑
Gulp简介 Gulp.js 是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务.Gulp.js是基于 Node.js构建的,利用Node.js流的威力,你可以快速构建项目. 安装 ...
- css常见布局方式
CSS常见布局方式 以下总结一下CSS中常见的布局方式.本人才疏学浅,如有错误,请留言指出. 如需转载,请注明出处:CSS常见布局方式 目录: 使用BFC隐藏属性 float + margin abs ...
- 一天带你入门到放弃vue.js(三)
自定义指令 在上面学习了自定义组件接下来看一下自定义指令 自己新建的标签赋予特殊功能的是组件,而指定是在标签上使用类似于属性,以v-name开头,v-on,v-if...是系统指令! v-是表示这是v ...
- 《R语言入门与实践》第三章:R 对象
在这一章,包含的内容有: R 的数据类型 属性 类(特殊的属性) Ruby 的数据结构 R 数据类型 R 可以识别六种类型的数据类型,分别是: double integer character log ...
随机推荐
- Celery - 异步任务 , 定时任务 , 周期任务
1.什么是Celery?Celery 是芹菜Celery 是基于Python实现的模块, 用于执行异步定时周期任务的其结构的组成是由 1.用户任务 app 2.管道 broker 用于存储 ...
- ims注册与注销
ims注册流程: 步骤1:当IMS和SIM访问已经就绪时,IMC将在满足条件后触发IMS注册到IMCB.步骤2.3:IMCB请求IMSA/IMSM获取IMS PDN和P-CSCF,然后触发VoLTE ...
- 4_1.springboot2.xWeb开发使用thymeleaf
1.简介 如果使用SpringBoot: 1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来: ...
- 04_Mybatis输入\出映射
1. 输入映射 通过paramterType指定输入参数的类型,类型可以是简单类型.hashmap.pojo的包装类. 1.1 传递pojo的包装对象 1.需求 完成用户信息的综合查询,需要传 ...
- <Django> MVT三大块之Models(模型)
1.ORM(对象-关系-映射)---面向对象,不需要面向SQL语句 根据对象的类型生成表结构 将对象.列表的操作,转化成SQL语句 将SQL语句查询的结果转化成对象.列表 目的:实现数据模型与数据库的 ...
- CF755F PolandBalls and Gifts
题意:给你一个礼物的置换.有k个人忘带了礼物.一个人无法获得礼物为他自己没有带礼物或给他带礼物的那个人没有带礼物.求选择k个人,没有获得礼物的人数的最小值和最大值. n,k<=1e6. 标程: ...
- LoadRunner例子:检查点为参数的一个例子
LoadRunner例子:检查点为参数的一个例子 检查点是LoadRunner的一个功能,用来验证业务功能的正确性.如果检查的内容是变化的,脚本该如何写呢? 问题提出:LoadRunner订票网站例子 ...
- lumen框架使用Elasticsearch详解
该博文是集合几个博客踩坑得来的,百度热搜前几篇都是缺胳膊少腿的,所以结合几篇博客实现了一遍. 一.lumen使用Elasticsearch 首先需要搭建好的elasticsearch环境: http: ...
- 组件:基础的基础组件(Component,Portlet)
<!DOCTYPE html> <html lang="zh"> <head> <title></title> < ...
- PAT甲级——A1097 Deduplication on a Linked List
Given a singly linked list L with integer keys, you are supposed to remove the nodes with duplicated ...