做者本人在工做之余喜欢本身写一些东西玩玩, 虽然不是资深程序员, 不过也仍是可以完成前端页面+后端接口+服务端部署的整个流程了。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
若是以为对你有用,就打赏一下吧。