JavaScript内核与高级编程之:`JavaScript` 的 `Storybook`:其在组件开发和文档生成中的 `JS` 实践。

各位靓仔靓女们,晚上好!我是你们的老朋友,今天咱们聊点好玩的,关于 JavaScript 的 Storybook,保证让你听完之后,腰不酸了,腿不疼了,写组件也更有劲了!

今天的主题是: JavaScript 的 Storybook:其在组件开发和文档生成中的 JS 实践

咱们的讲座将从以下几个方面展开:

  1. Storybook 是个啥玩意儿?(入门介绍)
  2. 为啥要用 Storybook?(痛点分析)
  3. 手把手教你搭建 Storybook 环境(实战演练)
  4. 编写 Story,让你的组件活起来!(核心技巧)
  5. Storybook 的高级用法(锦上添花)
  6. Storybook 在团队协作中的作用(效率提升)
  7. 常见问题与解决方案(避坑指南)

废话不多说,咱们开始吧!

1. Storybook 是个啥玩意儿?(入门介绍)

想象一下,你是一个辛勤的码农,每天都在写各种各样的组件。这些组件就像一个个乐高积木,最终拼成一个完整的页面。但是,在你拼积木之前,你得先看看这些积木长啥样,能不能用,对不对?

Storybook 就是一个专门用来展示和测试这些组件的“积木展示台”。它是一个独立的 UI 开发环境,让你可以在不依赖整个应用的情况下,单独地开发和测试你的组件。

简单来说,Storybook 提供了一个隔离的环境,让你能够:

  • 清晰地看到每个组件的不同状态:比如,按钮的默认状态、hover 状态、disabled 状态等等。
  • 方便地与组件进行交互:你可以直接在 Storybook 中点击按钮、输入文字,看看组件的反应。
  • 快速地迭代开发:修改组件的代码后,Storybook 会自动刷新,让你立即看到效果。

2. 为啥要用 Storybook?(痛点分析)

可能有些同学会说:“我直接在项目里开发组件不行吗?为啥要用 Storybook 这么麻烦?”

问得好!直接在项目里开发组件当然可以,但是可能会遇到以下几个问题:

  • 环境依赖复杂:组件可能依赖于整个应用的状态、数据和样式,导致开发和测试变得很困难。
  • 开发效率低下:每次修改组件的代码后,都需要重新编译整个应用,才能看到效果。
  • 难以进行独立测试:很难针对组件的各种状态和交互进行全面的测试。
  • 缺乏清晰的文档:没有一个集中的地方来展示和描述组件的使用方法。

Storybook 就像一个“组件游乐场”,它解决了这些痛点,让你能够:

  • 隔离开发:专注于组件本身,不受其他因素的干扰。
  • 提高效率:快速迭代开发,实时预览效果。
  • 方便测试:针对各种状态和交互进行全面的测试。
  • 生成文档:自动生成组件的文档,方便团队成员使用。

3. 手把手教你搭建 Storybook 环境(实战演练)

说了这么多,不如直接上手试试!咱们以一个 React 项目为例,来搭建一个 Storybook 环境。

首先,你需要确保你的项目中安装了 Node.js 和 npm (或者 yarn)。

然后,打开你的终端,进入项目目录,运行以下命令:

npx sb init

这个命令会自动检测你的项目类型,并安装 Storybook 相关的依赖。

安装完成后,你会发现你的项目中多了一个 .storybook 文件夹和一个 stories 文件夹。

  • .storybook 文件夹:用于配置 Storybook 的各种选项,比如主题、插件等等。
  • stories 文件夹:用于存放你的组件的故事(Story),也就是描述组件不同状态的代码。

接下来,启动 Storybook:

npm run storybook

或者

yarn storybook

稍等片刻,你的浏览器会自动打开 Storybook 的界面,你会看到一些默认的 Story,比如 Button、Header 等等。

4. 编写 Story,让你的组件活起来!(核心技巧)

现在,咱们来编写一个 Story,让你的组件活起来!

假设你有一个简单的 React 组件 MyButton

// src/components/MyButton.js
import React from 'react';

const MyButton = ({ label, onClick, disabled }) => {
  return (
    <button onClick={onClick} disabled={disabled}>
      {label}
    </button>
  );
};

export default MyButton;

接下来,创建一个 Story 文件 src/components/MyButton.stories.js

// src/components/MyButton.stories.js
import React from 'react';
import MyButton from './MyButton';

export default {
  title: 'Components/MyButton', // 定义 Story 在 Storybook 中的分类
  component: MyButton, // 指定要展示的组件
};

const Template = (args) => <MyButton {...args} />;

export const Primary = Template.bind({});
Primary.args = {
  label: 'Primary Button',
  onClick: () => alert('Clicked!'),
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: 'Secondary Button',
  disabled: true,
};

这个 Story 文件做了以下几件事:

  • export default:定义了 Storybook 的配置,包括 Story 的标题(title)和要展示的组件(component)。
  • Template:定义了一个模板函数,用于渲染组件。
  • PrimarySecondary:定义了两个 Story,分别展示了 MyButton 组件的不同状态。args 属性用于传递组件的 props。

现在,刷新 Storybook 界面,你会看到 MyButton 组件出现在了左侧的菜单中,你可以点击 PrimarySecondary Story,查看组件的不同状态。

表格总结:Story 文件结构

属性 描述
title 定义 Story 在 Storybook 中的分类,可以使用斜杠 / 来创建层级结构。例如:Components/MyButton 表示 MyButton 组件位于 Components 分类下。
component 指定要展示的组件。
Template 定义一个模板函数,用于渲染组件。通常使用 bind({}) 方法来创建一个新的函数,并绑定 this 上下文。
args 用于传递组件的 props。可以在 Story 中覆盖默认的 args 值,以展示组件的不同状态。

5. Storybook 的高级用法(锦上添花)

Storybook 除了基本的组件展示功能外,还提供了很多高级用法,可以帮助你更好地开发和测试组件。

  • Addons(插件):Storybook 提供了丰富的插件,可以扩展其功能。比如:

    • @storybook/addon-knobs:允许你在 Storybook 界面中动态修改组件的 props。
    • @storybook/addon-actions:记录组件的事件触发情况。
    • @storybook/addon-viewport:模拟不同的屏幕尺寸。
    • @storybook/addon-docs:自动生成组件的文档。

    安装 Addons 的方法很简单,只需要运行 npm install 或者 yarn add 命令,然后在 .storybook/main.js 文件中配置即可。

    例如,安装 @storybook/addon-knobs

    npm install --save-dev @storybook/addon-knobs

    然后在 .storybook/main.js 文件中添加:

    // .storybook/main.js
    module.exports = {
      stories: ['../src/**/*.stories.js'],
      addons: ['@storybook/addon-knobs'],
    };

    使用 @storybook/addon-knobs

    // src/components/MyButton.stories.js
    import React from 'react';
    import MyButton from './MyButton';
    import { text, boolean } from '@storybook/addon-knobs';
    
    export default {
      title: 'Components/MyButton',
      component: MyButton,
    };
    
    const Template = (args) => <MyButton {...args} />;
    
    export const Primary = Template.bind({});
    Primary.args = {
      label: text('Label', 'Primary Button'), // 使用 text 方法创建一个可编辑的 label
      disabled: boolean('Disabled', false), // 使用 boolean 方法创建一个可编辑的 disabled 属性
    };

    现在,你可以在 Storybook 界面中动态修改 labeldisabled 属性的值,看看组件的反应。

  • Controls:Controls 是 Storybook 6.0 之后引入的新特性,它可以替代 @storybook/addon-knobs,提供更强大的 props 控制功能。Controls 会自动根据组件的 propTypes 生成相应的 UI 控件,让你可以在 Storybook 界面中方便地修改 props。

    使用 Controls:

    // src/components/MyButton.stories.js
    import React from 'react';
    import MyButton from './MyButton';
    
    export default {
      title: 'Components/MyButton',
      component: MyButton,
      argTypes: {
        label: { control: 'text' }, // 指定 label 属性的 Control 类型为 text
        disabled: { control: 'boolean' }, // 指定 disabled 属性的 Control 类型为 boolean
        onClick: { action: 'clicked' }, // 使用 action 记录 onClick 事件的触发
      },
    };
    
    const Template = (args) => <MyButton {...args} />;
    
    export const Primary = Template.bind({});
    Primary.args = {
      label: 'Primary Button',
    };

    现在,你可以在 Storybook 界面中看到 labeldisabled 属性的 Control 控件,可以直接修改它们的值。

  • Docs(文档):Storybook 可以自动生成组件的文档,包括组件的 props、示例代码等等。你可以使用 @storybook/addon-docs 插件来生成文档。

    安装 @storybook/addon-docs

    npm install --save-dev @storybook/addon-docs

    然后在 .storybook/main.js 文件中添加:

    // .storybook/main.js
    module.exports = {
      stories: ['../src/**/*.stories.js'],
      addons: ['@storybook/addon-docs'],
    };

    在 Story 文件中添加文档:

    // src/components/MyButton.stories.js
    import React from 'react';
    import MyButton from './MyButton';
    
    export default {
      title: 'Components/MyButton',
      component: MyButton,
      argTypes: {
        label: { control: 'text', description: '按钮的文字' }, // 添加 description
        disabled: { control: 'boolean', description: '是否禁用按钮' }, // 添加 description
        onClick: { action: 'clicked' },
      },
      parameters: {
        docs: {
          description: {
            component: '这是一个自定义的按钮组件。', // 添加组件的描述
          },
        },
      },
    };
    
    const Template = (args) => <MyButton {...args} />;
    
    export const Primary = Template.bind({});
    Primary.args = {
      label: 'Primary Button',
    };

    现在,在 Storybook 界面中,你会看到一个 "Docs" 标签,点击它就可以查看组件的文档。

6. Storybook 在团队协作中的作用(效率提升)

Storybook 不仅可以帮助你更好地开发和测试组件,还可以提高团队的协作效率。

  • 统一组件库:Storybook 可以作为团队的组件库,让所有成员都可以方便地查看和使用组件。
  • 代码复用:通过 Storybook,团队成员可以更容易地发现和复用现有的组件,避免重复造轮子。
  • 设计一致性:Storybook 可以帮助团队保持设计的一致性,确保所有组件都符合设计规范。
  • 方便 Code Review:在 Code Review 的时候,可以通过 Storybook 来快速预览组件的效果,提高 Review 的效率。

7. 常见问题与解决方案(避坑指南)

在使用 Storybook 的过程中,可能会遇到一些问题,这里列举一些常见的问题和解决方案:

  • Storybook 启动失败
    • 检查 Node.js 和 npm (或者 yarn) 的版本是否符合要求。
    • 检查依赖是否安装完整。
    • 检查 .storybook 文件夹中的配置是否正确。
  • Storybook 界面显示空白
    • 检查 Story 文件中的代码是否正确。
    • 检查组件是否正确导出。
    • 尝试清除浏览器缓存。
  • Addons 安装失败
    • 检查 Addons 的版本是否与 Storybook 的版本兼容。
    • 检查 .storybook/main.js 文件中的配置是否正确。
  • Controls 不生效
    • 检查组件是否定义了 propTypes。
    • 检查 argTypes 属性的配置是否正确。

总结

Storybook 是一个非常强大的 UI 开发工具,它可以帮助你更好地开发、测试和文档化组件。通过 Storybook,你可以提高开发效率,保持设计一致性,并促进团队协作。

希望今天的讲座能够帮助你更好地理解和使用 Storybook。记住,实践才是检验真理的唯一标准,赶快动手试试吧!

祝大家编码愉快!下课!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注