阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

从 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:266017

评论

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

Salesforce架构师的10大原则

俞凡

架构 大厂实践 Salesforce

大画 Spark :: 网络(2)-下篇-通过网络收取消息的过程

dclar

大数据 spark 源代码 Spark 源码

LabVIEW条形码识别(实战篇—5)

不脱发的程序猿

图像识别 机器视觉 图像处理 LabVIEW 条形码识别

Go 语言快速入门指南:Go 转 JSON

宇宙之一粟

Go JSON序列化 1月月更

Go编译原理系列5(抽象语法树构建)

书旅

Go 后端 编译原理 编译语言

模块九作业:设计电商秒杀系统

危险游戏

架构实战营

火狐浏览器一败涂地?

Jackpop

如何保证消息消费时的幂等性?

JavaEdge

1月月更

王者荣耀商城异地多活架构设计

ren

Apache Atlas 数据血缘

亚马逊云科技 (Amazon Web Services)

存储

关于项目中 Repository 层的思考

CRMEB

基于Amazon ECS Fargate构建Apache Superset

亚马逊云科技 (Amazon Web Services)

存储

毕业设计项目

panxiaochun

架构实战营

ReactNative进阶(十七):RefreshControl 组件实现刷新效果

No Silver Bullet

1月月更 ReactNative RefreshControl

2021年行摄回忆录

穿过生命散发芬芳

盘点2021 1月月更

三行代码下载抖音视频

你?

【SpringCloud技术专题】「Gateway网关系列」微服务网关服务的Gateway全流程开发实践指南(2.2.X)

洛神灬殇

SpringCloud SpringCloud Gateway API Gateway 1月月更

低代码实现探索(十九)低代码的意义

零道云-混合式低代码平台

程序员的快乐,只需要这7款工具!

Jackpop

没有区块链,就没有元宇宙

CECBC

小白都能吃透 Java IOl 流,最骚最全笔记,没有之一!2️⃣

XiaoLin_Java

云原生训练营毕业总结

9527

低代码实现探索(十八)流程中参数的初始化设计

零道云-混合式低代码平台

简讯:明道云近期荣获的三项荣誉

明道云

架构实战营 - 毕业设计

随风King

「架构实战营」

有传闻说,写好总结可以升职加薪?

程序人生

虚拟数字人发展提速 多家银行宣布“造人”

CECBC

记一次安全漏洞分析

网络安全学海

黑客 网络安全 信息安全 渗透测试 安全漏洞

偷偷看了同事的代码找到了优雅代码的秘密

慕枫技术笔记

后端 1月月更

Weblogic-SSRF漏洞复现

喀拉峻

网络安全 安全 信息安全

加速数字经济发展,2022更需要云上创新的稳定器与推动力

脑极体

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