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屬性:
從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就能夠解決問題。