現(xiàn)狀
根據(jù)element-ui官方提供的方法,使用babel-pugin-componet
插件可以完成js和css的按需引入,官方提供的配置如下:
// babel.config.js
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
然后在項目的js或者vue文件中引入
import { Button, Select } from 'element-ui';
根據(jù)babel-pugin-componet
的官方說明,結(jié)合element-ui提供的配置,其作用相當(dāng)于
// 會自動引入base.css
require('element-ui/lib/theme-chalk/base.css')
var Button = require('element-ui/lib/button')
require('element-ui/lib/theme-chalk/button.css')
var Select = require('element-ui/lib/select')
require('element-ui/lib/theme-chalk/select.css')
這樣確實做到了按需引入組件js和css,但是大多數(shù)的情況下,我們會根據(jù)項目的情況調(diào)整element-ui的scss變量,因此就只能手動再單獨去引element-ui提供的scss文件,使用scss預(yù)編譯的結(jié)果去覆蓋默認(rèn)的css,最終導(dǎo)致打包出來的css文件中會包括兩份base.css、button.css和select.css的內(nèi)容。
思路
希望按需引入可以直接引入scss文件,然后配置全局的scss變量,直接對引入的scss文件進行作用,而不是通過樣式覆蓋的方式
babel-pugin-componet
的詳細(xì)配置中提供了styleLibrary
屬性,可以對引入的樣式目錄進行深度的配置,官方說明如下
// babel-pugin-componet options
["component", { "styleLibrary": {} }]: Import a independent theme package with more config
styleLibrary: {
"name": "xxx", // same with styleLibraryName
"base": true, // if theme package has a base.css
"path": "[module]/index.css", // the style path. e.g. module Alert => alert/index.css
"mixin": true // if theme-package not found css file, then use [libraryName]'s css file
}
可以看到這個配置可以修改加載樣式文件的目錄,我們按element-ui的scss文件目錄進行配置
[
"component",
{
"libraryName": "element-ui",
"styleLibrary": {
"name": "~node_modules/element-ui/packages/theme-chalk/src", // element-ui的scss目錄
"base": true, // if theme package has a base.css
"path": "[module].scss", // element-ui的組件scss文件
"mixin": true // if theme-package not found css file, then use [libraryName]'s css file
}
}
]
可以注意到我們配置了base: true
,也就是會加載一個基礎(chǔ)樣式,因為element-ui是必須有一個基礎(chǔ)樣式的。進行編譯后會報錯,提示無法找到node_modules/element-ui/packages/theme-chalk/src/base.css,其實就是默認(rèn)的文件后綴是css,官方說明中并沒有提供設(shè)置文件后綴的參數(shù),所以我們進入源碼碰碰運氣,很幸運在源碼中可以看到
const ext = options.ext || '.css';
修改配置
[
"component",
{
"libraryName": "element-ui",
"styleLibrary": {
"ext": ".scss",
"name": "~node_modules/element-ui/packages/theme-chalk/src", // element-ui的scss目錄
"base": true, // if theme package has a base.css
"path": "[module].scss", // element-ui的組件scss文件
"mixin": true // if theme-package not found css file, then use [libraryName]'s css file
}
}
]
到這一步就已經(jīng)成功一大半了,接下去只需要配置一下scss文件的全局預(yù)加載變量,使所有的scss文件都加上全局的scss變量。
將修改后的element-ui的全局變量保存在項目根目錄中的variables.scss,然后在vue.config.js
中對sass-loader的options進行配置,根據(jù)sass-loader的版本不同配置項也不同
{
loader: "sass-loader",
options: {
data: `@import "variables.scss";`
}
}
// 新版sass-loader
{
loader: "sass-loader",
options: {
prependData: `@import "variables.scss";`
}
}