2018-04-20style-loader添加一點(diǎn)功能

style-loader支持在options中設(shè)置一些attrs屬性,這些屬性將被添加到創(chuàng)建的style標(biāo)簽上,最終添加到dom樹(shù)里

這本功能在開(kāi)發(fā)調(diào)試時(shí)是很有用的,比如我們通過(guò)他可以知道樣式的源文件與插入的style的對(duì)應(yīng)關(guān)系,從而去檢查是否被正確處理了,以及他們加載的順序是怎樣的

但是當(dāng)前的style-loader中定義的attrs只能是靜態(tài)屬性,不支持像file-loader定義name那樣的占位符

翻看style-loader的issues,有人提過(guò)這樣的需求,但是他建議的是把node_modules中的ui組件里的樣式加上組件的id和version, 而我想的是把文件的路徑添加進(jìn)去

知道想做什么之后,就是研究怎么實(shí)現(xiàn)了,
翻看file-loader得知使用了loader-utils模塊的 interpolateName 方法

照葫蘆畫瓢
首先給style-loader的attrs設(shè)置上帶占位符的屬性

{
  loader: 'style-loader',
  options:{
    attrs:{
    path: '[path][name].[ext]'
    }
  }
}

然后在style-loader中處理
注意style-loader是pitch類Loader, 與普通loader不同,區(qū)別在他們的執(zhí)行順序上
普通loader的順序類似于參數(shù)傳參,比如
use:[
'a-loader',
'b-loader',
'c-loader',
]
其中a,b,c三個(gè)Loader都是普通loader,
那么他們的執(zhí)行順序?yàn)?br> a-loader(b-loader(c-loader(request)))

而如果a-loader為pitch類loader, 那么順序可能變成

a-loader.pitch(request);
b-loader(c-loader(request));

也可能變成其他順序,由a-loader.pitch具體實(shí)體決定,比如他可以返回一段代碼,也可以直接攔截掉

在style-loader里,
我們需要把options.attrs的內(nèi)容用loader-utils.interpolateName方法優(yōu)先處理,再傳給其生成的代碼,也就是使用addStyles處理,
為什么要優(yōu)先處理,是因?yàn)閍ddStyles接收的是css-loader返回的內(nèi)容,而css-loader返回的內(nèi)容不是原始的content, 同時(shí)其執(zhí)行的上下文已經(jīng)不是webpack的環(huán)境,而是瀏覽器,此時(shí)是沒(méi)有resourcePath等內(nèi)容的,所以我們只能在pitch階段把a(bǔ)ttrs處理好

處理也不難,下面這段代碼添加到 使用JSON.stringify(options)之前

 const context = options.context || this.rootContext || (this.options && this.options.context); 
 for(let key in options.attrs||{}){                                
   let name = loaderUtils.interpolateName(this,options.attrs[key],{                
     context, 
     content:null,
     regExp:options.regExp,    
   });
   options.attrs[key]=name; 
 } 

效果有了,但是有個(gè)問(wèn)題,多個(gè)style標(biāo)簽的path屬性都一樣,即第一次的那個(gè)。
經(jīng)過(guò)一番排查,找到原因,
options是個(gè)對(duì)象是這么來(lái)的

var options = loaderUtils.getOptions(this) || {};

因?yàn)槲覀兣渲脮r(shí)使用的是options:{attrs:{}} 對(duì)象的形式,而不是queryString的方式,getOptions方法直接返回原來(lái)的對(duì)象,導(dǎo)致1次修改之后,覆蓋了原來(lái)的占位符,然后后續(xù)的style不正常

解決辦法就是對(duì)其deepClone, 這樣不影響webpack loaders中的配置

 var options = {...(loaderUtils.getOptions(this) || {})}; 
 options.attrs = {...(options.attrs||{})}                 

終于正常


image.png

vs


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,551評(píng)論 19 139
  • 版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一、webpack介紹 1、由來(lái) ...
    it筱竹閱讀 11,457評(píng)論 0 21
  • GitChat技術(shù)雜談 前言 本文較長(zhǎng),為了節(jié)省你的閱讀時(shí)間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,891評(píng)論 7 110
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,271評(píng)論 6 342
  • (一) 我正在做一個(gè)夢(mèng),夢(mèng)里我開(kāi)著一輛赤紅色的越野車,在沙漠狂奔,跑著跑著就到了高速公路,迎面一輛大貨車兇神惡煞地...
    米小姐_M閱讀 198評(píng)論 0 0

友情鏈接更多精彩內(nèi)容