做者本人在工做之餘喜歡本身寫一些東西玩玩, 雖然不是資深程序員, 不過也仍是可以完成前端頁面+後端接口+服務端部署的整個流程了。javascript
開始入坑css
歡迎來個人Vue技術羣交流:887516034前端
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
複製代碼
這是.babelrc配置參數,component是babel插件的名字,對象是參數。vue
import Vue from 'vue';
import {
Dialog,
Autocomplete,
Dropdown,
...
} from 'element-ui';
Vue.use(Pagination);
Vue.use(Dialog);
Vue.use(Autocomplete);
...
//這裏提個醒
//MessageBox,Message,Notification這三個組件只能掛載Vue原型上調用,
//不能使用Vue.use();不然項目運行會默認執行一次,即便沒有使用它們
複製代碼
這樣就能夠愉快的按需加載使用本身想要的組件了,接下來給你們看一下這個按需加載插件的部分源碼,看它到底幹了什麼java
var _options = options,
_options$libDir = _options.libDir,//這是組件所在根目錄下的路徑element-ui/lib/
libDir = _options$libDir === void 0 ? 'lib' : _options$libDir,
_options$libraryName = _options.libraryName,//這是ui庫的名字--elementui
libraryName = _options$libraryName === void 0 ? defaultLibraryName : _options$libraryName,
_options$style = _options.style,
style = _options$style === void 0 ? true : _options$style,
styleLibrary = _options.styleLibrary,//這是引入組件時,所須要引入對應組件樣式的配置對象
_options$root = _options.root,
root = _options$root === void 0 ? '' : _options$root,
_options$camel2Dash = _options.camel2Dash,
camel2Dash = _options$camel2Dash === void 0 ? true : _options$camel2Dash;
var styleLibraryName = options.styleLibraryName;//這是組件所需樣式的路徑(相對於上面的lib)
var _root = root;
var isBaseStyle = true;
var modulePathTpl;
var styleRoot;
var mixin = false;
var ext = options.ext || '.css';//這是加載樣式的後綴,默認css
複製代碼
就這一部分代碼,咱們已經知道在執行按需加載時已經配置了對應樣式的加載,因此若是在.babelrc
文件配置過styleLibraryName
屬性的,不要在全局引入element的css樣式了,若是你不在意打包體積的話,請無視我。node
踩坑git
/* 改變主題色變量 */
$--color-primary: teal;
/* 改變 icon 字體路徑變量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";//注意此處引入了全部組件的scss樣式
複製代碼
看到這裏大家發現什麼了嗎?是的,沒錯,這裏引入了所有的scss,上面咱們剛說babel-plugin-component會在按需加載組件時,同時引入對應組件的css樣式,有人會說那這裏就不引入這個index.scss
文件,若是沒有組件的scss,那這個$--color-primary
變量會有效嗎? 答案固然是不可能有效的。程序員
既然咱們node_modules
裏面有全部組件的scss樣式文件,咱們是否是就可讓babel-plugin-component在引入組件時,就引入對應的scss文件呢?答案是徹底ojbk的,否則還寫這文章幹嗎。。。github
爬坑npm
if (styleLibrary && _typeof(styleLibrary) === 'object') {//這個是樣式的一些配置
styleLibraryName = styleLibrary.name;
isBaseStyle = styleLibrary.base;
modulePathTpl = styleLibrary.path;
mixin = styleLibrary.mixin;
styleRoot = styleLibrary.root;
}
if (styleLibraryName) {//是否在.babelrc配置了styleLibraryName
if (!cachePath[libraryName]) {//是否存在配置好的樣式獲取路徑
var themeName = styleLibraryName.replace(/^~/, '');
cachePath[libraryName] = styleLibraryName.indexOf('~') === 0 ?//路徑是否相對於element-ui/lib
resolve(process.cwd(), themeName) :
"".concat(libraryName, "/").concat(libDir, "/").concat(themeName);
}//若是是相對於lib 組合路徑---element-ui/lib/theme-chalk/ 這個目錄下是75個css文件
//這裏將這一段路徑保存在了cachePath[libraryName] 後續會用到
if (libraryObjs[methodName]) {//做者也沒搞清楚這裏是什麼 不過不要緊,事實證實這裏走了false
/* istanbul ingore next */
if (cache[libraryName] === 2) {
throw Error('[babel-plugin-component] If you are using both' + 'on-demand and importing all, make sure to invoke the' + ' importing all first.');
}
if (styleRoot) {//這裏默認是沒有配置的 全部走false
path = "".concat(cachePath[libraryName]).concat(styleRoot).concat(ext);
} else {
path = "".concat(cachePath[libraryName]).concat(_root || '/index').concat(ext);
}//這裏會默認先加載index.css 由於ext沒設置就會默認css
cache[libraryName] = 1;
} else {//走了else
if (cache[libraryName] !== 1) {//這裏確定是不等於1,由於上面一行纔會賦值1
/* if set styleLibrary.path(format: [module]/module.css) */
var parsedMethodName = parseName(methodName, camel2Dash);
if (modulePathTpl) {
var modulePath = modulePathTpl.replace(/\[module]/ig, parsedMethodName);
path = "".concat(cachePath[libraryName], "/").concat(modulePath);
} else {//這裏走了else 也就是樣式路徑後續爲模塊名.[ext]
path = "".concat(cachePath[libraryName], "/").concat(parsedMethodName).concat(ext);
}//全部這裏的路徑就是element-ui/lib/
if (mixin && !isExist(path)) {
path = style === true ? "".concat(_path, "/style").concat(ext) : "".concat(_path, "/").concat(style);
}
if (isBaseStyle) {
addSideEffect(file.path, "".concat(cachePath[libraryName], "/base").concat(ext));
}
cache[libraryName] = 2;
}
}
addDefault(file.path, path, {
nameHint: methodName
});
} else {
if (style === true) {
addSideEffect(file.path, "".concat(path, "/style").concat(ext));
} else if (style) {
addSideEffect(file.path, "".concat(path, "/").concat(style));
}
}
}
複製代碼
//第一步不用說了 先把ext後綴改成scss
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk",
"ext":".scss"
}
]
//-------------------
//第二步呢 就是配置路徑 比較重要的
//有一段代碼須要看的 雖然做者也看不懂,不過大概知道這一段是加載模塊的
if (libraryObjs[methodName]) {
path = "".concat(libraryName, "/").concat(libDir).concat(_root);
//須要注意這裏的libDir,以前的代碼咱們看到 加載樣式也會基於libDir
//因此咱們沒法經過.babelrc的option去修改libDir,
//那樣的話組件加載就有問題咱們不能影響最基本的組件加載
if (!_root) {
importAll[path] = true;
}
} else {
path = "".concat(libraryName, "/").concat(libDir, "/").concat(parseName(methodName, camel2Dash));
}
//因此咱們只能經過修改core.js的源碼解決,這是我目前的辦法
複製代碼
libDir
是不能改的 咱們說了 因此看源碼//這是上面提到的三目運算
if (!cachePath[libraryName]) {
var themeName = styleLibraryName.replace(/^~/, '');
cachePath[libraryName] = styleLibraryName.indexOf('~') === 0 ?
resolve(process.cwd(), themeName) :
"".concat(libraryName, "/").concat(libDir, "/").concat(themeName);
}//咱們把這裏------------------------libDir修改成 "packages"
如今路徑從element-ui/lib/theme-chalk--->element-ui/packages/theme-chalk
複製代碼
//咳咳,仍是那個三目運算
if (!cachePath[libraryName]) {
var themeName = styleLibraryName.replace(/^~/, '');
cachePath[libraryName] = styleLibraryName.indexOf('~') === 0 ?
resolve(process.cwd(), themeName) :
"".concat(libraryName, "/").concat("packages", "/").concat(themeName);
}
//咱們看packages後面的路徑是個變量themeName
//這個themeName就是styleLibraryName,你懂了嗎,你懂怎麼修改了嗎
複製代碼
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk/src",//這裏把theme-chalk-->theme-chalk/src
"ext":".scss"
}
]
複製代碼
總結
.babelrc
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk/src",
"ext":".scss"
}
]
]
複製代碼
node_modules/babel-plugin-component/lib/core.js
//95-98行左右
if (!cachePath[libraryName]) {
var themeName = styleLibraryName.replace(/^~/, '');
cachePath[libraryName] = styleLibraryName.indexOf('~') === 0 ? resolve(process.cwd(), themeName) : "".concat(libraryName, "/").concat("packages", "/").concat(themeName);
}
複製代碼
因爲隨便修改官方提供的插件源碼並不合理,做者我fork了官方的npm包,而且修改了對應位置的代碼,合理的作法是安裝我提供的babel-plugin-component-scss,當不須要scss時,仍可以使用官方的插件
須要注意的是,當使用babel-plugin-component-scss時,babel.config.js
or.babelrc
的配置須要以下:
"plugins": [
[
"component-scss",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk/src",
"ext":".scss"
}
]
]
複製代碼
over
歡迎來個人Vue技術羣交流:887516034
若是以爲對你有用,就打賞一下吧。