webpack -- element-ui 的按需引入
简单说明原理:
使用babel-plugin-component实现按需引入、打包。
将webpack配置成多入口,保证最终打包的目录结构符合babel-plugin-component插件的要求,实现按需加载
element源码关于按需引入的研究:
1、build目录中是cooking配置文件,cooking是饿了么前端研发的基于webpack的前端构建工具,我们使用原始的webpack实现。此处源码忽略。
2、example中是element项目的例子存放,打开element网页,可看见的项目入口。
3、packages目录中,是所有的功能模块,以alert模块为例,分析目录结构
alert模块目录,有一个index.js作为模块入口,在入口处,引入src目录中的主要组件,再对该组件进行拓展,增加install方法,我们知道,在对vue进行扩展,使用vue.use(...)时,vue内部会调用插件的install方法,此处给alert组件增加install方法,则最终打包完成后,按需引入alert功能组件时,可以使用vue.use(alert)进行注册组件到全局。
其他功能模块的目录结构也大同小异,在入口处对组件进行install扩展。
4、src目录中存放一些公共的mixin等工具和一个index.js入口文件,这个入口文件是打包后兼具所有功能组件的入口,上源码,一个一个分析:
首先将packages中的各个功能模块引入
定义一个install方法,在此方法中,将所有的功能模块进行注册。
components.map(component => {
Vue.component(component.name, component);
});
遍历注册
Vue.prototype.$loading = Loading.service;
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
Vue.prototype.$message = Message;
Vue.prototype.$ELEMENT = ELEMENT;
对vue原型进行扩展,使vue实例中可直接使用this.$alert等便捷方法。
最后,将所有功能模块和install方法一起导出。这样当引入element-ui时,便可以使用vue.use(element-ui)进行注册,即将所有的功能组件进行全局注册。
5、lib目录是按babel-plugin-component插件要求打包后存放最终代码的目录。
详细看看这个目录中的结构
目录中,将各个功能模块打包成了一个.js文件,在theme-chalk中,存放这名称和功能模块相同的.css文件。为何要这样打包??这就进入了我们的重点,看看babel-plugin-component插件的文档:
import { Button } from 'antd' 会被解析成同时引入antd/lib/button/index.js和引入lib/button/style.css
这就是这个插件为我们带来的按需引入的功能。插件会去解析你的代码,当你引入的是配置的modules中的某一部分时,自动为你解析,只为你的项目引入你指定的部分。
这个插件有几种目录结构的配置方案,刚刚解释的只是其中一种,我们来看element-ui采用的也是我们要使用的一种:
在lib下,存在几个模块componentA、componentB,当引入import {componentA} from '...'时,会被解析成从lib/componentA,此时,这个componentA若是目录,则进入目录找目录入口,也就是index.js,若componentA是个.js文件,则直接引入这个文件。
样式文件会通过你的bablerc配置,从lib中指定的目录中去引入同名文件
看看bablerc中的相关配置:
在plugins中,增加component配置,component相关option配置:
看看element官网说明的配置:
配置了libraryName和styleLibraryName。
好,到此element的分析及babel-plugin-componentbable插件的说明暂时告一段落。
咱们继续看我们如何去实现。
个人实现,按需引入
目录结构:
项目是用vue-cli搭建的项目:
1、build中是webpack相关配置
2、example目录是开发时调试用
3、src目录中components中是各个功能模块,各功能模块的入口中同element一样,对组件进行扩展,增加install方法,将组件进行全局注册,index.js是入口,其中引入所有功能模块,同时导出模块和install方法,将所有模块进行注册。
4、lib中是最终打包的目标目录
5、增加components.json文件
记录将要打包的功能模块名称和路径
webpack相关配置更改
规划中,需要将各个模块打包至lib,一个功能模块为一个.js文件,并且在theme目录中存在一个同名的.css文件,这样使用时借助babel-plugin-component插件就可实现按需引入。还需要一个总的index.js包含所有的功能模块,和一个index.css包含所有的样式。
这里采用多入口(entry)配置,实现各个功能模块分别打包成一个.js文件,并使用extract-text-webpack-plugin将样式进行抽离后,按入口chunk进行打包为对应的.css文件。
当将需要打包至一起是,使用单个入口,抽离所有css到一个css文件。
所以完成打包目标需要执行两个打包命令,看package.json相关配置:
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js",
"build_all": "node build/build.js all"
}
npm run build进行将各个模块打包为各自的.js文件,样式文件也同时抽离处理为同名的.css,npm run build_all将所有的功能打包为index.js和index.css
上webpack详细配置更改代码:
首先在config中将assetsRoot,output的路径设置为lib
在build.js中,获取命令行参数,根据参数判断需要进行的打包任务,下面详细介绍webpack.prod.conf和webpack.prodAll.conf文件
webpack.prod.conf
1、删除HtmlWebpackPlugin相关配置,这里只需打包为js文件和css文件,不涉及html
2、引入components.json,根据配置的模块及路径配置入口entrys,配置完后,将入口写入entry配置
3、ExtractTextPlugin插件是进行css抽离的,这里不用处理
4、ouput中,出口.js文件的名称不能写死
5、在plugins插件配置处,ExtractTextPlugin相关配置,filename不能写死,需要根据chunk名称自动生成对应名称。这里设置为'/theme/[name].css'指定目录lib/theme存放
webpack.prodAll.conf
1、同样删除html相关配置
注意入口配置,设置为src/index.js这个文件中引入了所有的功能模块。
output和抽离css的配置中的filename写死成index也可,写成[name]按chunk名也可,因为入口只有一个。只要在entry指定入口名为index。
到此,webpack配置就差不多完成了。最后上一个打包完成后的目录结构:
这样,在使用时,只需要引入babel-plugin-component插件,并进行配置,配置中,指定libraryName为库名,指定styleLibraryName为theme即可。
这个相关配置已经发布了npm包。其中只有两个功能组件,一个upload,一个input。
有读者想要试按需引入功能的可以按如下配置:
1、bable配置:
2、引入时:
webpack -- element-ui 的按需引入的更多相关文章
- vue-cli脚手架引入element UI的正确打开方式
element UI官网教程:http://element-cn.eleme.io/#/zh-CN/component/quickstart 1.完整引入,直接了当,但是组件文件不是按需加载,造成多余 ...
- vue Cli 按需引入Element UI 和全局引用Element UI
全局引用: 一.安装 Element UI npm i element-ui -S 二.在main.js 中引入 element UI import ElementUI from 'element-u ...
- 在Vue项目中使用Element UI:按需引入和完整引入
下面操作在main.js文件中进行 完整引入: import Element from 'element-ui'; //样式文件,需单独引入 import 'element-ui/lib/theme- ...
- vue-cli按需引入Element UI组件
一.环境 使用vue-cli搭建的环境 二.安装 babel-plugin-component npm install babel-plugin-component -D 三.修改.babelrc文件 ...
- vue按需引入Element UI的方法
在我们的实际项目开发中,多数是采用按需引入的模式来进行开发的,那么具体应该如何操作呢,可能会有许多新人傻傻分不清楚,具体将在下文讲到. 首先我们先vue create demo创建一个项目出来此时我们 ...
- Element UI——本地引入iconfont不显示
前言 前面因为本地引入Element UI导致了iconfont不显示,所以只好再去Element UI官网去扒下iconfot 步骤 进入官网 组件 | Element UI F12进入控制台,找到 ...
- Html | Vue | Element UI——引入使用
前言 做个项目,需要一个效果刚好Element UI有,就想配合Vue和Element UI,放在tp5.1下使用,但是引入在线的地址各种报错,本地引入就完美的解决了问题! 代码 __STATIC_J ...
- UI组件--element-ui--全部引入和按需引入
主要就是一句话, 如果用到的组件少, 要按需引入, 如果用到的组件很多,就全部引入, 因为按需引入全部的, 和全部引入效果一样(我这是废话, 大家都知道...) 完整引入 在 main.js 中写入以 ...
- vue按需引入element或mint
vue按需引入element或mint需要添加 babel-preset-es2015 和babel-plugin-component
随机推荐
- Linux 更换国内源
1.事件背景 事情起因是因为我想安装xvfb,执行sudo apt-get install xvfb发现安装报错,看报错原因是被墙导致,因为我用的默认源也没有挂代理:然后就百度,发现都是互相抄,什么换 ...
- python字典键或值去重
from fuzzywuzzy import fuzz, process a = {'嫦娥四号探测器是用哪个型号的火箭发射的?': ['长征3B'], '嫦娥四号探测器是在我国[]发射成功的.': [ ...
- FusionCopmpute之CNA,VRM虚拟机安装
CNA和VRM安装步骤一样,需要修改的只有IP 按步骤创建 修改自己虚拟机想要存放的位置 需要把自己网络同样配置为仅主机(提前配好) 自己也可以修改至200G 虚拟机只是用多少取多少 CNA可以设置为 ...
- KDB_Database_Link 使用介绍
kdb_database_link 是 KingbaseES 为了兼容oracle 语法而开发的跨数据库访问扩展,可用于访问KingbaseES, Postgresql , Oracle .以下分别介 ...
- 【读书笔记】C#高级编程 第五章 泛型
(一)泛型概述 泛型不仅是C#编程语言的一部分,而且与程序集中的IL代码紧密地集成.泛型不仅是C#语言的一种结构,而且是CLR定义的.有了泛型就可以创建独立于被包含类型的类和方法了. 1.性能 泛型的 ...
- The 19th Zhejiang Provincial Collegiate Programming Contest
目录 A.JB Loves Math B.JB Loves Comma C. JB Wants to Earn Big Money G. Easy Glide I. Barbecue L. Candy ...
- java项目中VO、DTO以及Entity,各自是在什么情况下应用的
按照标准来说: entity里的每一个字段,与数据库相对应 vo里的每一个字段,是和你前台页面相对应 dto,这是用来转换从entity到dto,或者从dto到entity的中间的东西 举个例子: h ...
- C++ "链链"不忘@必有回响之双向链表
C++ "链链"不忘@必有回响之双向链表 1. 前言 写过一篇与单链表相关的博文(https://blog.51cto.com/gkcode/5681771),实际应用中,双向循环 ...
- Java语言(基础一)
Java语言 Java的特性和优势 简单性(简单易学) 面向对象(一种思想 万物皆对象) 可移植性(一次编写到处运行 JVM) 高性能(及时编译) 分布式(网络分布式url) 动态性(反射机制) 多线 ...
- 通俗易懂理解 MySQL B+树、数据存储、索引等知识
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485630&idx=1&sn=681c9c0d ...