写点什么

从 Styleguidist 迁移到 Storybook

Kedar Vaidya 、Benson Pan

  • 2022-12-15
    北京
  • 本文字数:3167 字

    阅读完需:约 10 分钟

从 Styleguidist 迁移到 Storybook

提供一流的开发者体验是 Yelp 基础设施和工程效率团队的核心原则之一。随着开发人员不断创建新的 React 组件,我们的 React 代码库一直在增长,但我们现有的 React Styleguidist(本文简称 Styleguidist)开发环境无法并行扩展。从 Styleguidist 到 Storybook 的过渡让我们能够为 React 组件提供一个更快、更加友好的开发环境,并更好地协调开发人员和设计人员的工作流程。在这篇文章中,我们将深入探讨我们是如何以及为什么要迁移到 Storybook。

现状


Styleguidist 是一个交互式 React 组件开发环境,开发人员用它来开发和查看用户界面。Styleguidist 还可以用于生成静态文档页面(样式指南),并分享给其他利益相关者。文档是用 Markdown 创建的,带有代码块,这些代码块在一个单独的交互式沙盒中渲染 React 组件。一个简单的例子如下所示:


The `<ButtonGroup />` component is used to arrange multiple `<Button />`components side-by-side.
```jsxconst Button = require('../Button').default;
<ButtonGroup> <Button text="Foo" /> <Button text="Bar" /> <Button text="Baz" /></ButtonGroup>
复制代码



一个 Styleguidist 沙盒示例


在 Yelp,我们在使用 Styleguidist 时遇到了各种各样的问题,这些问题导致 React 开发体验欠佳:

  • 由于没有得到广泛的 Web 社区的支持,Styleguidist 缺少插件生态系统,因此 Styleguidist 的插件必须自己从头开发。

  • 在使用大型包时,Styleguidist 不能很好地伸缩,因为它会为包中的每一个示例渲染一个独立的沙盒,导致初始化加载时间和热加载时间变长。

  • 开发人员必须为每个组件创建许多排列,以显示组件可能支持的每一种状态。

  • 通过编辑 Markdown 来修改组件状态对于开发人员和非技术用户来说并不直观。

为什么选择 Storybook

Storybook 是一个开源的 UI 开发和文档工具,过去几年在 Web 社区中越来越流行。它拥有强大的社区支持和丰富的插件生态系统,可用于易访问性测试、跨浏览器测试和其他用途。


在 Storybook 中,用户可以通过 Story 来逐个浏览和开发组件示例。Story 捕获了 React 组件的渲染状态,就像 Styleguidist 的 Markdown 示例一样。这与性能糟糕的 Styleguidist 形成了对比,Styleguidist 总是会渲染包中的每一个组件的每一个示例。


在 Styleguidist 中,开发人员经常需要为组件的每一个可视化排列创建一个示例,从而增加了维护负担(例如,在修改组件 API 后需要更新每一个示例)。在 Storybook 中,开发人员可以通过 react-docgen 自动生成控件,用户可以在文档 UI 中直接修改和预览组件。与 Styleguidist 相比,这进一步简化了用户体验,因为文档用户不再需要通过编辑 Markdown 来修改组件的状态。



一个 Styleguidist 沙盒示例


迁   移

我们的 React 代码库包含了数千个 Styleguidist 文件,每个文件中都有许多个组件示例。手动迁移它们是不可行的,强制要求开发人员手动用新的 Storybook 格式重写他们的示例也是不合理的。为了保持现有 React 组件示例并减少开发人员在迁移过程中的负担,我们列出了以下这些需求:


  • 我们现有的 Styleguidist 文件使用了 ES5 风格的导入和语法。我们希望新的 Storybook 语法与组件源代码保持一致,所以将使用 ES6。

  • 应该让使用过 Styleguidist 的开发人员对 Storybook 中的文档也感到熟悉。

    Storybook 支持 MDX,这是一种结合了 Markdown 和 JSX 的文件格式,可以用 Markdown 为文档页面渲染 React 组件,我们可以将现有的 Styleguidist Markdown 转成 MDX。

  • Styleguidist 中的每一个示例代码块都应该被翻译成一个 Story,组件的 stories.js 文件应该包含所有的示例。


为了实现这些目标,我们决定使用 Codemods 将我们的 Styleguidist 文件重构为 Storybook 格式。Codemods 是一系列基于脚本的操作,通过编程的方式对代码库进行转换,在不需要手动介入的情况下进行大规模的自动化修改。


首先,我们提取 Styleguidist 代码块,Markdown 文件中的其余内容(例如文字描述)可以直接逐字复制到新的 MDX 文件中。为了实现一对一的迁移,我们将每个代码块视为一个 Story。我们可以利用现有的工具,比如用 remark-code-blocks 来提取 JavaScript 代码块,用 5to6-codemod 将这些代码块中的 ES5 语法转换为 ES6 语法。


// 之前的代码:// const Button = require('../Button').default;import Button from '../Button';
复制代码


为了减少开发人员在迁移过程中的负担,我们决定将一个组件的所有 Story 都包含在同一个 component.stories.js 文件中,然后显示在 component.stories.mdx 文档页面中。然后我们发现 MDX 代码块是在相同的上下文中运行的,而且我们关于保持沙盒与 Styleguidist 隔离的假设是不对的。在将多个 Styleguidist 示例转换到同一个文件中时,这个问题尤为严重,因为将多个代码块连接在一起会导致重复导入:


import Button from '../Button';Full width `ButtonGroup` example:<ButtonGroup fill>(omitted for brevity)
复制代码


import Button from '../Button'; // <-- 这与上面的导入重复了!Disabled `ButtonGroup` example:<ButtonGroup disabled>(omitted for brevity)
复制代码


在将上面的 Story 合并到同一个 JS 文件中之后,Button 的导入就重复了。我们的 Codemod 需要解析并对这些导入进行去重,以防止出现运行时错误。另外,我们还需要包含 Styleguidist 隐式导入的组件:


// ButtonGroup.stories.jsimport Button from '../Button'; // 去重import { ButtonGroup } from './'; // 显式添加隐式导入的组件<ButtonGroup>    <Button text="Foo" />    <Button text="Bar" />    <Button text="Baz" /></ButtonGroup>
复制代码


接下来,我们将提取的 Markdown 代码块、去重的导入语句以及 ES 语法写到 component.stories.js 中,并在 component.stories.mdx 文件中写入标准的 Storybook 模板代码:


// ButtonGroup.stories.mdximport { ArgsTable, Canvas, Description, Meta, Story } from '@storybook/addon-docs';import * as stories from './ButtonGroup.stories.js';import { ButtonGroup } from './';
<Meta title="yelp-react-component-button/ButtonGroup" component={ButtonGroup}/>
The `<ButtonGroup />` component is used to arrange multiple `<Button />`components side-by-side.
<Canvas> <Story name="Example0" story={stories.Example0} /></Canvas>
复制代码


最后,我们需要通过 Storybook 让开发人员知道如何构建组件。我们可以用生产环境现有的 webpack 配置来扩展 Storybook 的构建配置,这样就可以保留 Storybook 的自动 docgen 功能,以及其他一些特性,比如代码块预览。使用现有的 webpack 配置也意味着组件的外观和行为与实际页面中的完全一样。


结  论


将 React 组件示例从 Styleguidist 迁移到 Storybook 极大地提升了开发者体验和组件性能。我们能够利用 Storybook 的特性,如按需加载,通过在编译时生成更小的包来提升性能,从而缩短沙盒的启动时间。基于我们的 Codemod 迁移策略,我们能够转换代码库中几乎所有的示例,而且不会出现运行时错误,在迁移过程中也不会对开发人员造成阻碍。


切换到 Storybook 为 Yelp 打开了新的大门,我们很高兴能在上面添加插件,进一步提升前端开发人员的工作效率。


我们希望我们的分享能够为其他面对类似迁移的团队带来有用的信息!


原文链接:


https://engineeringblog.yelp.com/2022/07/migrating-from-styleguidist-to-storybook.html


声明:本文为 InfoQ 翻译,未经许可禁止转载。


今日好文推荐


重磅!阿里开源自研高性能核心搜索引擎Havenask


程序员离职后为泄私愤远程锁公司服务器硬盘;前程无忧宣传语嘲讽“996”职场人;Twitter 开源工作停摆| Q资讯


再不重视软件开发工具就晚了


“睡车间”、削减一切,马斯克为SpaceX定制的文化,不能照搬到互联网公司


2022-12-15 11:268590

评论

发布
暂无评论
发现更多内容

英特尔推动UQD标准化落地,携手合作伙伴构筑液冷生态

E科讯

能源能耗分析平台(源码+文档+部署+讲解)

深圳亥时科技

可观测场景如何使用 Vector Remap 优化日志数据的解析与存储

Greptime 格睿科技

云原生 日志 vector 可观测 database

《京东金融APP的鸿蒙之旅系列专题》鸿蒙新特性篇:Hello, 仓颉 World

京东科技开发者

如何在敏捷开发中实现更好的需求管理

易成研发中心

需求管理 需求管理工具

基于枚举实现的状态流转控制

六哥是全栈

枚举 Java 8 状态机

国内外十大开源快速开发平台推荐

NocoBase

开源 低代码 快速开发 无代码

KWDB v2.1.0 发版说明

KWDB数据库

时序数据库 查询优化 分布式架构 DataX 数据查询

《一文讲透》第4-3期:KWDB 数据库运维 —— 安全与审计(上)

KWDB数据库

时序数据库 数据库运维 审计 数据库安全 多模数据库

华为视频多平台聚合,热门IP《白夜破晓》《珠帘玉幕》任你追

最新动态

华为阅读启动“乘国航 阅世界”国航伴读计划,3重好礼免费领!

最新动态

【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(6)

HarmonyOS SDK

HarmonyOS

hyperf-alarm-clock,一个自动计算代码执行时间,超时并发送通知的小工具

左诗右码

数智绩效合并报表:全球化合并实现财报精准高效

用友智能财务

科技 财务 企业数智化 财务软件

NocoBase 本周更新汇总:优化 REST API 数据源插件

NocoBase

开源 低代码 插件 无代码 版本更新

强化学习在众包差异化定价中的探索

京东科技开发者

【稳定性】上线三板斧(可灰度、可验证、可回滚)

京东科技开发者

用户指南 | 快速迁移 InfluxDB v2 数据至 GreptimeDB

Greptime 格睿科技

数据库 云原生 数据存储 数据迁移

保障管理系统(源码+文档+部署+讲解)

深圳亥时科技

为什么说逻辑数据编织是一种低门槛、高容错度、高 ROI 的数据集成与开发模式?

Aloudata

数据仓库 数据开发 数据集成 数据虚拟化 数据编织

释放数据生产力——数据编织的价值实现与评估

Aloudata

数据分析 数据开发 数据集成 数据虚拟化 数据编织

【论文速读】| 人工智能驱动的网络威胁情报自动化

云起无垠

某充电桩业务服务内存监控和程序行为分析

乘云数字DataBuff

运维 内存监控

长上下文语言模型评估体系探析

Baihai IDP

程序员 AI LLMs 长上下文语言模型

从 Styleguidist 迁移到 Storybook_语言 & 开发_InfoQ精选文章