写点什么

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

评论

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

公排自动滑落模式智能合约dapp系统开发逻辑详情

开发微hkkf5566

用 Pytest+Allure 生成漂亮的 HTML 图形化测试报告

霍格沃兹测试开发学社

跨平台API对接(Python)的使用

霍格沃兹测试开发学社

面试 | 今日头条测试开发岗位面试题目回顾

霍格沃兹测试开发学社

测试面试题集锦(五)| 自动化测试与性能测试篇(附答案)

霍格沃兹测试开发学社

技术分享 | 黑盒测试方法论-判定表

霍格沃兹测试开发学社

最流行的接口测试体系,从入门到项目实战

霍格沃兹测试开发学社

测试开发基础|一文搞定计算机网络(一)

霍格沃兹测试开发学社

测试必会 | 通过容器化 Python Web 应用掌握 Docker 容器核心技能

霍格沃兹测试开发学社

测试面试真题 | 从屡次碰壁到成长蜕变,半年拿下某大厂 60W 年薪测试开发 Offer!

霍格沃兹测试开发学社

测试面试真题|工作2年,从小厂到大厂,薪资翻倍是怎样的体验?

霍格沃兹测试开发学社

测试面试题集锦(三)| 计算机网络和数据库篇(附答案)

霍格沃兹测试开发学社

业务场景抽离,助力测试提效

转转技术团队

软件测试最常用的 SQL 命令 | 通过实例掌握基本查询、条件查询、聚合查询

霍格沃兹测试开发学社

测试开发基础 mvn test | 利用 Maven Surefire Plugin 做测试用例基础执行管理

霍格沃兹测试开发学社

软件测试最常用的 SQL 命令(二) | 高级 Join 多表查询

霍格沃兹测试开发学社

接口自动化你不懂?听HttpRunner的作者怎么说

霍格沃兹测试开发学社

测试开发基础 | 计算机网络篇(二):物理层与数据链路层

霍格沃兹测试开发学社

测试面试题集锦(二)| 测试工具篇(附答案)

霍格沃兹测试开发学社

测试面试题集锦(六)| 软素质篇与反问面试官篇(附答案)

霍格沃兹测试开发学社

版本控制神器GitHub的基本使用与踩坑,教你一铲子填平!

霍格沃兹测试开发学社

该如何测客户端专项测试?

霍格沃兹测试开发学社

墨天轮沙龙 | 庚顿数据姚羽:实时数据技术赋能流程工业,保障业务连续性

墨天轮

数据库 国产数据库 实时数据库

飞书项目负责人洪涛:从抖音研发到飞书项目背后的管理经验

B Impact

飞书 飞书项目

测试工程师如何突破职场瓶颈?

霍格沃兹测试开发学社

面试 | Python 自动化测试技术面试真题

霍格沃兹测试开发学社

智能遍历测试在回归测试与健壮性测试的应用

霍格沃兹测试开发学社

构建测试平台与对应的组织架构需要哪些能力? 21/100

霍格沃兹测试开发学社

Github点击破百万!这部《从零开始学架构》神书就此霸榜

Java-fenn

Java 程序员 java面试 Java面试题 Java面试Java面试题

电商性能测试实战 | JMeter 插件 Ultimate Thread Group 完成梯度递增场景的压测

霍格沃兹测试开发学社

聊聊后端Web开发框架(Python)的简单使用

霍格沃兹测试开发学社

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