文件
Storybook 文件

編寫預設擴充功能

Storybook 預設設定是預先設定的設定或組態,可讓開發人員快速設定並使用一組特定的功能、特色或整合來自訂其環境。

預設設定如何運作

預設擴充功能可讓開發人員透過 API 組合各種組態選項和外掛程式,以與 Storybook 整合並自訂其行為和功能。通常,預設設定會分成兩個檔案,每個檔案都有其特定角色。

本機預設設定

這種預設設定可讓您封裝和組織特定於擴充功能的組態,包括建置器支援、Babel 或第三方整合。例如

example-addon/src/preset.ts
import { webpackFinal as webpack } from './webpack/webpackFinal';
 
import { viteFinal as vite } from './vite/viteFinal';
 
import { babelDefault as babel } from './babel/babelDefault';
 
export const webpackFinal = webpack as any;
 
export const viteFinal = vite as any;
 
export const babelDefault = babel as any;

根層級預設設定

這種預設設定是面向使用者的,負責註冊擴充功能,而使用者無需額外組態,方法是透過 previewAnnotations 和 UI 相關功能 (例如,擴充功能) 透過 managerEntries API 來捆綁 Storybook 相關功能 (例如,參數)。例如

example-addon/preset.js
export const previewAnnotations = [require.resolve('./dist/preview')];
 
export const managerEntries = [require.resolve('./dist/manager')];
 
export * from './dist/preset';

預設設定 API

編寫預設設定時,您可以存取一組選定的 API 來與 Storybook 環境互動,包括支援的建置器 (例如 Webpack、Vite)、Storybook 組態和 UI。以下是您在編寫預設擴充功能時可以使用的可用 API。

Babel

若要自訂 Storybook 的 Babel 組態並新增對其他功能的支援,您可以使用 babelDefault API。它會在任何其他使用者預設設定之前套用提供的組態,最終使用者可以透過 babel 組態選項進一步自訂。例如

example-addon/src/babel/babelDefault.ts
import { TransformOptions } from '@babel/core';
 
export function babelDefault(config: TransformOptions) {
  return {
    ...config,
    plugins: [
      ...config.plugins,
      [require.resolve('@babel/plugin-transform-react-jsx'), {}, 'preset'],
    ],
  };
}

Babel 組態僅適用於內部使用 Babel 的框架。如果您為使用不同編譯器 (例如 SWCesbuild) 的框架啟用,則會遭到忽略。

建置器

根據預設,Storybook 支援業界領先的建置器,包括 WebpackVite。如果您需要這些建置器的任何其他功能,可以使用 API 根據您的特定需求擴充建置器組態。

Vite如果您正在建立預設配置,並希望加入 Vite 支援,可以使用 viteFinal API 來修改預設配置並啟用其他功能。例如:

example-addon/src/vite/viteFinal.ts
export function ViteFinal(config: any, options: any = {}) {
  config.plugins.push(
    new MyCustomPlugin({
      someOption: true,
    }),
  );
 
  return config;
}

Webpack

若要在 Storybook 中自訂 Webpack 設定,以新增對其他檔案類型的支援、套用特定的載入器、設定外掛程式,或進行任何其他必要的修改,您可以使用 webpackFinal API。 一旦呼叫,它將使用提供的配置擴展預設的 Webpack 配置。 以下是一個範例:

example-addon/src/webpack/webpackFinal.ts
import type { Configuration as WebpackConfig } from 'webpack';
 
export function webpackFinal(config: WebpackConfig, options: any = {}) {
  const rules = [
    ...(config.module?.rules || []),
    {
      test: /\.custom-file$/,
      loader: require.resolve(`custom-loader`),
    },
  ];
  config.module.rules = rules;
 
  return config;
}

ManagerEntries

如果您正在編寫一個預設配置,該配置會載入您可能無法控制的第三方插件,但需要存取特定功能或額外配置,您可以使用 managerEntries API。例如:

//example-addon/preset.js
 
export const managerEntries = (entry = []) => {
  return [...entry, require.resolve('path-to-third-party-addon')];
};

PreviewAnnotations

如果您需要其他設定來為預設配置渲染故事,例如裝飾器參數,您可以使用 previewAnnotations API。例如,若要將裝飾器套用至所有故事,請建立一個包含裝飾器的預覽檔案,並使其可供預設配置使用,如下所示:

example-addon/src/preview.ts
import type { Renderer, ProjectAnnotations } from '@storybook/types';
import { PARAM_KEY } from './constants';
import { CustomDecorator } from './decorators';
 
const preview: ProjectAnnotations<Renderer> = {
  decorators: [CustomDecorator],
  globals: {
    [PARAM_KEY]: false,
  },
};
 
export default preview;

進階設定

預設配置 API 旨在具有彈性,並允許您根據特定需求自訂 Storybook,包括在不發布的情況下使用預設配置進行更進階的使用案例。 在這種情況下,您可以依賴私有預設配置。 這些私有預設配置包含用於開發目的而非最終使用者的配置選項。 .storybook/main.js|ts 檔案是這樣一個私有預設配置的範例,它使您能夠修改 Storybook 的行為和功能。

.storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
 
const config: StorybookConfig = {
  viteFinal: async (config, options) => {
    // Update config here
    return config;
  },
  webpackFinal: async (config, options) => {
    // Change webpack config
    return config;
  },
  babel: async (config, options) => {
    return config;
  },
};
 
export default config;

插件

對於插件消費者來說,managerEntries API 可能太過技術性,以致難以使用。為了讓向 Storybook 新增插件更容易,預設配置 API 提供了 addons API,它接受插件名稱的陣列,並會自動為您載入它們。 例如:

.storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
 
const config: StorybookConfig = {
  addons: [
    // Other Storybook addons
    '@storybook/addon-a11y',
  ],
};
 
export default config;

數值陣列支援參考其他應包含在管理員中的預設配置和插件。 Storybook 會自動偵測提供的數值是預設配置還是插件,並據此載入它。

進入點

進入點是註冊預覽進入點的地方。 此功能可用於建立一個 configure-storybook 預設配置,該配置會自動將所有 *.stories.js 檔案載入到 Storybook 中,從而消除了使用者重複複製貼上相同配置的需求。

UI 設定

Storybook 預設配置 API 還可以存取 UI 設定,包括預覽的 headbody HTML 元素,這些元素由 previewHeadpreviewBody API 設定。 這兩者都允許您以類似於使用 preview-head.htmlpreview-body.html 檔案的方式設定 Storybook。 這些方法接受字串並返回修改後的版本,將提供的內容注入 HTML 元素中。

.storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
 
const config: StorybookConfig = {
  previewBody: (body) => `
    ${body}
    ${
      process.env.ANALYTICS_ID ? '<script src="https://cdn.example.com/analytics.js"></script>' : ''
    }
  `,
};
 
export default config;

此外,如果您需要自訂管理員(即 Storybook 的搜尋、導覽、工具列和插件的渲染位置),您可以使用 managerHead 修改 UI,類似於您使用 manager-head.html 檔案的方式。 例如:

.storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
 
const config: StorybookConfig = {
  managerHead: (head) => `
    ${head}
    <link rel="icon" type="image/png" href="/logo192.png" sizes="192x192" />
  `,
};
 
export default config;

但是,如果您需要,您也可以自訂 Storybook 用於渲染 UI 的範本。 若要執行此操作,您可以使用 previewMainTemplate API 並提供以 ejs 檔案建立的自訂範本的參考。 有關如何執行此操作的範例,請參閱 Webpack 5 建置器使用的範本

疑難排解

Storybook 沒有載入我預設配置中的檔案

由於 Storybook 依賴 esbuild 而不是 Webpack 來建置 UI,因此依賴 managerWebpack API 來設定管理員或載入 CSS 或影像以外的其他檔案的預設配置將不再有效。 我們建議從您的預設配置中移除它,並調整您的設定以將任何其他檔案轉換為 JavaScript。

深入瞭解 Storybook 插件生態系統