vue中babel-plugin-component按需引入和element-ui 的主題定製,支援釋出,上線

語言: CN / TW / HK

前言

目前專案用的vue + element-ui,之前有了解過element-ui真正的按需引入,也有了解到主題定製,之前的專案都是根據element-ui的類及標籤,在全域性或者區域性進行一大堆樣式覆蓋,達到自己專案ui的樣式,專案中按需引入實際也並沒有真正實現按需引入。趁此新起的專案。實踐一下對 element-ui 主題和元件方面來優化。

完整引入

完整地將 ui 和樣式引入。

import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css'

在頁面簡單使用 button元件,看看效果。

<el-button type="primary">Login</el-button> image.png

再看一下打包後的資源大小情況npm run build --report

Hash: 40db03677fe41f7369f6 Version: webpack 3.12.0 Time: 20874ms Asset Size Chunks Chunk Names static/css/app.cb8131545d15085cee647fe45f1d5561.css 234 kB 1 [emitted] app static/fonts/element-icons.732389d.ttf 56 kB [emitted] static/js/vendor.a753ce0919c8d42e4488.js 824 kB 0 [emitted] [big] vendor static/js/app.8c4c97edfce9c9069ea3.js 3.56 kB 1 [emitted] app static/js/manifest.2ae2e69a05c33dfc65f8.js 857 bytes 2 [emitted] manifest static/fonts/element-icons.535877f.woff 28.2 kB [emitted] static/css/app.cb8131545d15085cee647fe45f1d5561.css.map 332 kB [emitted] static/js/vendor.a753ce0919c8d42e4488.js.map 3.26 MB 0 [emitted] vendor static/js/app.8c4c97edfce9c9069ea3.js.map 16.6 kB 1 [emitted] app static/js/manifest.2ae2e69a05c33dfc65f8.js.map 4.97 kB 2 [emitted] manifest index.html 506 bytes [emitted]

發現打包後提取公共模組 static/js/vendor.js 有 824kb

再看一下各個模組佔用情況:

image.png

發現 elment-ui.common.js 佔用最大。所有模組資源總共有 642kb。怎麼才能減小打包後的大小呢?很容易就會想到 ui 的引入和樣式的引入中,實際我們只使用了一個元件,卻整體都被打包了,在這裡引入這一個元件即可。

按需引入元件樣式

再次打包優化嘗試

後來查到有人同樣遇到這個問題,提出一個issues#6362,原來只引入需要的element-ui元件,webpack還是把整體的 UI 庫和樣式都打包了,需要一個 webpack 的 babel 外掛 babel-plugin-component,這樣才能真正按需引入打包。這塊其實被寫到官方文件更換 自定義主題 的配置了。

於是 npm i babel-pugin-componet -D 安裝後,在增加 .babelrc 檔案外掛配置

{ "presets": [["@babel/preset-env", { "modules": false }]], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "~theme" } ] ] } 注意:presets如果是env,有問題,換成@babel/preset-env就可以 頁面執行正常,再次打包。

Hash: f182f70cb4ceee63b5d5 Version: webpack 3.12.0 Time: 10912ms Asset Size Chunks Chunk Names static/css/app.95c94c90ab11fdd4dfb413718f444d0c.css 39.9 kB 1 [emitted] app static/fonts/element-icons.732389d.ttf 56 kB [emitted] static/js/vendor.befb0a8962f74af4b7e2.js 157 kB 0 [emitted] vendor static/js/app.5343843cc20a78e80469.js 3.86 kB 1 [emitted] app static/js/manifest.2ae2e69a05c33dfc65f8.js 857 bytes 2 [emitted] manifest static/fonts/element-icons.535877f.woff 28.2 kB [emitted] static/css/app.95c94c90ab11fdd4dfb413718f444d0c.css.map 93.5 kB [emitted] static/js/vendor.befb0a8962f74af4b7e2.js.map 776 kB 0 [emitted] vendor static/js/app.5343843cc20a78e80469.js.map 17.1 kB 1 [emitted] app static/js/manifest.2ae2e69a05c33dfc65f8.js.map 4.97 kB 2 [emitted] manifest index.html 506 bytes [emitted]

static/js/vendor.js 確實變小了,157kB。再來看各個模組分析圖。

image.png

模組總共 157.93KB,少了 5 倍!

主題和主題工具安裝

首先安裝主題工具 element-theme element-theme-chalk,可以全域性安裝也可安裝在專案目錄。這裡推薦安裝在項目錄,方便別人 clone 專案時能直接安裝依賴並啟動。

1.element-theme element-theme-chalk安裝

npm i element-theme element-theme-chalk -D 然後建立element-variables.scss檔案,內容如下

$--color-primary: red !default; 所有的主題色就變為紅色了,效果如下圖

通過 Node API 構建方式

最後引入 element-theme 通過 Node API 形式構建 建立theme.js,內容如下

image.png

const et = require('element-theme') // 第一步生成樣式變數檔案 // et.init('./src/theme.scss') // 第二步根據實際需要修改該檔案 // ... // 實時編譯模式 // et.watch({ // config: './element-variables.scss', // out: './theme/index.css' // }) // 第三步根據該檔案編譯出自定義的主題樣式檔案 et.run({ config: '', // 配置引數檔案路徑 預設`./element-variables.css` out: '' // 輸出目錄 預設`./theme` })

在 package.json 中增加 scripts 指令

{ "scripts": { "theme": "node theme.js" } }

這樣就可以通過 npm run theme 指令來編譯主題了。編譯過程:

  • 執行該指令初始化主題變數檔案 element-variables.scss
  • 根據實際需要修改這個檔案裡主題樣式。
  • 再執行該指令編譯輸出自定義的主題樣式檔案放在 theme 目錄下。

在執行對應的部署指令,就可以上線了

總結

通過以上實驗分析我們可以得知,element-ui 要想實現按需引入和純淨的主題樣式:

  • 首先通過 babel-plugin-component 外掛進行按需引入。
  • 再用 element-theme 工具生成樣變數檔案。
  • 然後根據專案需求修改自定義樣式,依據該檔案構建生成所有樣式。
  • 最後將按需引入樣式 styleLibraryName 指向自定義樣式目錄。

這是我專案中最終實現的定製,參考