Gulp:插件编写入门
之前挖了个坑,准备写篇gulp插件编写入门的科普文,之后迟迟没有动笔,因为不知道该肿么讲清楚Stream这货,毕竟,gulp插件的实现不像grunt插件的实现那么直观。
好吧,于是决定单刀直入了。文中插件示例可在这里找到:https://github.com/chyingp/gulp-preprocess
写在前面
我们来看看下面的gruntfile,里面用到了笔者刚写的一个gulp插件gulp-preprocess。好吧,npm publish的时候才发现几个月前就被抢注了。为什么星期天晚上在 http://npmjs.org/package/ 上没有搜到 TAT
这个插件基于preprocess这个插件,插件使用方法请自行脑补。本文就讲解下如何实现 gulp-preprocess 这个插件
var gulp = require('gulp'),
preprocess = require('gulp-preprocess');
gulp.task('default', function() {
gulp.src('src/index.html')
.pipe(preprocess({USERNAME:'程序猿小卡'}))
.pipe(gulp.dest('dest/'));
});
进入实战
关键代码
我们来看下最关键的几行代码。可以看到,上文的 preprocess() 的作用就是返回一个定制的 Object Stream ,这是实现gulp的流式操作必需的,其他gulp插件也大同小异。
gulp-preprocess/index.js
module.exports = function (options) {
return through.obj(function (file, enc, cb) {
// 主体实现忽略若干行
});
};
接着,看下具体实现。实际上代码很短
引入依赖
首先,引入插件的依赖项。其中:
- gutil:按照gulp的统一规范打印错误日志
- through2:Node Stream的简单封装,目的是让链式流操作更加简单
- preprocess:文本预处理器,主要就是文本替换啦
'use strict';
var gutil = require('gulp-util');
var through = require('through2');
var pp = require('preprocess');
核心逻辑
其次,定义gulp-preprocess的主体代码。没错,就是下面这么短的代码。代码结构也比较清晰,下面还是简单做下分解介绍。
module.exports = function (options) {
return through.obj(function (file, enc, cb) {
if (file.isNull()) {
this.push(file);
return cb();
}
if (file.isStream()) {
this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
return cb();
}
var content = pp.preprocess(file.contents.toString(), options || {});
file.contents = new Buffer(content);
this.push(file);
cb();
});
};
核心代码分解
还是直接上代码,在关键位置加上注释。对 through2 不熟悉的童鞋可以参考这里
module.exports = function (options) {
return through.obj(function (file, enc, cb) {
// 如果文件为空,不做任何操作,转入下一个操作,即下一个 .pipe()
if (file.isNull()) {
this.push(file);
return cb();
}
// 插件不支持对 Stream 对直接操作,跑出异常
if (file.isStream()) {
this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
return cb();
}
// 将文件内容转成字符串,并调用 preprocess 组件进行预处理
// 然后将处理后的字符串,再转成Buffer形式
var content = pp.preprocess(file.contents.toString(), options || {});
file.contents = new Buffer(content);
// 下面这两句基本是标配啦,可以参考下 through2 的API
this.push(file);
cb();
});
};
写在后面
要把gulp插件内部实现的原理讲透不是件容易的事情,因为实现还是比较复杂的,首先需要对Buffer、Stream 有一定的了解,包括如何通过Node暴露的API对Stream进行定制化。可以参考笔者的另一篇随笔《gulp.src()内部实现探究》,虽然也只是讲了很小的一部分。
Gulp:插件编写入门的更多相关文章
- 如何编写一个gulp插件
很久以前,我们在"细说gulp"随笔中,以压缩JavaScript为例,详细地讲解了如何利用gulp来完成前端自动化. 再来短暂回顾下,当时除了借助gulp之外,我们还利用了第三方 ...
- chrome插件编写基本入门
chrome插件编写基本入门 http://igeekbar.com/igeekbar/post/331.htm #精选JAVASCRIPTCHROME 作为一名程序猿,怎么能不会写chrome插件 ...
- Gulp资料大全:入门、插件、脚手架、包清单
awesome-gulp中文版 一份gulp的资源,插件和使用实例清单, 致力于打造更好的前端工程构建流程. 被老外的awesome 清单刺激到,觉得有必要翻译一份,为国产的程序员们做点事情,本清单将 ...
- gulp 插件
原文链接:http://www.mamicode.com/info-detail-517085.html gulp是什么? http://gulpjs.com/ 相信你会明白的! 与著名的构建工具gr ...
- 将less编译成css的gulp插件
简介:gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成:使用她,我们不仅可以很愉快的编写代码, ...
- 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)
前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...
- jQuery插件编写及链式编程模型小结
JQuery极大的提高了我们编写JavaScript的效率,让我们可以愉快的编写代码,做出各种特效.大多数情况下,我们都是使用别人开发的JQuery插件,今天我们就来看看如何把我们常用的功能做出JQu ...
- gulp.js基础入门
安装 Node 去 nodejs.org 根据系统选择性按照教程安装Node. 创建项目 创建项目文件夹 进入项目文件夹 初始化项目 使用npm命令:npm init,根据提示完成. 安装 Gulp ...
- gulp插件(gulp-jmbuild),用于WEB前端构建
源码地址:https://github.com/jiamao/gulp-jmbuild https://github.com/jiamao/gulp-jmbuild gulp-jmbuild gulp ...
随机推荐
- SQL Server 查询表的字段对应描述、数据类型、长度
create procedure proc_view_cloumns ( ) ) AS select b.name,a.value,c.name, b.max_length from sys.exte ...
- heckboxlist详细用法、checkboxlist用法、checkboxlist
heckboxlist详细用法.checkboxlist用法.checkboxlist for (int i = 0; i < CheckBoxList1.Items.Count; i++) { ...
- windows环境下lib和dll的区别和联系详细
https://blog.csdn.net/ghevinn/article/details/43759655 c++中共有两种库:1.LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代 ...
- mysql数据库管理工具(navicat for mysql) 10.1.7 绿色中文版
Navicat for MySQL:Navicat for MySQL 是一套专为 MySQL 设计的高性能数据库管理及开发工具.它可以用于任何版本 3.21 或以上的 MySQL 数据库服务器,并支 ...
- 端口扫描--zmap
ZMap被设计用来针对整个IPv4地址空间或其中的大部分实施综合扫描的工具.ZMap是研究者手中的利器,但在运行ZMap时,请注意,您很有 可能正在以每秒140万个包的速度扫描整个IPv4地址空间 . ...
- C++构造析构函数生命期及对象生命期
- jumperserver docker部署
最近在考虑 系统安全问题,jumperserver 用docker 部署比较简单1. 安装redis2.安装mariadb create database jumpserver charset='ut ...
- App常见产品问题及预防方法
01界面适配 a:手机分辨率为1920x7080的高分辨率手机,在调整手机字体大小时,会导致页面显示出现变形: b:因用户设置的特殊字体导致列表的字母条不显示: c:某些banner 图片在部分机型只 ...
- Postman-自动化传参
一,自动化传参 在实现接口自动测试的时候,会经常遇到接口参数依赖的问题,例如调取登录接口的时候,需要先获取登录的key值,而每次请求返回的key值又是不一样的,那么这种情况下,要实现接口的自动化,就要 ...
- Ant在MyEclipse中的配置总结
1.在配置Ant之前,先要配置好JDK的JAVA_HOME和path:之后下载解压apache-ant-1.7.1;并配置环境变量ANT_HOME(安装目录,后不可以加分号:)及其path(安装目录/ ...