Научит вас быстро создавать свой собственный сборник рассказов

React.js

Что такое сборник рассказов

Storybook — это инструмент, помогающий в разработке элементов управления пользовательского интерфейса. Создавайте независимые элементы управления через историю, чтобы каждая разработка элемента управления имела независимую среду разработки и отладки. Работа Storybook не зависит от проекта, и разработчикам не нужно беспокоиться о невозможности разработки элементов управления из-за проблем со средой разработки и зависимостями.

Фреймворки, поддерживаемые Storybook, охватывают основные фреймворки (React, Vue, Angular). Поскольку React используется в качестве стека технологий, в этой статье будет рассказано, как настроить среду Storybook для проектов, использующих React.

Установить

  1. Установить Storybook глобально
npm i -g storybook
  1. Выполните следующую команду, чтобы установить @storybook/react
npm i --save-dev @storybook/react
  1. в файле package.json
{
  "scripts": {
    "storybook": "start-storybook -p 9001 -c .storybook"
  }
}
  1. Создан в корневом каталоге проекта.storybookсодержание

  2. существует.storybookСоздано в каталогеconfig.jsдокумент

import { configure } from '@storybook/react';
import 'index.scss';

function loadStories() {
  require('./stories/userStory');
}

configure(loadStories, module);
  1. создать историю
    Хотя официальная рекомендация — создавать его в корневом каталоге проекта.storiesкаталог, но я предпочитаю.storybookсоздать каталогstoriesсодержание. Затем создайте разныеstoriesсодержание. Например, если есть пользовательский модуль, я создамstories/userStoryсодержание.
// stories/userStory/index.jsx
import React from 'react';
import { storiesOf } from '@storybook/react';
import BasicInfo from 'pages/clientDetail/components/BasicInfo';

storiesOf('用户信息', module)
  .add('基础信息', () => <BasicInfo />);

До сих пор, согласноStorybook React Guide, мы настроили простую среду сборника рассказов. На самом деле эта среда уже доступна.Конечно, если нужны какие-то дополнительные функции, например поддержкаlessа такжеscssПодождите, вам нужно настроить конфигурацию веб-пакета.

конфигурация сборника рассказов

1. Пользовательская конфигурация веб-пакета

Базовая конфигурация веб-пакета StorybookСодержит только следующее:

  • babel
    • ES2016+ Support
    • .babelrc support
  • Webpack
    • CSS Support
    • Image and Static File Support
    • JSON Loader

Иногда конфигурация веб-пакета по умолчанию не соответствует нашему проекту, поэтому нам нужно расширить конфигурацию веб-пакета.

Обычно я используюFull Control ModeВнесите изменения в конфигурацию веб-пакета. первый в.storybookдобавить в каталогwebpack.config.jsдокумент

const path = require('path');

module.exports = (storybookBaseConfig, configType) => {
  // 现在应该很多项目会使用`less`或者`scss`等css预处理技术。
  // 这里使用了postcss-loader进行处理
  storybookBaseConfig.module.rules.push({
    test: /\.s?css$/,
    use: ['style-loader', { loader: 'css-loader', options: { importLoaders: 1 } }, 'postcss-loader'],
    include: path.resolve(__dirname, '../'),
  });

  return storybookBaseConfig;
};

Примечание 1. Конфигурация по умолчанию недействительна.

Если используется пользовательская конфигурация, конфигурация по умолчанию будет недействительной, если ее не изменить.file-loader, когда сборник рассказов запущен, будет сообщено об ошибке, если есть элементы управления, которые ссылаются на файлы, такие как изображения.

  // 默认配置会失效,处理文件需要配置相应的file-loader
  storybookBaseConfig.module.rules.push({
    test: /\.(gif|png|jpe?g|eot|woff|ttf|pdf)$/,
    loader: 'file-loader',
  });

Примечание 2. Сохраните исходные изменения конфигурации.

использоватьFull Control ModeХотя режим может сильно изменитьwebpackКонфигурация, но следующая модификация конфигурации должна обратить внимание на расширение исходной конфигурации.

  • entry
  • output
  • first loader in the module.loaders (Babel loader for JS)
  • all existing plugins

Например, если вам нужно добавить загрузчик, вам нужно нажать загрузчик наmodule.rulesв массиве.

storybookBaseConfig.module.rules.push({
  test: /\.s?css$/,
  use: ['style-loader', { loader: 'css-loader', options: { importLoaders: 1 } }, 'postcss-loader'],
  include: path.resolve(__dirname, '../'),
});

2. storybook + Redux

На самом деле компоненты можно разделить на 2 типа, подробности в этой статье.статья

  • Класс презентации, без логики, только стиль презентации (презентационный)
  • Логический класс, ориентированный на логику и не включающий отображение стиля (Контейнер)

Показать класс

Использовать Storybook для элементов управления класса отображения очень просто, просто передайте свойства в соответствии с элементами управления класса отображения.

логический класс

В моем проекте это обычно класс после соединения с реакцией-редукцией. Операции внутри класса (такие как сетевые операции) выполняются через избыточность. Чтобы этот класс работал правильно, необходимы следующие операции. (примерыuserStory)

  1. Внесите react-redux в файл историиproviderа такжеstore.
import { provider } from 'react-redux';
import store from 'store';
  1. расширятьstory
    Добавьте декоратор в storiesOf, функция декоратора — оборачивать историю. Поэтому мы можем использовать характеристики декоратора, чтобы ввести хранилище в элемент управления.
// stories/userStory/index.jsx
import React from 'react';
import { provider } from 'react-redux'
import { storiesOf } from '@storybook/react';
// 引入store
import store from 'store';
import BasicInfo from 'pages/clientDetail/components/BasicInfo';

storiesOf('用户信息', module)
  .addDecorator(storyFn => <Provider store={store}>{storyFn()}</Provider>)
  .add('基础信息', () => <BasicInfo />);
  1. фиктивные данные
    команда построилаyapiПлатформа отвечает за создание фиктивных данных.

  2. whistle
    Поскольку фиктивные данные и сборник рассказов находятся в разных доменах, js вызывает фиктивные данные из разных доменов и должен быть прокси-сервером для пересылки запросов. Наша команда используетwhistle. свисток хорошая штука👍, рекомендую для взлома стен! ! !

    Ниже приведены правила переадресации, настроенные свистком.

//yourproject.com resCors://*
//localhost:8888 resCors://enable
//yourproject.com http://127.0.0.1:8888/  weinre://
# 9001是storybook的端口
# https://myapi.xxx.com 是yapi所在域名。
^localhost:9001/cgi-bin/** //myapi.xxx.com/mock/3876/cgi-bin/$1

addons

Что такое аддоны, собственно можно понять плагины, расширяющие функцию сборника рассказов.

Аддоны, которые я использую,

  • аддон-экшены Используется для отображения данных, полученных обработчиком события.
  • аддон-консоль вывод консоли (журнал, ошибка, предупреждение)
  • аддон-информация Это наиболее полезно.Если элемент управления заполняет протип, его можно отобразить прямо в сборнике рассказов.
  • аддон-окно просмотра Фактически, это функция панели инструментов устройства Chrome.

Уведомление
И addon-actions, и addon-viewport должны быть вaddons.jsзарегистрирован для использования.

упражняться

тренировочный кодекс

это мое.storybookСтруктура каталогов.

.
├── README.md
├── addons.js
├── config.js
├── stories
│   └── userStory
│       └── index.js
└── webpack.config.js
  • config.js
import { configure } from '@storybook/react';
import { setConsoleOptions } from '@storybook/addon-console';
import 'index.scss';

setConsoleOptions({
  panelExclude: [],
});

function loadStories() {
  require('./stories/userStory');
}

configure(loadStories, module);
  • webpack.config.js
const path = require('path');

module.exports = (storybookBaseConfig, configType) => {
  storybookBaseConfig.module.rules.push({
    test: /\.s?css$/,
    use: ['style-loader', { loader: 'css-loader', options: { importLoaders: 1 } }, 'postcss-loader'],
    include: path.resolve(__dirname, '../'),
  });

  storybookBaseConfig.module.rules.push({
    test: /\.(gif|png|jpe?g|eot|woff|ttf|pdf)$/,
    loader: 'file-loader',
  });

  // 设置别名
  storybookBaseConfig.resolve.alias = {
    antd: path.resolve(__dirname, '..', `node_modules/antd/dist/antd.min.js`),
    antdcss: path.resolve(__dirname, '..', 'node_modules/antd/dist/antd.min.css'),
    antdzhCN: path.resolve(__dirname, '..', 'node_modules/antd/lib/locale-provider/zh_CN.js'),
  };

  // 增加src为绝对路径
  storybookBaseConfig.resolve.modules.push(path.resolve(__dirname, '..', 'src'));

  // 使用source-map
  storybookBaseConfig.devtool = 'source-map';

  storybookBaseConfig.mode = 'development';

  return storybookBaseConfig;
};
  • addons.js
import '@storybook/addon-actions/register';
import '@storybook/addon-viewport/register';

Аддоны действий и области просмотра должны быть зарегистрированы в addons.js для нормального использования.

  • userStory
import React from 'react';
import { Provider } from 'react-redux';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { withConsole } from '@storybook/addon-console';
import BasicInfo from 'pages/clientDetail/components/BasicInfo';
import KeyActionItem from 'pages/clientDetail/components/KeyAction/KeyActionItem';
import { withInfo } from '@storybook/addon-info';
import store from 'pages/clientDetail/store';
import zhCN from 'antdzhCN';
import { LocaleProvider } from 'antd';
import 'antdcss';

// redux结合
storiesOf('用户信息', module)
  .addDecorator(withInfo)
  .addDecorator((storyFn, context) => withConsole()(storyFn)(context))
  .addDecorator(storyFn => <Provider store={store}>{storyFn()}</Provider>)
  .addDecorator(storyFn => <LocaleProvider locale={zhCN}>{storyFn()}</LocaleProvider>)
  .add('基础信息', () => <BasicInfo />, {
    info: {
      text: `
        用户基础信息展示,可进行上下翻页。
      `,
    },
  });

storiesOf('行为轨迹item', module)
  .addDecorator(withInfo)
  .addDecorator((storyFn, context) => withConsole()(storyFn)(context))
  .add('行为轨迹item--课程顾问', () => (
    <div style={{ display: 'flex', justifyContent: 'center', paddingTop: '30px' }}>
      <KeyActionItem
        time="2018-12-12 12:12:12"
        user="testUser"
        role="课程顾问"
        type="saler"
        data={[{ title: '备注', content: '备注测试'}]}
        id={1}
        onClickDelete={action('onClickDelete')}
        canDelete
      />
    </div>
  ))
  .add('行为轨迹item--客户', () => (
    <div style={{ display: 'flex', justifyContent: 'center', paddingTop: '30px' }}>
      <KeyActionItem
        time="2018-12-12 12:12:12"
        user="testUser"
        role="家长"
        type="client"
        data={[{ title: '购买记录', content: '测试购买记录'}]}
      />
    </div>
  ))
  .add('行为轨迹item--admin', () => (
    <div style={{ display: 'flex', justifyContent: 'center', paddingTop: '30px' }}>
      <KeyActionItem
        time="2018-12-12 12:12:12"
        user="admin"
        type="admin"
        data={[{ title: '购买记录', content: '测试购买记录'}]}
      />
    </div>
  ));

Практика скриншотов

Элемент управления addons-info может отображать информацию о свойствах компонента.

Эпилог

В этой статье я расскажу о самом основном использовании сборника рассказов.

  1. конфигурация сборника рассказов
  2. конфигурация веб-пакета
  3. Представлено редуксом
  4. Введение в дополнения

Метод использования, описанный в статье, очень прост, и я надеюсь, что больше людей смогут использовать сборник рассказов в Amway. Для получения дополнительной (высокой) практики сборника рассказов, пожалуйста, обратитесь сюдапрактика сборника рассказов

Ссылаться на

  1. Официальный сайт сборника рассказов
  2. StoryBook meets redux