<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
        當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

        gulp進(jìn)階-自定義gulp插件_html/css_WEB-ITnose

        來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 16:36:50
        文檔

        gulp進(jìn)階-自定義gulp插件_html/css_WEB-ITnose

        gulp進(jìn)階-自定義gulp插件_html/css_WEB-ITnose:gulp已經(jīng)成為很多項(xiàng)目的標(biāo)配了,gulp的插件生態(tài)也十分繁榮,截至2015.1.5,npm上已經(jīng)有10190款gulp插件供我們使用。我們完全可以傻瓜式地搭起一套構(gòu)建。 然而,我們經(jīng)常會(huì)遇到一種情況,我們好不容易按照文檔傳入對(duì)應(yīng)的參數(shù)調(diào)用了插件,卻發(fā)現(xiàn)結(jié)果不如預(yù)期,
        推薦度:
        導(dǎo)讀gulp進(jìn)階-自定義gulp插件_html/css_WEB-ITnose:gulp已經(jīng)成為很多項(xiàng)目的標(biāo)配了,gulp的插件生態(tài)也十分繁榮,截至2015.1.5,npm上已經(jīng)有10190款gulp插件供我們使用。我們完全可以傻瓜式地搭起一套構(gòu)建。 然而,我們經(jīng)常會(huì)遇到一種情況,我們好不容易按照文檔傳入對(duì)應(yīng)的參數(shù)調(diào)用了插件,卻發(fā)現(xiàn)結(jié)果不如預(yù)期,

        gulp已經(jīng)成為很多項(xiàng)目的標(biāo)配了,gulp的插件生態(tài)也十分繁榮,截至2015.1.5,npm上已經(jīng)有10190款gulp插件供我們使用。我們完全可以傻瓜式地搭起一套構(gòu)建。

        然而,我們經(jīng)常會(huì)遇到一種情況,我們好不容易按照文檔傳入對(duì)應(yīng)的參數(shù)調(diào)用了插件,卻發(fā)現(xiàn)結(jié)果不如預(yù)期,這時(shí)候我們就要一點(diǎn)點(diǎn)去排錯(cuò),這就要求我們對(duì)gulp插件的工作原理有一定的了解。本文以實(shí)現(xiàn)一個(gè)gulp插件為例,講解一下gulp插件是如何工作的。

        需求描述

        通常,我們的構(gòu)建資源為js/css/html以及其它的一些資源文件,在開(kāi)發(fā)或發(fā)布階段,js/css會(huì)經(jīng)過(guò)合并,壓縮,重命名等處理步驟。

        有些場(chǎng)景下,我們不能確定經(jīng)過(guò)構(gòu)建后生成js/css的名稱或者數(shù)量,如此就不能在HTML文件中寫死資源的引用地址,那么該如何實(shí)現(xiàn)一個(gè)Gulp的插件用以將最終生成的資源文件/地址注入到HTML中呢?

        假設(shè)我們需要實(shí)現(xiàn)的插件是這樣使用方式:

          

        我們通過(guò)一個(gè)HTML注釋用以聲明需要依賴的資源,InlineResource 是匹配的關(guān)鍵詞,":"做為分割,/*.css$/,/*.js$/ 是聲明要依賴的文件的正則匹配。

        在gulpfile.js我們需要這邊配置:

        gulp.task('dist', function () { return gulp.src('index.html') .pipe(InjectResources( gulp.src(['*.js', '*.css']) .pipe(hash(/*添加MD5作為文件名*/)) )) .pipe(gulp.dest('dist'))})

        這里簡(jiǎn)單介紹下其中的一些方法與步驟:

      1. gulp.src('index.html')會(huì)讀取文件系統(tǒng)中當(dāng)前目錄下的index.html,并生成一個(gè)可讀的Stream,用于后續(xù)的步驟消費(fèi)

      2. InjectResources(stream)是我們將要實(shí)現(xiàn)的插件,它接受一個(gè)參數(shù)用以獲取要注入到HTML中的JS/CSS,此參數(shù)應(yīng)該是一個(gè) Stream實(shí)例,用生成一個(gè)Stream實(shí)例,用于接收并處理上一步流進(jìn)來(lái)的數(shù)據(jù)

      3. hash(options)是一個(gè)第三方插件,用于往當(dāng)前流中的文件名添加md5串,如: gulp-hash

      4. gulp.dest('dist')用于將注入資源后的HTML文件生成到當(dāng)前目錄下

      5. 我們要關(guān)心的是第2點(diǎn):如何接所有的資源文件并完成注入?

        我們可以將該邏輯分成4個(gè)步驟

        1. 獲取所有的js/css資源
        2. 獲取所有的HTML文件
        3. 定位HTML中的依賴聲明
        4. 匹配所依賴的資源
        5. 生成并注入依賴的資源標(biāo)簽

        在開(kāi)編之前,我們需要依賴一個(gè)重要的第三方庫(kù): map-stream

        map-stream 用于獲取當(dāng)前流中的每一個(gè)文件數(shù)據(jù),并且修改數(shù)據(jù)內(nèi)容。

        步驟1 (JS/CSS資源)

        module.exports = function (resourcesStream) { // step 1: TODO => 這里要獲取所有的js/css資源}

        資源流會(huì)作為參數(shù)的形式傳給InjectResources方法,在此通過(guò)一個(gè)異步的實(shí)例方法獲取所有的文件對(duì)象,放到一個(gè)資源列表:

        var resources = []function getResources(done) { if (resources) return done(resources) // 由于下面的操作是異步的,此處要有鎖... resourcesStream.pipe(mapStream(function (data, cb) { resources.push(data) cb(null, data) })) .on('end', function () { done(resources) })}

      6. mapStream的處理方法中獲取到的data是由gulp.src生成的 vinyl對(duì)象,代表了一個(gè)文件
      7. 每一個(gè)stream都會(huì)在接受后拋出end事件
      8. Note: mapStream的處理方法中的cb方法,第二個(gè)參數(shù)可以用于替換當(dāng)前處理的文件對(duì)象

        到此,我們就完成了第一步的封裝啦!

        module.exports = function (resourcesStream) { // step 1: function getResources () { ... }}

        步驟2 (HTML文件)

        module.exports = function (resourcesStream) { // step 1: ?? // step 2: TODO => 獲取當(dāng)前流中的所有目標(biāo)HTML文件 return mapStream(function (data, cb) { })}

        InjectResources插件方法會(huì)返回一個(gè) Writable Stream實(shí)例,用于接收并處理流到InjectResources的HTML文件,mapStream的返回值就是一個(gè)writable stream。

        此時(shí),mapStream的處理方法拿到的data就是一個(gè)HTML文件對(duì)象,接下來(lái)進(jìn)行內(nèi)容處理。

        步驟3 (定位依賴)

        module.exports = function (resourcesStream) { // step 1: ?? // step 2: ? return mapStream(function (data, cb) { var html = data.contents.toString() // step 3: TODO => 獲取HTML中的資源依賴聲明 })}

        我們拿到的data是一個(gè) vinyl對(duì)象,contents屬性是文件的內(nèi)容,類型可能是Buffer也可能是String, 通過(guò)toStraing()后可以獲取到字符串內(nèi)容。

        所有的依賴聲明都有InlineResource關(guān)鍵詞,簡(jiǎn)單點(diǎn)的做法,可以通過(guò)正則來(lái)定位并替換HTML中的資源依賴:

        html.replace(//g, function (expr, fileRegexpStr){ // fileRegexp是用以匹配依賴資源的正則字符串})

        到此,我們完成了資源依賴的定位,下一步將是獲取所依賴的資源用以替換。

        步驟4 (依賴匹配)

        我們將通過(guò)步驟1定義的 getResources 方法獲取所需的資源文件:

        module.exports = function (resourcesStream) { // step 1: ?? // step 2: ? return mapStream(function (data, cb) { // step 3: ? getResources(function (list) { html.replace(depRegexp, function (expr, fileRegexpStr) { var fileRegexp = new RegExp(fileRegexpStr) // step 4: TODO => 獲取匹配的依賴 }) }) })}

        由于 getResources 是異步方法,因此需要把替換處理邏輯包裹在 getResources 的回調(diào)方法中

        根據(jù)依賴聲明中的正則表達(dá)式,對(duì)資源列表一一匹配:

        function matchingDependences(list, regexp) { var deps = [] list.forEach(function (file) { var fpath = file.path if (fileRegexp.test(fpath)) { deps.push(fpath) } }) return deps}

        到此只差最后一步,將資源轉(zhuǎn)換為HTML標(biāo)簽并注入到HTML中

        步驟5 (資源轉(zhuǎn)換/依賴注入)

        module.exports = function (resourcesStream) { // step 1: ?? // step 2: ? return mapStream(function (data, cb) { // step 3: ? // step 4: ? // ... html.replace(depRegexp, function (expr, fileRegexpStr) { var deps = matchingDependences(list, fileRegexpStr) // step 5: 文件對(duì)象轉(zhuǎn)換為HTML標(biāo)簽 }) })}

        接下來(lái)的定義一個(gè)transform方法,用于將路徑列表轉(zhuǎn)換為HTML的資源標(biāo)簽列表,其中引入了 path模塊用于解析獲取文件路徑的一些信息,該模塊是node內(nèi)置模塊。

        var path = require('path') function transform(deps) { return deps.map(function (dep) { var ext = path.extname(dep) switch (ext) { case 'js': '

        最終,我們將標(biāo)簽列表拼接為一個(gè)字符串來(lái)HTML中的依賴聲明(注入):

        html = html.replace(depRegexp, function (expr, fileRegexpStr) { var deps = matchingDependences(list, fileRegexpStr) // step 5: 文件對(duì)象轉(zhuǎn)換為HTML標(biāo)簽 return transform(deps)})// html文件對(duì)象data.contents = new Buffer(html)// 把修改后的文件對(duì)象放回HTML流中cb(null, data)

        到此也就完整地實(shí)現(xiàn)了一個(gè)擁有基本注入功能的插件~~~~~~

        One More Thing

        通過(guò)上面實(shí)現(xiàn)的示例步驟,可以清楚了解到gulp插件的工作原理。 但要做一個(gè)易用/可定制性高的插件,我們還要繼續(xù)完善一下,例如:

      9. 比較資源的路徑與HTML的路徑,輸出相對(duì)路徑作為默認(rèn)的標(biāo)簽資源路徑
      10. 提供 sort 選項(xiàng)方法用于修改資源的注入順序
      11. 提供 transform 選項(xiàng)方法用于定制標(biāo)簽中的資源路徑
      12. 在依賴聲明中支持 inline 聲明,用以將資源內(nèi)容內(nèi)聯(lián)到HTML中,例如:

         

      13. 支持命名空間,用于往同一個(gè)資源流中使用多次資源注入的區(qū)分,例如:

         gulp.src('index.html') .pipe( InjectResources(gulp.src('asserts/*.js'), { name: 'asserts'}) ) .pipe( InjectResources(gulp.src('components/*.js'), { name: 'components'}) ) ...

      14. . . .

      15. 聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        gulp進(jìn)階-自定義gulp插件_html/css_WEB-ITnose

        gulp進(jìn)階-自定義gulp插件_html/css_WEB-ITnose:gulp已經(jīng)成為很多項(xiàng)目的標(biāo)配了,gulp的插件生態(tài)也十分繁榮,截至2015.1.5,npm上已經(jīng)有10190款gulp插件供我們使用。我們完全可以傻瓜式地搭起一套構(gòu)建。 然而,我們經(jīng)常會(huì)遇到一種情況,我們好不容易按照文檔傳入對(duì)應(yīng)的參數(shù)調(diào)用了插件,卻發(fā)現(xiàn)結(jié)果不如預(yù)期,
        推薦度:
        標(biāo)簽: html css gu
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 最近中文字幕国语免费完整 | 亚洲最新黄色网址| 亚洲午夜一区二区电影院| 一区二区三区在线免费看| 亚洲AV无码国产在丝袜线观看| 亚洲精品天堂无码中文字幕| 国产午夜不卡AV免费| 国产精品亚洲片在线观看不卡| 国产一区二区三区免费观在线| 亚洲夜夜欢A∨一区二区三区| 亚洲国产成人无码AV在线| 日本人的色道www免费一区| 亚洲AⅤ男人的天堂在线观看| 亚洲 小说区 图片区 都市| 亚洲av永久无码精品天堂久久| 破了亲妺妺的处免费视频国产| 亚洲美女自拍视频| 免费H网站在线观看的| 久久夜色精品国产噜噜亚洲AV| 久久福利资源网站免费看| 亚洲AV无码国产一区二区三区| 免费中文字幕在线观看| 亚洲av无码专区在线观看下载| 亚洲精品第一国产综合精品99| 亚洲高清毛片一区二区| ZZIJZZIJ亚洲日本少妇JIZJIZ| 十八禁无码免费网站| 亚洲精品人成网在线播放影院| jjzz亚洲亚洲女人| 香蕉免费一区二区三区| 亚洲国产精品网站在线播放| 国产成人亚洲精品狼色在线| 97av免费视频| 真正全免费视频a毛片| 免费一级毛片一级毛片aa| 99久久精品毛片免费播放| 亚洲偷偷自拍高清| 青青草原亚洲视频| 成人黄18免费视频| 日本高清不卡aⅴ免费网站| 亚洲人成未满十八禁网站|