方便迁移,使用 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.

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

orange 微信支付

微信支付

orange 支付宝

支付宝

orange 贝宝

贝宝