Gulp:插件编写入门
写在前面
我们来看看下面的 gruntfile
,里面用到了笔者刚写的一个 gulp 插件 gulp-preprocess
。好吧,npm publish 的时候才发现几个月前就被抢注了。为什么星期天晚上在 http://npmjs.org/package/ 上没有搜到 TAT。
文中插件示例可在这里找到:https://github.com/chyingp/gulp-preprocess
这个插件基于 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 进行定制化。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 前端模块规范
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论