苏宁vue组件库构建之道

苏宁vue组件库构建之道

前言

苏宁内部系统前端框架逐步升级到Vue, 为满足内部业务需求, 开发已有前端组件的Vue版本成为当务之急;由于原本分散的组件开发模式,到后面出现了许多问题, 比如风格不统一, API命名随意,可扩展性差, 复用性差等,所以在开发Vue版本组件过程中参考了成熟的组件库 Ant.Design, 形成了统一的设计语言,并且在设计组件着重提升了组件的可扩展性和复用性。

组件设计

在实际项目中, 组件总会遇到无法满足的场景, 这时候通常有两种选择。

一、开发一个新的组件适用于单个场景

二、 修改原组件提供支持

选择一 每当出现不适配的场景就开发一个新组建, 会造成整个组件库无限膨胀, 维护非常困难;

选择二 会造成原组件不断新增逻辑,复杂度不断增加,最终难以维护;

是否有别的方式可以解决呢?

以dropdown 组件为例,dropdown组件可分解为 触发元素和下拉面板两部分, 触发元素本身是多变的,可能是个按钮也可能只是一行文字,面对多变的场景, 组件本身无法在内部正对每种场景做定义,这时候就需要提供给用户自由度, 让用户决定使用的元素。

苏宁vue组件库构建之道

vue 提供了slot的插槽, 使组件能获取用户在外部定义的元素.这个元素被编译为VNode实例, 通过操作VNode( 操作vue的 VNode 比较繁琐),可以给用户定义的元素绑定必要的内部事件和属性. 同样下拉面板也是完全可以由用户定义。

这样dropdown组件只需关注展开的功能, 而具体通过什么来触发展开, 以及展开后需要怎么渲染内容, 由用户定义, 组件是不需要关注的。

由此在上面两种选择之外又有了第三种选择, 即组件只提供基本的功能,然后具体的行为由用户自定义,这样基本满足了大部分业务场景; 但又有一个问题,这样提供的组件功能是不是过于简单, 组件使用起来是不是不方便? 的确,灵活性会带来易用性的缺憾, 在开发组件时如何保持灵活性的同时又不易用性, 这就需要根据组件使用的实际业务场景, 提取出通用部分作为组件的默认值, 同时向外提供插槽供用户自定义, 这样才能在保证灵活性的同时兼顾易用性。

组件优化

组件的使用场景多种多样, 有些场景对大数据量有要求.比如Select下拉框组件, 正常情况下Select组件中数据最多100条,但某天业务非要在Select中渲染1000+数据, Vue本身处理1000+数据是很快的,但浏览器渲染大量的DOM节点,就非常慢了。这时候就需要优化,减少页面实际渲染的DOM数, 我们采用的方式是,只渲染用户可视区域内的DOM节点,当用户拖拉滚动条时再根据滚动条的位置实时计算需显示的DOM节点, 这样浏览器实际需要渲染的节点就很少了, 而且由于可视区域内可渲染的数据行数是固定的,可充分利用Vue的节点复用机制, 大数据量时性能也能有非常大的提升。

构建

组件库可提供全量包,方便全量使用,也可以提供单个组件包,方便按需引用, 这时候需要按照不同方式构建。

全量包

基于webpack 使用 output.libraryTarget = ‘umd’ 方式构建,确保其兼容性。

构建全量包时,主要问题是如何将所有组件及样式引入入口文件。下面提供一种比较简单的方式。首先是引入组件, 只需创建一个导出文件components.js导出所有组件, 然后在入口文件中引入components模块。

苏宁vue组件库构建之道

其次是样式,如果组件的样式是一个单独文件, 可以创建一个入口js (这样导出样式时可以利用webpack的去重能力,防止样式重复引入),最后在webpack入口文件中通过required.context方法,获取所有样式的入口文件,这样就能在打包时将所有样式一起打包出来了。

苏宁vue组件库构建之道

单个组件包

单个组件包提供编译后的代码, 不处理文件之间的依赖, 依赖关系由最终使用的项目来处理, webpack或rollup会分析文件之间的依赖关系, 并最终将其打包成一个单独的文件, 无法适配组件包的构建需求, 所以选用gulp作为构建工具; gulp并没有类似于vue-loader模块, 需要基于 @vue/component-compiler编译vue文件,后面的过程与编译一个普通的js包类似。

苏宁vue组件库构建之道

发布及版本依赖管理

在开发组件库时经常遇到这个场景, 大量组件同时依赖一个底层库, 当底层库发布时, 所有依赖于此的组件需要同时发布,并要将组件中底层库的依赖版本更新为当前发布版本。

上面的场景光靠人工更新,不光繁琐而且非常容易出错. 所以需要依赖于工具; lerna是常用的工具。lerna是一个管理js多包项目的工具,通过lerna发布时,会分析包之间的依赖关系, 并根据lerna.json中的version配置,决定是发布所有包,还是只发布依赖有更新的包;lerna具体的配置网上教程很多不细说。

lerna(v2版本) 使用过程中会遇到的问题。

lerna在默认情况下会根据repo的package.json安装node_modules,这会造成每个repo都安装大量重复的包,是否能够避免这种情况?

有两种方案可供参考:

一、yarn workspace feature(推荐使用)

二、lerna本身提供的hoist参数

yarn workspace 基于yarn 能够使用yarn提供的各种优化,而且能够使用yarn lock功能减少包冲突.在lerna中使用yarn workspace 需要新增以下配置:

最外层的package.json

苏宁vue组件库构建之道

- private:true 配置是必须的

- packages是项目包的根目录

lerna.json

苏宁vue组件库构建之道

小结

上述只覆盖了组件库开发中的几个主要内容,在实际组件库开发过程中还会面对很多的问题, 需要根据实际情况去解决。


分享到:


相關文章: