建置時期的 Story 標題產生

一個 Babel 外掛程式,可在編譯時為 Storybook CSF stories 產生標題,通常基於 story 檔案的檔名。

在 Github 上檢視

babel-plugin-storybook-csf-title

Atlassian license PRs Welcome

一個 Babel 外掛程式,可在編譯時期Storybook CSF stories 產生標題,通常基於 story 檔案的檔名。

用法

這個外掛程式會根據 `toTitle` 函數的結果,為所有轉換後的檔案添加 `title` 屬性,而 `toTitle` 函數將作為外掛程式的選項提供。

假設 `toTitle: () => 'foo'`,有三種常見情境:

1️⃣ 檔案未提供預設匯出

在這個情境下,外掛程式會建立一個預設匯出 ` { title: "foo" }`。

例如:

import React from 'react';
import Component from './index';

export const Example = () => <Component />;

轉換成

import React from 'react';
import Component from './index';

export const Example = () => <Component />;

export default { title: 'foo' };

2️⃣ 檔案提供一個物件作為預設匯出

在這個情境下,外掛程式會將 `title: foo` 屬性添加到現有的匯出中。

例如:

import React from 'react';
import Component from './index';

export default { 
    something: 'something'
};

export const Example = () => <Component />;

轉換成

import React from 'react';
import Component from './index';

export default { 
    title: 'foo'
    something: 'something'
};

export const Example = () => <Component />;

如果現有的匯出已經包含 `title` 屬性,則會拋出錯誤。

3️⃣ 檔案提供一個非物件作為預設匯出

如果設定了 `renameDefaultExportsTo` 選項,外掛程式會假設預設匯出是一個元件,並將這個元件移至名為 `${renameDefaultExportsTo}` 的具名匯出。然後,它會建立一個預設匯出 ` { title: "foo" }`。

例如,假設 `renameDefaultExportsTo` 是 `"Default"`,

import React from 'react';
import Component from './index';

export default () => <Component />;

轉換成

import React from 'react';
import Component from './index';

export const Default = () => <Component />;

export default { 
    title: 'foo'
};

如果已經存在一個 `${renameDefaultExportsTo}` 匯出,則會拋出錯誤。

安裝

例如,透過 `yarn` 安裝外掛程式:

yarn add --dev babel-plugin-storybook-csf-title

在你的 Babel 設定中,將 `babel-plugin-storybook-csf-title` 作為一個外掛程式加入

plugins: [
    ['babel-plugin-storybook-csf-title', { toTitle: require('./your-to-title-function') }],
]

請注意,這個外掛程式實際上只對 story 檔案有意義。你會希望確保它只應用於這些檔案,例如像這樣:

/* add plugin to babel, however disable it by default */
plugins: [
    ['babel-plugin-storybook-csf-title', false], 
],
/* enable the plugin for all files that match your story name pattern */
overrides: [{ 
    include: /\/stories\.(ts|tsx)$/, 
    plugins: [
        ['babel-plugin-storybook-csf-title', { toTitle: require('./your-to-title-function') }]
    ]
}]

選項

這個外掛程式接受三個選項:`toTitle` (必要)、`ifTitleFound` (選填) 和 `renameDefaultExportsTo` (選填)

  • `toTitle` 是一個函數,對於每個被轉換的 story 檔案,它會接收 Babel 的 `state` 物件,並且必須以字串形式回傳 story 檔案的標題。大多數 `toTitle` 實作會根據 `state.filename` 做出決定。

  • `ifTitleFound` 是一個選填的字串值,可以設定為:

    • `'skip'` - 如果標題已在程式碼中手動指定,則跳過新增標題
    • `undefined` (或任何其他值) - 如果處理的檔案已經定義了標題,則引發錯誤
  • `renameDefaultExportsTo` 是一個選填的字串值,用於控制如上所述的情境 3。預設值為 `undefined`。

產生有意義的 story 名稱

在大多數情況下,story 名稱將基於 story 檔案的檔名產生。以下是一個可能的 `toTitle` 實作,適用於 `yarn workspaces` 風格的 monorepo 設定:

const path = require('path');
const pkgUp = require('pkg-up');

module.exports = (state) => {

    // find the closest package.json
    const packageJsonPath = pkgUp.sync({ cwd: state.filename });

    // read the package.json
    const packageJson = require(packageJsonPath);

    // get the path of the story file relative to the package root
    const { dir: packageJsonDir } = path.parse(packageJsonPath);
    const { dir: fileDir, name: fileName } = path.parse(path.relative(packageJsonDir, state.filename));

    const storybookPath = [
        // package name; "/" has meaning to storybook, hence replace a possible "/" by "|"
        packageJson.name.replace('/', '|'),

        // file dir
        ...fileDir.split(path.sep),
    ];

    // handle file names
    if (fileName === 'examples' || fileName === 'stories') {
        // nothing to do
    } else if (fileName.endsWith('.stories')) {
        storybookPath.push(fileName.slice(0, '.stories'.length + 1));
    } else if (fileName.endsWith('.examples')) {
        storybookPath.push(fileName.slice(0, '.examples'.length + 1));
    }

    return storybookPath.join('/');
}

貢獻

歡迎對 `babel-plugin-storybook-csf-title` 做出貢獻!請參閱 CONTRIBUTING.md 以了解詳細資訊。

授權條款

版權所有 (c) 2020 Atlassian 和其他貢獻者。採用 Apache 2.0 授權,請參閱 LICENSE 檔案。

With ❤️ from Atlassian

由以下人士製作
  • obweger
    obweger
適用於
    React
標籤