vue-cli3.0+webpack4中關於svg-sprite-loader踩坑,讓svg組件徜徉個人web項目

第一次寫文章,今天踩坑事後但願可以記錄這樣'生動有趣'的踩坑之旅,仍是那樣,在技術的海洋中,我和大佬就像魚和水,我沒了大佬就涼了,大佬沒了我還清淨,感謝一路栽培。公司以前的項目都是用vue-cli2.x的腳手架集成的webpack3,可是最近的項目用到@vue/cli3,也就是vue-cli3,最新的腳手架契合webpack4,目前文檔也更新到了這個版本,一開始看目錄結構,納尼!!webpack常規的配置文件build和config文件怎麼沒了,這尼瑪是否是沒有用到自動化構建!!諸如此類的疑問我相信當你第一眼看到這樣簡潔清爽的目錄結構時也會產生,而後我就去看文檔,這裏cli.vuejs.org/zh/guide/,原來腳手架自動幫咱們把webpack的配置集成到了node_modules中 vue

,這樣的目錄結構仍是有些熟悉的。好,那麼疑問又產生了,我如何根據項目須要配置baseUrl,outputDir,assetsDir ,loader等等呢,官方是這樣寫的 調整 webpack 配置最簡單的方式就是在 vue.config.js 中的 configureWebpack 選項提供一個對象 , 總結兩個, configureWebpack, chainWebpack,這也是咱們後面須要用到的兩個屬性,是更改webpack配置的關鍵, configureWebpack屬性值能夠是一個對象或者是一個函數,當爲對象時該對象將會被 webpack-merge 合併入最終的 webpack 配置,這應該是集成第三方插件的用法,另外當屬性值是一個函數的時候,函數的第一個參數是已經解析好的配置,咱們能夠看一下console.log

結果 是
是否是看到了許多熟悉的屬性,是的,這個config就是webpack的基礎配置了,
這裏也返回了vue-cli3給我內置配好的不一樣lodaer,圖中對應每個[object],這也是後來修改和暴力重設loader發現的,彷彿發現新大陸通常的我開始繼續項目了,畢竟大佬給的時間有點緊迫,嚶嚶嚶....,由於種種緣由ui小姐姐無法將有過渡漸變效果的svg圖片放在iconfont上,因此只能本身在項目本地使用svg,參考vue-element-admin中提供一個svg組件的方式,我也這樣作
這是svg圖片的組件目錄結構,接下來是js文件和vue-component

本來的es6箭頭函數看上去比較社會(澀會),因此用es5的方式展現,這裏很是重要的webpack內置api,require.context函數,它接受三個參數,第一個是文件夾,第二個是是否使用子文件,第三個是文件匹配的正則。對於咱們的項目來講,咱們須要動態引入的就是

const req = require.context('./svg', false, /\.svg$/)
複製代碼

require.context會返回一個函數,對應上面的console咱們看一下控制檯node

那麼311這裏對應的這個函數到底表明什麼呢,咱們知道js中函數也是一個對象,那麼這個函數有神馬不一樣,點開看一下:
,哇,看到這個我心態都蹦了,還很激動,這個方法會把咱們剛剛聯繫的上下文中的svg所有寫入一個map對象,而這個方法也本身定義了keys方法,用來遍歷map,遍歷後的key能夠做爲 webpackContext(key)的參數,從而導出每個svg,咱們看一下導出的requireAll(req)(對應圖中,也就是前面說到的webpackContext(key))
果真如所說的,導出了每個map中對應的svg圖,可是可能會有所疑問爲何不是鍵值形式對應的值,以下:
這裏就要說到遇到的第一個坑了,常規按照腳手架的設置,對svg圖片的處理會通過file-loader進行文件轉化,咱們知道這種工程化項目在跑起來時內部會生產一個隱式的dist包,全部的靜態資源都會被打包進dist/assets/下,這裏也不例外,因此我console.log出來後全是諸如此類的"assets/img/daily-mission83544646.svg "如此的通過其餘loader轉化的svg圖片,可是這樣寫的話咱們的svg組件是無法經過use標籤拿到對應svg圖片的,這裏參考一下張鑫旭大神的關於svg的講解 將來必熱 ,因此咱們只能更改腳手架的默認配置,經過svg-sprite-loader生成對應的svg精靈圖供咱們組件使用,思路回到前文提到的兩種配置更改webpack的思路,由於沒有用過,因此此坑必填。使用configWebpack:config=>{}這種方式去合併或者添加svg-sprite-loader的方法雖然在rules中增長了該lodaer,可是不知道是由於已經有了其餘loader解析svg或者腳手架的基礎poader配置權限最高問題,svg圖片始終得不到正確的處理,此方法(失敗)代碼:

configWebpack:config =>{
   config.module.rules.push(
           {
               test: /\.svg$/,
               loader: 'svg-sprite-loader',
               include: [resolve('src/icons')],
               options: {
                   symbolId: 'icon-[name]'
               }
           }
       )
}
複製代碼

結果無功而返,參考了文檔後發現了重設loader的配置方法,那就是經過chainWebpack,經過鏈式操做來修改配置,官方給出的結論 是能夠容許咱們更細粒度的控制其內部配置,提供了一個 webpack 原始配置的上層抽象,使其能夠定義具名的 loader 規則和具名插件,並有機會在後期進入這些規則並對它們的選項進行修改。對於這句話我目前還不是很理解,真是隻在此山中,雲深不知處!若是合併不行,那就替換!webpack

chainWebpack: config => {
        const svgRule = config.module.rule('svg');
         svgRule.uses.clear();
         svgRule
            .test( /\.svg$/)
            .use('svg-sprite-loader')
           .loader('svg-sprite-loader')
           .options({
              symbolId: 'icon-[name]'
          });
      }
複製代碼

如此~svg成功經過此loader解析,咱們也獲得了須要的svg圖片模塊,可是既然知道合併不行,替換能夠,若是不但願用鏈式操做的話這裏也列出一種暴力的方法去修改,一樣經過configWebpackes6

configureWebpack: config => {
       console.log(config)
       let rules=config.module.rules;
       for(let i in rules){
           console.log(rules[i]);
           if(rules[i].use && rules[i].use[0].loader=='file-loader'){
               rules.splice(i,1)
           }
       }

       config.module.rules.push(
           {
               test: /\.svg$/,
               loader: 'svg-sprite-loader',
               include: [resolve('src/icons')],
               options: {
                   symbolId: 'icon-[name]'
               }
           }
       )
   }
複製代碼

如今這樣的話,刪除了file-loader,其實和替換同樣,可是看上去暴力一些,效果確是相同的。至此,大佬和個人加班時間也到了末尾,感受很累,可是感受收穫頗豐,走出公司,風呼嘯着略過個人雙肩揹包,我聳了下眼鏡,走向昏黃的公交車站。感謝!web

相關文章
相關標籤/搜索