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()內部實現探究》,雖然也只是講了很小的一部分。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM