原标题:彻底学会element-ui按需引入和纯净主题定制

作者:wuwhs

来源:SegmentFault 思否社区

前言

手上有些项目用的element-ui,刚好有空琢磨一下怎么减小打包文件大小和打包速度方面,为了演示实验,用 vue-cli 生成初始项目,在这仅对 element-ui 主题和组件方面来优化。

vue init webpack vuecli

完整引入

完整地将 ui 和样式引入。

import ElementUI from 'element-ui'

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

在页面简单使用 2 个组件,看看效果。

用户管理

配置管理

角色管理

定时任务补偿

>

再看一下打包后的资源大小情况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

再看一下各个模块占用情况:

发现 elment-ui.common.js 占用最大。所有模块资源总共有 642kb。怎么才能减小打包后的大小呢?很容易就会想到 ui 的引入和样式的引入中,实际我们只使用了三个组件,却整体都被打包了,在这里引入这三个组件即可。

按需引入组件样式

新建一个 element-variables.scss 文件(为什么是 SCSS 文件,后面自定义主题会用到)。

/*icon字体路径变量*/

$--font-path: "~element-ui/lib/theme-chalk/fonts";

/*按需引入用到的组件的scss文件和基础scss文件*/

@import "~element-ui/packages/theme-chalk/src/base.scss";

@import "~element-ui/packages/theme-chalk/src/rate.scss";

@import "~element-ui/packages/theme-chalk/src/button.scss";

@import "~element-ui/packages/theme-chalk/src/row.scss";

按需引入组件

新建一个 element-config.js 文件,将项目用到的 element 组件引入。

import {

Tabs,

TabPane,

Steps,

Step

} from 'element-ui'

exportdefault {

install (V) {

V.use(Tabs)

V.use(TabPane)

V.use(Steps)

V.use(Step)

}

}

第一次优化后打包分析

将以上 element-variables.scss 和 element-config.js 引入到 main.js 中。

import ElementUI from '@/assets/js/element-config'

import '@/assets/css/element-variables.scss'

Vue.use(ElementUI)

貌似上面一切都很顺理成章,打包后大小会减小。

Hash: 2ef987c23a5d612e00e1

Version: webpack 3.12.0

Time: 17430ms

Asset Size Chunks Chunk Names

static/css/app.3c70d8d75c176393318b232a345e3f0f.css 38.8 kB 1 [emitted] app

static/fonts/element-icons.732389d.ttf 56 kB [emitted]

static/js/vendor.caa5978bb1eb0a15b097.js 824 kB 0 [emitted] [big] vendor

static/js/app.5ebb19489355acc3167b.js 3.64 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.3c70d8d75c176393318b232a345e3f0f.css.map 53.9 kB [emitted]

static/js/vendor.caa5978bb1eb0a15b097.js.map 3.26 MB 0 [emitted] vendor

static/js/app.5ebb19489355acc3167b.js.map 17 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!

再看各个模块占用情况:

WHAT? 竟然模块都没什么变化,岂不是竹篮打水,事与愿违。

再次打包优化尝试

后来查到有人同样遇到这个问题,提出一个issues#6362,原来只引入需要的element-ui组件,webpack还是把整体的 UI 库和样式都打包了,需要一个 webpack 的 babel 插件 babel-plugin-component,这样才能真正按需引入打包。这块其实被写到官方文档更换 自定义主题 的配置了。

于是 npm i babel-pugin-componet -D 安装后,在增加 .babelrc 文件插件配置

{

"presets": [

[ "env", {

"modules": false,

"targets": {

"browsers": [ "> 1%", "last 2 versions", "not ie <= 8"]

}

}],

"stage-2"

],

"plugins": [

"transform-vue-jsx",

"transform-runtime",

[

"component",

{

"libraryName": "element-ui",

"styleLibraryName": "theme-chalk"

}

]

]

}

页面运行正常,再次打包。

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。再来看各个模块分析图。

模块总共 157.93KB,少了 5 倍!

更换主题-覆盖样式

element-ui 的 theme-chalk 使用 SCSS 编写,如果在自己的项目中也是用 SCSS,那么可以直接在项目中改变样式变量,因此可以在前面新建的 element-variables.scss 文件用新的主题颜色变量覆盖即可。

/**

* 覆盖主题色

*/

/*主题颜色变量*/

$--color-primary: #f0f;

/*icon字体路径变量*/

$--font-path: '~element-ui/lib/theme-chalk/fonts';

/* 引入全部默认样式 会引入没用到的组件样式 */

// @import '~element-ui/packages/theme-chalk/src/index';

/* 按需引入用到的组件的scss文件和基础scss文件 */

@import '~element-ui/packages/theme-chalk/src/base.scss';

@import '~element-ui/packages/theme-chalk/src/rate.scss';

@import '~element-ui/packages/theme-chalk/src/button.scss';

@import '~element-ui/packages/theme-chalk/src/row.scss';

现在我们的主题就变成了预期效果

可能你已经注意到了,这里推荐的是分别引入用到的组件样式,而不是引入全部默认样式,因为这样会导致引入没有使用到的组件样式。比如当前案例中我们没有使用到 ColorPicker 组件,在打包输出的 css 文件中确有该组件样式。

更换主题-纯净样式

通过以上优化可以按需的将所用到组件打包,排除没用到的组件,减少包的大小。但是,还是存在一个小瑕疵:一个用到的组件样式会被两次打包,一次是默认的样式,一次是覆盖的样式。

出现这个问题是由于我们在两个地方对样式进行引入了,一个是在 .babelrc 文件中通过 babel-plugin-component 插件按需引入 element-ui 组件及其默认样式,一个是在 element-variables.scss 文件中覆盖默认样式生成的自定义样式。

所以怎样将二者结合,即babel-plugin-component 插件按需引入的组件样式改成用户自定义样式,达成纯净样式目标呢?这里就要用到 element-ui 的主题工具进行深层次的主题定制。

主题和主题工具安装

首先安装主题工具 element-theme,可以全局安装也可安装在项目目录。这里推荐安装在项目录,方便别人 clone 项目时能直接安装依赖并启动。

npm i element-theme -D

然后安装白垩主题,可以从 npm 安装或者从 GitHub 拉取最新代码。

# 从 npm

npm i element-theme-chalk -D

# 从 GitHub

npm i https://github.com/ElementUI/theme-chalk -D

主题构建

element-theme 支持的构建有 Node API 和 CLI 方式。

通过 CLI 构建方式

如果全局安装可以在命令行里通过 et 调用工具,如果安装在当前目录下,需要通过 node_modules/.bin/et 访问到命令。执行 -i(--init) 初始化变量文件。默认输出到 element-variables.scss,当然你可以传参数指定文件输出目录。如果你想启用 watch 模式,实时编译主题,增加 -w(--watch) 参数;如果你在初始化时指定了自定义变量文件,则需要增加 -c(--config) 参数,并带上你的变量文件名。默认情况下编译的主题目录是放在 ./theme 下,你可以通过 -o(--out) 参数指定打包目录。

# 初始化变量文件

et --init [file path]

# 实时编译

et --watch [--config variable file path] [--out theme path]

# 编译

et [--config variable file path] [--out theme path] [--minimize]

通过 Node API 构建方式

引入 element-theme 通过 Node API 形式构建

var et = require( 'element-theme')

// 实时编译模式

et.watch({

config: 'variables/path',

out: 'output/path'

})

// 编译

et.run({

config: 'variables/path', // 配置参数文件路径 默认`./element-variables.css`

out: 'output/path', // 输出目录 默认`./theme`

minimize: false, // 压缩文件

browsers: [ 'ie > 9', 'last 2 versions'], // 浏览器支持

components: [ 'button', 'input'] // 选定组件构建自定义主题

})

应用 Node API 构建自定义主题

在这里,为了让主题的构建更加直观和被项目共享,采用 Node API 方式构建,在项目根目录下新建 theme.js文件。

const et = require( 'element-theme')

// 第一步生成样式变量文件

// et.init( './src/theme.scss')

// 第二步根据实际需要修改该文件

// ...

// 第三步根据该变量文件编译出自定义的主题样式文件

et.run({

config: './src/theme.scss',

out: './src/theme'

})

在 package.json 中增加 s 指令

{

"s": {

"theme": "node theme.js"

}

}

这样就可以通过 npm run theme 指令来编译主题了。编译过程:

运行该指令初始化主题变量文件 theme.scss。

根据实际需要修改这个文件里主题样式。

再运行该指令编译输出自定义的主题样式文件放在 theme 目录下。

这样就完成了所有自定义主题样式的构建。要想将这些自定义样式随着组件按需引入,需要将 .babelrc 文件中按需引入插件 babel-plugin-component 参数 styleLibraryName 从原本的 element-ui 默认样式目录变成现在自定义目录 ~src/theme。

"plugins": [

"transform-vue-jsx",

"transform-runtime",

[

"component",

{

"libraryName": "element-ui",

"styleLibraryName": "~src/theme"

}

]

]

一切准备就绪,项目打包,打包后的 css 文件中只有唯一自定义样式,没有了默认样式,也不存在没被引入组件的样式,实现了我们预期的纯净的自定义样式!

Hash: c442bcf9d471bddfdccf

Version: webpack 3.12.0

Time: 10174ms

Asset Size Chunks Chunk Names

static/css/app.52d411d0c1b344066ec1f456355aa7b9.css 38.8 kB 1 [emitted] app

static/fonts/element-icons.535877f.woff 28.2 kB [emitted]

static/js/vendor.befb0a8962f74af4b7e2.js 157 kB 0 [emitted] vendor

static/js/app.43c09c1f16b24d371e07.js 3.82 kB 1 [emitted] app

static/js/manifest.2ae2e69a05c33dfc65f8.js 857 bytes 2 [emitted] manifest

static/fonts/element-icons.732389d.ttf 56 kB [emitted]

static/css/app.52d411d0c1b344066ec1f456355aa7b9.css.map 81.3 kB [emitted]

static/js/vendor.befb0a8962f74af4b7e2.js.map 776 kB 0 [emitted] vendor

static/js/app.43c09c1f16b24d371e07.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]

由于样式是纯净的,css 文件大小从原来完全引入的 234KB 变成 38.8KB,进一步减小了打包大小。

总结

通过以上实验分析我们可以得知,element-ui 要想实现按需引入和纯净的主题样式:

首先通过 babel-plugin-component 插件进行按需引入。

再用 element-theme 工具生成样变量文件。

然后根据项目需求修改自定义样式,依据该文件构建生成所有样式。

最后将按需引入样式 styleLibraryName 指向自定义样式目录。

如果对样式提取要求不高,可直接采取变量覆盖形式(同时存在默认样式)。

还有不清楚可以从链接(https://github.com/wuwhs/element-replace-theme)查看案例源码,赠人 star,手有余香。 返回搜狐,查看更多

责任编辑:

element ui需要引入样式吗_彻底学会element-ui按需引入和纯净主题定制相关推荐

  1. element引入的组件大小高度不对_ElementUI 在 按需引入时定义 default size?

    import Vue from 'vue'import Element from 'element-ui'import 'element-ui/lib/theme-chalk/index.css'Vu ...

  2. xd可以用ui动效效果吗_通过动画使UI设计栩栩如生:Adobe XD和After Effects

    xd可以用ui动效效果吗 Note - If you don't fancy splashing out on an Adobe license, you can trial their produc ...

  3. CSS引入样式的四种方法及优先级顺序

    CSS引入样式的几种方法 css可以通过4种方式引入样式表 根据不同的需求可以选择不同的引入方式 但是它们也有不同的优缺点 行内样式 嵌入式样式 外部样式 @import 导入的方式 1.行内样式 特 ...

  4. echarts 按需引入模_【React】react项目引入echarts插件

    参考npm文档:[echarts-for-react](echarts-for-react) 由于npm上已经有针对react项目出的echarts插件,所以在这里直接安装 第一步:npm安装echa ...

  5. vue中babel-plugin-component按需引入和element-ui 的主题定制,支持发布,上线

    前言 目前项目用的vue + element-ui,之前有了解过element-ui真正的按需引入,也有了解到主题定制,之前的项目都是根据element-ui的类及标签,在全局或者局部进行一大堆样式覆 ...

  6. ElementPlus 完整引入与按需引入

    ElementPlus 全局引入与按需引入 前言 一.完整引入 1.安装组件库 2.在项目中引入 3.设置组件语言 二.按需引入 1.安装组件库 2.Webpack 配置 3.在项目中引入 (1)全局 ...

  7. element引入的组件大小高度不对_试水 elementplus ui 组件库

    上次逛知乎发现 element  之前的团队,已经将 element-plus 开发出来了,看来我们可以在 Vue3 接着使用 element 了,在我的心目中 element 这个框架真的好,设计样 ...

  8. vue + element ui 的后台管理系统框架_从零开始搭建 VUE + Element UI后台管理系统框架...

    点击右上方红色按钮关注"web秀",让你真正秀起来 前言 后台管理系统前端框架,现在很流行的形式都是,上方和左侧都是导航菜单,中间是具体的内容.比如阿里云.七牛云.头条号.百家号等 ...

  9. 2022-04-05 学习记录--React-React UI组件库-ant-design(蚂蚁金服)—— 按需引入样式 + 自定义主题

    一.流行的开源React UI组件库 流行的开源React UI组件库 material-ui(国外) 1.官网:http://www.material-ui.com/#/ 2.github:http ...

最新文章

  1. 为什么不记录慢速查询?
  2. chrmoe debug
  3. [PYTHON] 深度解析copy.copy() 与 copy.deepcopy()
  4. 川大计算机专业导师冯子亮,问问川大计算机研究生招收的小专业有哪些
  5. javascript实现silverlight pivotViewer控件
  6. 安全公司本意告警用户,不料先遭攻击并泄露超50亿个人数据
  7. 推理集 —— 特殊与差异
  8. vue获取路径参数和请求参数
  9. 模拟https类型的get,post请求时,碰到证书不信任,无法正常获取返回内容的异常
  10. 字符串拼接的sql注入实战
  11. WiRadius认证计费管理系统
  12. HBuilderX云打包提示cli版本和服务器的cli版本不一致
  13. 漫步微积分二十五——面积问题
  14. 现代战争——僵尸网络的历史 上篇
  15. 【Typescript专题】之类型进阶
  16. Java编程序哥德巴赫猜想
  17. 2022-2028全球与中国无线和多室音频市场现状及未来发展趋势
  18. Linux中常用软件安装(基于Ubuntu)
  19. 基于Ubuntu20.04配置Emscripten开发环境
  20. 华为智慧金融峰会召开发布金融云网解决方案;Supermicro产能将翻倍每年供货超200万台服务器 | 全球TMT...

热门文章

  1. 修改environment导致重启不能登录的问题解决
  2. 第二部分:开发简要指南-第六章 使用Fragments构建动态UI
  3. 解压并安装protobuf库_golang-leaf服务器-protobuf的安装
  4. 信捷步进指令的使用_电工想做PLC工程师?那步进电机的编程控制指令你一定要了解...
  5. 计算机网络技术之网络系统设计与组建工程
  6. vue 判断对象不为空_Vue 学习笔记(二):实例
  7. Python+django网页设计入门(15):公用模板设计与使用
  8. dos进入mysql不记得密码_windos mysql 忘记密码,无密码登录,重新登录
  9. Spring 基础 用mock对Controller执行测试(系列号4)
  10. mysql 导出csv命令_MySQL 导出数据到csv文件的命令