方便迁移,使用 jscodeshift 编写 codemod
时间线:工作半年(2022.10-2023.1)
# 背景
2022 年底时,抖音直播前端(H5 层面)的 C 端组件库设计规范是遵循旧的直播设计规范开发,但后来设计统一对齐成了抖音设计规范(DUX,Delight Design),因此原有的直播组件库已不太适用于业务场景。
而 Delight Design 当时存在安卓、iOS、lynx 组件库,由于人力问题一直未启动 H5 组件库建设,双方一拍即合,共建实现 C 端 H5 组件库。
于是我们就开始共建 DUX H5 组件库
耗时不到三个月,大家齐心协力产出 21 个基础组件、文档站、对应 demo,并产出一个原直播组件库的全新版本(90%+ 兼容,少数 break change)& 更新 codemod 工具。
# 组件库大致技术
React18 + Typescript + lodash-es + gulp 构建
# 好用 mixins 沉淀
@mixin text-ellipsis { | |
work-break: break-all; | |
white-space: nowrap; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
} | |
// 细边框 | |
@mixin thin-border( | |
$width: 1PX, | |
$color: var(--dux-LinePrimary), // 主颜色, | |
$style: solid, | |
$border-radius: 0 | |
) { | |
&::before { | |
content: ""; | |
pointer-events: none; | |
display: block; | |
position: absolute; | |
left: 0; | |
top: 0; | |
transform-origin: 0 0; | |
border-width: $width; | |
border-style: $style; | |
border-color: $color; | |
} | |
@media (min-resolution: 2dppx) { | |
&::before { | |
width: 200%; | |
height: 200%; | |
transform: scale(.5); | |
border-radius: calc(2 * $border-radius); | |
} | |
} | |
@media (min-resolution: 3dppx) { | |
&::before { | |
width: 300%; | |
height: 300%; | |
transform: scale(.333); | |
border-radius: calc(3 * $border-radius); | |
} | |
} | |
} | |
// 元素实际触区 | |
@mixin touch-area ( | |
$width: 100%, // 宽度 | |
$height: 44px, // 设计要求 | |
) { | |
& { | |
position: relative; | |
} | |
&::before { | |
width: $width; | |
height: $height; | |
content: ""; | |
position: absolute; | |
left: 50%; | |
top: 50%; | |
transform: translate(-50%, -50%); | |
} | |
} | |
@mixin active-area ( | |
$width: 100%, | |
$height: 100%, | |
$borderRadius: 4px, | |
$color: var(--dux-ShadowInverse), | |
$left: 0, | |
$top: 0 | |
) { | |
& { | |
position: relative; | |
} | |
&:active::after { | |
background: var(--dux-active-area-backgroundColor, $color); | |
} | |
&::after { | |
width: $width; | |
height: $height; | |
content: ""; | |
position: absolute; | |
background: var(--active-area-background, transparent); | |
left: $left; | |
top: $top; | |
} | |
} |
# 不同主题控制
sass 编写中,注意多层颜色 token 变量,暴露一层给到外层统一主题覆盖。
优先级:组件特殊 token > 主题 token > 默认兜底色。
# 任务
时间紧,任务不轻的情况下,其中我负责了以下三个组件的编写:
- Tag(标签)
- Input(单行文本框)
- TextArea(多行文本框)
# 问题
不太回忆起来了,仅列举部分还记得的问题
# Tag 里渲染文字上浮的问题
经过一顿搜索后,原作者:(99+ 封私信 / 80 条消息) Android 浏览器下 line-height 垂直居中为什么会偏离? - 知乎 (zhihu.com)
简而言之就是因为字体内部渲染的问题,无法通过前端的技术去根本上修复
只能进行缓解:让行高 = 字号,多余的行高通过间距去控制(即减小字体的渲染范围来缓解)
# TextArea、Input 内在拼音输入态时多次触发无意义的 onChange
中文比较特殊,有拼音输入态。所以这里选择使用 onCompositionEnd 来判断是否处于拼音输入状态,并暴露参数给 onChange 回调。
# codemod 工具
本次我们的 H5 组件库在旧有的基础上,产生了一些 API 的 break change(更名或参数变更)。为了方便旧有组件库用户一键迁移,于是使用 jscodeshift 编写了一个 codemod:通过 AST,找出需要替换的代码片段。
像 React-codemod 就是利用的 jscodeshift 实现。
jscodeshift 提供了许多的上层功能封装(自带 runner 可对文件目录自动递归处理),用于当 AST editor 较为省事。
编写过程中,可以配合 https://astexplorer.net 工具来辅助快速找出节点对应类型去写匹配代码。
同样,我也负责了 Tag、Input、TextArea 三个组件对应的 transformer
文件编写。
参考资料:GitHub - facebook/jscodeshift: A JavaScript codemod toolkit.