gulp尝试开发
背景
这是挺久之前的事情了,还是觉得先记录下来,免得自己忘记了。
在实习的公司做web开发,gulp 是经常用到的,可是我做的不仅仅的前端,还包括后台,
所以将前端文件移至后台这种事当然也需要我做啦,用gulp,但是,文件移至后台目录后,资源文件的路径必须修改,
(我做的后台的是用express做的),一时间,没有找到适合的插件,于是我萌生了自己开发一下gulp插件的想法。
开发流程
参考了几篇博客
Gulp插件制作指南
Gulp:插件编写入门  
先来看一下插件的全部代码
'use strict';
var gutil = require('gulp-util');
var through = require('through2');
const PLUGIN_NAME = 'gulp-url-replace';
module.exports = function (options) {
    var pattern = [];
    var testClose = /\/$/;
    var pp;
    for (pp in options) {
        var odir = {};
        if (testClose.test(pp)) {
            odir.o = new RegExp(pp, 'g');
        }
        else {
            odir.o = new RegExp(pp + '/', 'g');
        }
        if (testClose.test(options[pp])) {
            odir.n = options[pp];
        }
        else {
            odir.n = options[pp] + '/';
        }
        pattern.push(odir);
    }
    return through.obj(function (file, enc, cb) { //流/编码/回调
        if (typeof options !== 'object') {
            this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return 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 = file.contents.toString();
        pattern.forEach(function (r) {
            content = content.replace(r.o, r.n);
        });
        file.contents = new Buffer(content);
        this.push(file);
        cb();
    });
};
省略出主干就是
//引入依赖
var gutil = require('gulp-util');
var through = require('through2');
//暴露主函数
module.exports = function (options) {
    //返回处理流 Node Stream
    return through.obj(function (file, enc, cb) {
        // 主体处理
    });
};
下面分步解释:
引入依赖模块
ar gutil = require('gulp-util');
var through = require('through2');
gulp-util: 错误日志打印模块,按照gulp的统一规范打印错误日志
through2: Node Stream的简单封装,目的是让链式流操作更加简单
gulp 的 through2 开发标准样例
const PLUGIN_NAME = 'gulp-url-replace';
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();
        }
        // 将文件内容转成字符串
        var content = file.contents.toString();
        //对文件内容处理
        content = dosomething(content);
        // 然后将处理后的字符串,再转成Buffer形式
        file.contents = new Buffer(content);
        // 下面这两句基本是标配啦,可以参考下 through2 的API
        this.push(file);
        cb();
    });
};
以上两步就是开发gulp插件的步骤了
gulp-url-replace 核心逻辑
//正则保存的数组
var pattern = [];
//测试 源路径是否以“/”结尾
    var testClose = /\/$/;
    var pp;
    // odir参数正则话,并统一以“/”结尾
    for (pp in options) {
        var odir = {};
        if (testClose.test(pp)) {
            odir.o = new RegExp(pp, 'g');
        }
        else {
            odir.o = new RegExp(pp + '/', 'g');
        }
        if (testClose.test(options[pp])) {
            odir.n = options[pp];
        }
        else {
            odir.n = options[pp] + '/';
        }
        pattern.push(odir);
    }
    //省略
    //转化成字符串
    var content = file.contents.toString();
    //循环正则替换
    pattern.forEach(function (r) {
        content = content.replace(r.o, r.n);
    });
    //转化回node stream
    file.contents = new Buffer(content);
    //省略
如此,就完成了html中资源路径的替换
注意点
gulp的流处理是逐个处理的
例如
gulp.src('./1.txt,./2.txt')
.pipe(replace())
...
那么 replace() 就会执行两次,两次传入的 file 分别是 1.txt和2.txt,
而不是两个文件一起传进来
使用
npm install gulp-url-replace --save-dev
var gulp = require('gulp');
var replace = require('gulp-url-replace')
gulp.task('move', function(){
    gulp.src('./*.html')
    .pipe(replace({
                      'lib/': '<%= stHost %>/node/public/lib/',
                      'img/':'<%= stHost %>/node/public/img/',
                      'css/': '<%= stHost %>/node/public/css/',
                      'js/': '<%= stHost %>/node/public/js/',
                  }))
    .pipe(gulp.dest("../production/views/"))
})
总结
虽然写法,publish,测试方面都不规范,但是,也是学到了gulp开发的一点知识,
以后可以自己本地做些可能用到的gulp插件
目前源代码已经发布在 github上
gulp-url-replace