写点什么

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

评论

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

企业转型难?火山引擎数智平台提供数智升级新路径

字节跳动数据平台

大数据 数据中台 12 月 PK 榜

Amazon 4.7 星评,领域新经典,了解服务设计就读它

图灵社区

产品经理 设计模式 服务设计

自动化测试技术笔记(二):准备工作的切入点

老张

自动化测试

Java程序员培训机构怎么选

小谷哥

培训班出来前端程序员好找吗?

小谷哥

HTTP报文内容

穿过生命散发芬芳

HTTP 12月月更

新华三推出人工智能模型训练平台,让智慧算力触手可及

脑极体

参加大数据培训可以找到工作吗

小谷哥

软件测试培训 | 在霍格沃兹测试开发学社学习是种怎样的体验?

霍格沃兹测试开发学社

专利解析|数据中台—数据流配置弹框交互优化方法

元年技术洞察

数据中台 数字化转型 专利解析

我把传统业务架构升级到业务中台架构的心得

大东(AIP内容运营专员)

学习掌握哪些前端技术才能找到好工作?

小谷哥

阿里云视觉智能开放平台——人脸活体检测算法重磅升级

夏夜许游

服务升级 人脸活体检测 人脸人体

直播|HashData信创概览

酷克数据HashData

信创

大咖说·开源人说|数据库 PolarDB 开源的商业逻辑与价值思考

大咖说

数据库 阿里云 开源

我对中台的理解和企业数字中台建设的思考

大东(AIP内容运营专员)

迁移速度与计算性能兼得!天翼云DirtyLimit技术大显身手

天翼云开发者社区

虚拟机 迁移 弹性计算

【经验总结】HDI与普通PCB的4点主要区别

华秋PCB

工艺 PCB PCB设计

如何优化大场景实时渲染?HMS Core 3D Engine这么做

HarmonyOS SDK

HMS Core

智能合约DAPP开发WEB3.0系统搭建技术

薇電13242772558

智能合约

小游戏流量变现都有哪些窍门?

FinFish

小游戏 微信小程序-游戏 小程序游戏 微信小游戏

数据存储,消息队列的高可用保障

C++后台开发

数据库 数据结构 消息队列 后端开发 linux开发

Laravel中HasOne和BelongsTo的区别

ModStart

我对管理角色带团队的一些经验分享

大东(AIP内容运营专员)

【FAQ】申请Health Kit权限的常见问题及解答

HarmonyOS SDK

HMS Core

RocketMQ Schema——让消息成为流动的结构化数据

Apache RocketMQ

RocketMQ

汽车之家基于 Milvus 的向量检索平台实践

Zilliz

数据库 向量检索 Milvus

重磅!TDengine 3.2.0 正式发布

TDengine

数据库 tdengine 时序数据库

隐匿于喧嚣城市的世外桃源,「武汉浮生艺术馆」开放小程序预约通道,顺利举办多场艺术展览

天天预约

小程序 SaaS 预约工具 展览 艺术馆

我把整个研发中台拆分过程的一些心得总结

大东(AIP内容运营专员)

在新基建数字化的时代,寻找自我的突破和价值创造

大东(AIP内容运营专员)

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