Redian新闻
>
从 Styleguidist 迁移到 Storybook

从 Styleguidist 迁移到 Storybook

公众号新闻

作者丨 Kedar Vaidya 、Benson Pan
译者丨明知山
策划丨 Tina

提供一流的开发者体验是 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 示例转换到同一个文件中时,这个问题尤为严重,因为将多个代码块连接在一起会导致重复导入:

```jsximport Button from '../Button';Full width `ButtonGroup` example:<ButtonGroup fill>(omitted for brevity)```
```jsximport 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定制的文化,不能照搬到互联网公司

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
美好夏天:美丽的安大略湖Vue 3是最佳选择吗? 耗时两周从Vue 2迁移到Svelte后:代码执行更快、体验更佳《最后的诗歌》: 11: 早晨在那边眨眼迁移学习「求解」偏微分方程,条件偏移下PDE的深度迁移算子学习奥兰多独栋别墅位于 Stoneybrook 享有美丽水景 售价51.5万美金从Oracle迁移到openGauss实战分享AACO College Panel: From High School to CollegeChina’s Booming New Toy Market: Hyperrealistic ‘Military Lego’瞧不上 C++ 和 D 语言,国外程序员将 5.8 万行代码迁移到 Jai 语言,到底图什么?自从用了CheckStyle插件,代码写的越来越规范了....7 Papers | 英伟达64个A100训练StyleGAN-T;9类生成式AI模型综述积木式深度学习的正确玩法!新加坡国立大学发布全新迁移学习范式DeRy,把知识迁移玩成活字印刷|NeurIPS 2022三星 Galaxy Book 3 Ultra 笔记本真机曝光,对标苹果 MacBook ProUnity 7.7桌面环境将推出支持Wayland的UnityX风味版本顶刊TIP2022!领域迁移Adaboost,让模型“选择”学哪些数据!U-loop & Fairybean“武之道”:肃杀战场上横舞长刀的女武士!Overcapacity Plagues China’s Dairy Sector as Demand DampensGAN强势归来?英伟达耗费64个A100训练StyleGAN-T,优于扩散模型摩洛哥十日游之一,被代表中国游客Gurman:苹果M2 Pro / Max MacBook Pro14/16英寸和Mac Pro新款将于23年Q1发布最新!白宫圣诞装饰揭幕, 还记得川普当年“爆发富”style吗?我刷故我在英伟达超快StyleGAN回归,比Stable Diffusion快30多倍,网友:GAN好像只剩下快了上海最高纪录同时有四个全国甲级队第65届格莱美落幕,Beyoncé打破获奖历史 赢得32座格莱美奖!霉霉、Adele、Harry Styles等均或等年度大奖BenQ GW2780 27" Slim Bezel LED Stylish Monitor fhdEasyList “瘫痪”,将被迫迁移Logitech Pro Y-U0031 Tenkeyless Wired Gaming KeyboardCHERRY MX 8.0 RGB Gaming Keyboard MX Blue SwitchCyber Monday折扣汇总:Booking圣诞旅行巨折!AMI/雅诗兰黛/LaMer最后一天!ProGAN、StyleGAN、Diffusion GAN…你都掌握了吗?一文总结图像生成必备经典模型(一)Gurman:苹果正开发包括 MacBook Pro 在内的触摸屏 Mac 电脑NeurIPS 2022 | 全新迁移学习范式DeRy,把知识迁移玩成活字印刷Fluent Mybatis、原生Mybatis,、Mybatis Plus 大对比,哪个更好用?Macbook Air 13in 2020 (M1/8gram/256g SSD/battery health 98)
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。