免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Gulp.js深入講解
ria之家 2014-03-02 7082 閱讀
javascript
上周明河發(fā)了篇《Gulp.js—比Grunt更易用的前端構(gòu)建工具》,同時(shí)也貼在阿里的技術(shù)站上,引起了不少前端同學(xué)的討論。
赤溫(開發(fā)工程師)說:這東西(Gulp.js與Grunt)差距不大,社區(qū)才是王道!
英布(高級前端開發(fā)工程師)說:一個(gè)是以配置的方式,一個(gè)是以編程的方式,感覺各有千秋吧,復(fù)雜流程還是使用編程的方式比較好,簡單的那就隨便了。
誠冉(前端開發(fā)工程師)說:曾經(jīng)苦于將grunt的各個(gè)工具黏合在一起的過程,grunt這個(gè)東西生出來就不是給小項(xiàng)目用的,必須是一定規(guī)模的并且持續(xù)更新的項(xiàng)目,才舍得花這么大力氣來“制造工具”。一點(diǎn)也不夸張,雖然grunt的組件越來越多,但概念就像import一樣,稱不上是框架,頂多是一種合作機(jī)制。Nodejs的世界里,好像不跟stream和pipe沾點(diǎn)邊的概念都不好用似的,現(xiàn)在寫Web服務(wù)框架,基本都跟connect一個(gè)風(fēng)格,req和res一層一層的流經(jīng)各個(gè)handler。剛一看到glup下意識的覺得有點(diǎn)俗氣了,但是想想U(xiǎn)nix的哲學(xué),標(biāo)準(zhǔn)化的輸入輸出,不需要過多的元信息描述,簡單實(shí)用,組件連接起來產(chǎn)生的巨大威力,任何人都無法拒絕!
獵隼(資深前端開發(fā)工程師)說:基于node.js的工具有一點(diǎn)讓人深惡痛絕:會(huì)創(chuàng)建一個(gè)文件夾,而且里邊的文件有大量的冗余。這對項(xiàng)目文件是一種污染,很有可能讓一些不明真相的工具把這些代碼也一起搜索了,比如一些查找替換程序。比較喜歡ruby的管理方式,需要的包在本機(jī)只需要安裝一次,而且不會(huì)像node那樣創(chuàng)建一個(gè)文件夾
半邊同學(xué)推薦了一個(gè)討論Gulp.js與Grunt的issue,明河也推薦一篇文章《No Need To Grunt, Take A Gulp Of Fresh Air》。
Gulp.js處理構(gòu)建任務(wù)如下圖:
Grunt處理任務(wù):
(上圖來自http://slid.es/contra/gulp
理解Gulp.js的核心設(shè)計(jì)
streaming很容易聯(lián)想到河流,河流有哪些特征?流動(dòng)、源源不斷、具有方向、有起點(diǎn)、有終點(diǎn),而這些特征也是Gulp.js構(gòu)建代碼的特點(diǎn)。
Gulp.js官網(wǎng)上的簡介是The streaming build system,核心的詞是streaming(流動(dòng)式),如何理解這個(gè)詞呢?《Gulp.js—比Grunt更易用的前端構(gòu)建工具》,明河講到Gulp.js的精髓在于對Node.js中Streams API的利用,所以想要理解Gulp.js,我們必須理解Streams,streaming其實(shí)就是Streams的設(shè)計(jì)思想。
流(stream)的概念來自unix,核心思想是do one thing well,一個(gè)大工程系統(tǒng)應(yīng)該是由各個(gè)小且獨(dú)立的管子連接而成,如誠冉同學(xué)所說:Unix的哲學(xué),標(biāo)準(zhǔn)化的輸入輸出,不需要過多的元信息描述,簡單實(shí)用,組件連接起來產(chǎn)生的巨大威力,任何人都無法拒絕!,如下圖:
推薦下《stream-handbook》,非常詳細(xì)地說明了如何使用Streams,也提供了很多Streams的第三方模塊供參考。
我們以經(jīng)典的Nodejs讀取文件邏輯來說明Streams與傳統(tǒng)方式的差異。
使用fs模塊讀取一個(gè)json文件
傳統(tǒng)的方式:
var dataJson, fs;fs = require('fs');dataJson = './gallery-db/component-info.json';exports.all = function(req, res) { fs.readFile(dataJson,function(err, data){ if (err) { console.log(err); } else { res.end(data); } });};
fs.readFile()是將文件全部讀取放進(jìn)內(nèi)存,然后觸發(fā)回調(diào),這種方式存在二方面的瓶頸。
1.讀取大文件時(shí)容易造成內(nèi)存泄漏
比如一個(gè)上傳視屏的服務(wù),面對少者二三百M(fèi),多者七八G的文件,明顯這種方式不可行,所以我們需要分?jǐn)嗌蟼鳎绻褂脗鹘y(tǒng)方式,就會(huì)發(fā)現(xiàn)非常蛋疼,估計(jì)沒人想這么干….
2.深惡痛絕的回調(diào)問題
這是我自己寫NodeJs代碼最深惡痛絕的地方,在提供大的服務(wù)時(shí),比如讀取4-5個(gè)文件,回調(diào)層層嵌套,可讀性和維護(hù)性非常大,惡心指數(shù)陡增。
而且每次你都要對err進(jìn)行處理:
if (err) { console.log(err);} else { //...}
代碼啰嗦,不夠簡練。koa已經(jīng)解決了這個(gè)問題,NodeJs的發(fā)展史就是跟回調(diào)斗爭史啊。
流的方式:
var dataJson, fs;fs = require('fs');dataJson = './gallery-db/component-info.json';exports.all = function(req, res) { var stream; stream = fs.createReadStream(dataJson); stream.on('error', function(err) { return console.log(err); }); stream.on('data', function(chunk) { return console.log('got %d bytes of data', chunk.length); }); return stream.pipe(res);};
fs.createReadStream()創(chuàng)建一個(gè)readable streams(只讀的流),請看《stream-handbook》中的readable streams部分,readable streams是有狀態(tài)的,比如可以監(jiān)聽其data事件,讀取數(shù)據(jù)后會(huì)觸發(fā),比如error事件,讀取數(shù)據(jù)失敗后會(huì)觸發(fā)。
stream.pipe(res),pipe方法是流對象的核心方法,這句代碼可以理解為,res(結(jié)果集,實(shí)際上是一個(gè)writeable streams,寫流)對象接收從stream而來的數(shù)據(jù),并予以處理輸出。所以Gulp.js中的pipe()方法并不是gulp的方法,而是流對象的方法。pipe()返回的是res的返回的對象。
上述代碼會(huì)把component-info.json的內(nèi)容打印出來。
流的種類有:readable streams、writeable streams(比如Gulp.js中的gulp.dest(‘./build’)f方法)、transform(明河很不喜歡這個(gè)詞,詞不達(dá)意,稱之為through更為合適,表示這是讀/寫流,后面會(huì)詳細(xì)講解)streams,duplex streams(duplex可以理解為循環(huán)的流,比如服務(wù)器端和客戶端的實(shí)時(shí)通信,由于與Gulp.js無關(guān),不展開講)。
如何開發(fā)個(gè)Gulp.js插件?
所有的Gulp.js插件基本都是through(后面不再使用transform這個(gè)詞) streams,即是消費(fèi)者(接收gulp.src() 傳遞出來的數(shù)據(jù),然后進(jìn)行處理加工處理),又是生產(chǎn)者(將加工后的數(shù)據(jù)傳遞出去),我們以gulp-clean為例(這個(gè)插件用于清理目錄和文件)。
先看下gulp-clean的API用法:
var gulp = require('gulp');var clean = require('gulp-clean');gulp.task('default', function() { gulp.src('app/tmp') .pipe(clean());});
非常簡單的代碼,目的是殘忍地將tmp目錄干掉。
gulp-clean的源碼傳送門。
引入依賴模塊
var rimraf = require('rimraf');var es = require('event-stream');var gutil = require('gulp-util');var path = require('path');
rimraf 模塊用于刪除目錄。
gulp-clean插件使用了個(gè)through streams的包裝模塊:event-stream,用于簡化streams調(diào)用的api,明河推薦使用through2,會(huì)更好用。
path 模塊就不說了,大家太熟悉了。
定義供外部調(diào)用插件方法
module.exports = function (options) { return es.map(function (file, cb) { //具體業(yè)務(wù)邏輯 });};
es.map()會(huì)創(chuàng)建一個(gè)through streams,我們只要關(guān)注寫業(yè)務(wù)邏輯就好,不用關(guān)注如何創(chuàng)建streams。
file為上游讀流產(chǎn)生的文件數(shù)據(jù),cb是核心方法用于向下游傳遞處理后的數(shù)據(jù)。
return cb(null, file);具體業(yè)務(wù)代碼
// 獲取文件絕對路徑var filepath = file.path;var cwd = file.cwd;var relative = path.relative(cwd, filepath);// 防止路徑錯(cuò)誤if (!(relative.substr(0, 2) === '..') && relative !== '' || (options ? (options.force && typeof options.force === 'boolean') : false)) { //刪除目錄 rimraf(filepath, function (error) { if (!error) { return cb(null, file); } else { return cb(new Error('Unable to delete "' + filepath + '" file (' + error.message + ').'), file); } });//打印錯(cuò)誤消息} else if (relative === '') { gutil.log('gulp-clean: Cannot delete current working directory. (' + filepath + ')'); return cb(null, file);}//打印錯(cuò)誤消息else { gutil.log('gulp-clean: Cannot delete files outside the current working directory. (' + filepath + ')'); return cb(null, file);}
代碼非常簡單,獲取文件(目錄)路徑,調(diào)用rimraf()刪除之即可。
一個(gè)簡單的Gulp.js插件就完成了,so easy!
總結(jié)
Gulp.js的使用和插件的開發(fā)都很簡單,當(dāng)然里面還有很多細(xì)節(jié),明河就不展開講了,請看Gulp.js的官方文檔。
javascript
作者:ria之家
RIA三部曲:jquery、ext、flex
原文地址:Gulp.js深入講解, 感謝原作者分享。
發(fā)布kissy小工程構(gòu)建器generator-bee從Gulp.js聊聊streams(PPT)
評論
這是Gulp.js視頻教程: http://www.oxox.work/web/recommend/gulp-js/
|  就要發(fā)給你 發(fā)表于 10月前
發(fā)表評論
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
PostCSS
Gulp解決發(fā)布線上文件(CSS和JS)緩存問題
常用gulp插件介紹(一)
加速hexo
前端構(gòu)建工具gulp入門教程
gulp自動(dòng)化任務(wù)腳本在HybridApp開發(fā)中的使用
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服