Docs
Storybook Docs

贡献 Storybook 框架

Storybook 框架是一个节点包,它支持元框架(Next.js、NuxtJS、SvelteKit)或 builder(Webpack、Vite)与渲染器(React、Angular、Vue 3、Web 组件等)的组合的开箱即用支持。

¥A Storybook framework is a node package that enables out-of-the-box support for either a metaframework (Next.js, NuxtJS, SvelteKit) or a combination of builder (Webpack, Vite) plus renderer (React, Angular, Vue 3, web components, etc).

对于元框架,Storybook 框架还负责使 Storybook 的行为类似于元框架生成的应用所需的其他配置。例如,Storybook 中的 @storybook/nextjs 重新创建或模拟 Next.js 应用的许多功能

¥For metaframeworks, the Storybook framework also takes care of additional configuration necessary to make Storybook behave similarly to apps generated by the metaframework. For example, @storybook/nextjs recreates or mocks a number of features of Next.js apps inside Storybook.

供你参考,你可以查看 所有官方 Storybook 框架,包括其完整的源代码和文档。

¥For your reference, you can view all of the official Storybook frameworks, including their full source code and documentation.

如何制作框架

¥How to make a framework

1. 确定包名称

¥ Decide on a package name

名称应以 storybook-framework- 开头,然后与你的框架支持的名称相对应。例如,针对 SvelteKit 的框架将是 storybook-framework-svelte-kit,而针对带有 Vite 的 Stencil 的框架将是 storybook-framework-stencil-vite。当不针对元框架时,命名约定为 storybook-framework-<renderer>-<builder>

¥The name should start with storybook-framework- and then correspond to what your framework supports. For example, a framework targeting SvelteKit would be storybook-framework-svelte-kit and a framework targeting Stencil with Vite would be storybook-framework-stencil-vite. When not targeting a metaframework, the naming convention is storybook-framework-<renderer>-<builder>.

2. 考虑你的框架需要做什么

¥ Consider what your framework will need to do

目标是让 Storybook 的行为尽可能类似于你所针对的元框架或构建器-渲染器组合(开箱即用)。

¥The goal is to make Storybook behave—out-of-the-box—as similarly as possible to the metaframework or builder-renderer combination you’re targeting.

对于元框架,这意味着尝试重新创建元框架提供的任何构建器或 babel 配置。你应该尝试以尽可能尊重用户现有项目配置的方式执行此操作。

¥For metaframeworks, this means attempting to recreate any builder or babel configuration provided by the metaframework. You should try to do so in a way that respects the user's existing project configuration as much as possible.

你的框架支持的库可能有不同的主要版本可用。考虑你的框架将支持每个库的哪些版本。你需要考虑这些不同版本中的更改,或者将框架本身拆分为不同的版本/包以支持每个库版本。为了加快维护速度,请考虑为框架支持的各种库版本添加集成测试。

¥The library or libraries your framework supports may have different major versions available. Consider which versions of each library your framework will support. You will need to account for the changes within those different versions or split your framework into different versions/packages itself to support each library version. To speed up maintenance, please consider adding integration tests for the various library versions your framework supports.

3. 编写文档

¥ Write the documentation

在编写任何代码之前,请编写一个有用的 README,其中包含安装说明和可用功能列表。使用 @storybook/nextjs 的自述文件 作为模板。首先编写文档有助于指导你的其他工作。

¥Before writing any code, write a helpful README that contains installation instructions and a list of available features. Use the README for @storybook/nextjs as a template. Writing the documentation first helps guide your other work.

4. 编写框架本身

¥ Author the framework itself

框架可以包含以下部分:

¥A framework can contain the following parts:

package.json(example)

因为框架是一个节点包,所以它必须包含一个 package.json 文件。以下是你可以用来开始的模板:

¥Because a framework is a node package, it must contain a package.json file. Here’s a template you can use to start:

package.json template
{
  "name": "<your-framework-name>",
  "version": "1.0.0",
  "description": "Storybook for <meta-framework-name> or <renderer> & <builder>",
  "keywords": [
    "Storybook",
    "<meta-framework-name>",
    "<renderer>",
    "<builder>",
    "<anything>",
    "<else>",
    "<relevant>"
  ],
  "homepage": "<your package's homepage>",
  "bugs": {
    "url": "https://github.com/<your-org>/<your-repo>/issues"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/<your-org>/<your-repo>.git",
    "directory": "<path/to/your/framework>"
  },
  "license": "MIT",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "require": "./dist/index.js",
      "import": "./dist/index.mjs"
    },
    "./preset": {
      "types": "./dist/preset.d.ts",
      "require": "./dist/preset.js",
      "import": "./dist/preset.mjs"
    },
    "./preview.js": {
      "types": "./dist/preview.d.ts",
      "require": "./dist/preview.js",
      "import": "./dist/preview.mjs"
    },
    "./package.json": "./package.json"
  },
  "main": "dist/index.js",
  "module": "dist/index.mjs",
  "types": "dist/index.d.ts",
  "files": ["dist/**/*", "types/**/*", "README.md", "*.js", "*.d.ts"],
  "scripts": {
    "check": "tsc --noEmit",
    "test": "..."
  },
  "dependencies": {
    "@storybook/manager-api": "^7.0.0",
    "@storybook/core-common": "^7.0.0",
    "@storybook/node-logger": "^7.0.0",
    "@storybook/<builder>": "^7.0.0",
    "@storybook/<renderer>": "^7.0.0"
  },
  "devDependencies": {
    "typescript": "x.x.x",
    "<meta-framework>": "^x.x.x",
    "<builder>": "^x.x.x"
  },
  "peerDependencies": {
    "@storybook/addon-actions": "^7.0.0",
    "<meta-framework>": "^x.x.x || ^x.x.x",
    "<renderer>": "^x.x.x || ^x.x.x",
    "<builder>": "^x.x.x"
  },
  "engines": {
    "node": ">=18.0.0"
  },
  "publishConfig": {
    "access": "public"
  }
}

关于其中一些属性的一些说明:

¥A few notes on some of those properties:

  • exports:需要根、./presetpackage.json 导出。如果你的框架有 preview.js,那么这也是必需的。

    ¥exports: The root, ./preset, and package.json exports are required. If your framework has a preview.js, then that is required as well.

  • types:我们强烈建议你使用 TypeScript 编写框架并分发类型。

    ¥types: We strongly encourage you to author your framework in TypeScript and distribute the types.

  • dependenciesdevDependencies:这些只是示例。你的可能看起来完全不同。

    ¥dependencies and devDependencies: These are just examples. Yours may look quite different.

  • peerDependencies:如果你的框架为你所针对的库的多个版本提供支持,请确保在此处表示出来。

    ¥peerDependencies: If your framework provides support for multiple versions of the libraries you’re targeting, be sure that is represented here.

preset.js(example)

预设 API 是你配置 Storybook 核心(框架使用哪个构建器和渲染器)、构建器(通过 webpackFinalviteFinal 导出)、babel(通过 babel 导出)、任何必要的插件以及框架的任何可用选项的地方。

¥The preset API is where you will configure the Storybook core (which builder and renderer are used by your framework), the builder (via either the webpackFinal or viteFinal export), babel (via the babel export), any necessary addons, and any available options for your framework.

preview.js(example)

(可选)预览 API 是你配置故事渲染的地方,例如全局装饰器或初始化框架按预期运行所需的一些运行时配置。如果你的框架需要此文件,请注意你还需要 preset.js 中配置 previewAnnotations

¥The (optional) preview API is where you configure the rendering of stories, such as global decorators or initializing some runtime config needed for your framework to behave as expected. If your framework requires this file, note that you also need to configure the previewAnnotations in preset.js.

types.ts(example)

如果你使用 TypeScript 编写框架(推荐),则应导出 StorybookConfig 的类型,该类型反映了框架的可用选项。

¥If you author your framework in TypeScript (recommended), you should export the type for StorybookConfig which reflects the available options of your framework.

5. 测试你的框架

¥ Test your framework

使用尽可能接近框架的 Storybook 在新的项目中对其进行测试。例如,对于使用 React 和 Webpack5 的 @storybook/nextjs,从使用 @storybook/react@storybook/builder-webpack5 的项目开始。按照 README 中的安装说明进行操作,并确保一切按预期运行。请记住测试你支持的库的各种版本、配置和选项。

¥Test it in a fresh project using a Storybook set up as close as possible to your framework. For example, for @storybook/nextjs, which uses React and Webpack5, start with a project that uses @storybook/react and @storybook/builder-webpack5. Follow the installation instructions from your README and ensure everything works as expected. Remember to test the various versions, configs, and options for the libraries you’re supporting.

6. 让我们知道!

¥ Let us know!

一旦它经过全面测试和发布,请通过在 #showcase Discord 通道中宣布它或在推特上提及 @storybookjs 来让我们了解你的框架。我们希望精心制作的社区框架最终能够进入 Storybook 代码库并被视为支持 "officially"。

¥Once it's fully tested and released, please let us know about your framework by either announcing it in the #showcase Discord channel or tweeting it and mentioning @storybookjs. It's our hope that well-made community frameworks can eventually move into the Storybook codebase and be considered "officially" supported.

了解有关为 Storybook 做贡献的更多信息

¥Learn more about contributing to Storybook

  • RFC 流程 用于编写功能请求

    ¥RFC process for authoring feature requests

  • 代码 用于功能和错误修复

    ¥Code for features and bug fixes

  • 开始使用新框架的框架

    ¥Frameworks to get started with a new framework

  • 文档 用于文档改进、拼写错误和澄清

    ¥Documentation for documentation improvements, typos, and clarifications

  • 示例 提供有关新代码片段和示例

    ¥Examples for new snippets and examples