vue-style-loader源碼初步分析

背景:

  首先聲明一下,我只是個菜雞,為了解決問題才去看的源碼,解決完問題之後也就沒有興趣看其他部分代碼了,所以這篇文章是一次很低層次的解讀,角度也相當片面,想必會有很多噴點吧。

  事情的經過是這樣,今年十月底的時候對公司前端產品的構建工具做了一次升級,從webpack1升級到了webpack4,現在已經投入正式環境,寫這篇文章的時候我在外邊出差,忙的時候997,閑的時候也997,這會兒就有點閑得慌,所以就想着把之前的操作復盤總結一遍,這個過程其實非常順利,沒遇到過幾次報錯,打開build出來的文件之後卻讓我莫名的詫異,我的樣式並沒有掛載到dom元素中,但構建過程中並沒有遇到過報錯。我這邊使用的前端框架是vue,由於解析vue文件樣式代碼的過程中需要用到的loader有vue-loader css-loader(或者其他css預處理語言的loader)、vue-style-loader,於是我就把問題定位到了這幾個loader上面。因為之前有成功過的案例,在確認過我的配置跟之前寫的配置一樣之後,我對使用的這些依賴產生了懷疑,但是我實在是很好奇到底是哪個流程中除了問題,所以就對構建流程中這部分的細節進行了一些了解。

  我起了一個新的入口文件和父組件,去除無關的代碼來複現這個問題。

  不多說,直接多圖警告

事 故 現 場

  執行完打包命令之後,按理來說打開dist目錄中的index.html頁面中應該就會出現一個傻不愣登的正方形色塊比如:

  但你我都知道如果這麼順利的話就不會有這篇水文存在了,實際上打開是這樣的:

  我之前大概了解過vue-style-loader是在style-loader的基礎之上寫出來的,主要功能跟style-loader類似,只是多了一些額外的特性,所以我想切換成style-loader試一下,然後愕然發現居然正常了,於是推測問題出在vue-style-loader身上,就在去看依賴的源碼並做了一些嘗試:

 
 
 
 
 
 

  但問題來了:

  我不可能真的去改node_modules中的vue-style-loader,因為每換一個環境,就需要改一次源碼這肯定是不現實的,正確的解決辦法一定不在這裡。

我開始思考vue-style-loader與style-loader的區別,為什麼style-loader就能順利處理esModule呢,然後我在style-loader的代碼中找到了線索,源碼中有個名為options的json文件,描述了這個loader的配置項及其含義,其中有一個esModule屬性:

 
  於是我去github上看了style-loader的發佈歷史,最近的一個版本:
 

  從options中的附帶鏈接也了解到了現在的css-loader也有個配置屬性esModule,從[email protected](2019-12-17)開始,css-loader支持esModule屬性,@4.0.0(2020-07-26)開始這個屬性的默認值為true。

終於破案了,實際上是因為我復盤的時候,安裝的style-loader、vue-style-loader、css-loader沒有指定版本,默認安裝了最新的依賴,css-loader、style-loader都把配置項的esModule默認值設為了true,而vue-style-loader最後一次更新已經是快三年前了,這期間的改動沒有同步,所以vue-style-loader是不處理esModule的,所以這個問題的解決方法就出來了,只需要把css-loader的options添加上esModule:false就能夠解決問題。