Использование Storybook с Laravel Jetstream, Inertia и TailwindCSS

Вы хотите использовать Storybook в своем приложении Laravel с помощью Jetstream и Inertia?
Вы столкнулись с сопротивлением и сдались из-за Webpack?

Тогда этот пост может помочь вам. Это результат безуспешных поисков в интернете, чтобы заставить его работать. Надеюсь, вам понравится.

Предисловие

Прежде чем мы начнем, я хотел бы подчеркнуть, что мои знания в области frontend крайне ограничены. Как Джон Старк, я не знаю ничего, связанного с Webpack, и этот пост действительно призван помочь людям, пытающимся заставить Storybook работать с Jetstream, Inertia и Tailwind. Если вы заметите какие-то ужасные ошибки или что-то, что можно улучшить, пожалуйста, свяжитесь со мной через Twitter, и я с удовольствием обновлю этот пост.

Я написал этот пост, используя этот стек:

  • Laravel v9.2
  • Jetstream v2.7
  • Inertia v0.11
  • TailwindCSS v3
  • Storybook v6.4.21

Установите Storybook

npx sb init
Эта команда заглянет в ваш package.json зависимостей, чтобы определить, какие стартовые скрипты будет использовать Storybook. Она также установит некоторые зависимости, создаст конфигурацию по умолчанию и посыплет несколько историй по умолчанию для начала.

После его установки вы поймете, что запуск Storybook резко прекратится.

info @storybook/vue3 v6.4.21
info
info => Loading presets
info => Using implicit CSS loaders
info => Using prebuilt manager
info => Using default Webpack4 setup
ERR! TypeError: Cannot read property 'NormalModule' of undefined
Вход в полноэкранный режим Выход из полноэкранного режима

Используется неправильная версия Webpack. Давайте исправим это.

Используйте правильную версию Webpack

Начнем с добавления двух зависимостей, которые sb init пропустил при проверке нашего проекта.

В package.json я добавлю эти две devDependencies:

"@storybook/manager-webpack5": "^6.4.21",
"@storybook/builder-webpack5": "^6.4.21",
Вход в полноэкранный режим Выход из полноэкранного режима

Затем мы скажем Storybook использовать соответствующий построитель, добавив новый ключ в объект, объявленный в .storybook/main.js:

"core": {
    "builder": "webpack5",
  },
Войти в полноэкранный режим Выйти из полноэкранного режима

Давайте запустим npm install && npm run storybook и на этот раз, вы должны быть в состоянии проверить ваш совершенно новый Storybook!

Теперь давайте добавим историю для компонента Jetstream, скажем… кнопки.

Создание истории

Удалите истории по умолчанию, которые приходят при установке Storybook, и внутри stories/Button.stories.js давайте создадим историю для нашей кнопки:

import Button from '@/Jetstream/Button.vue';

export default {
  title: 'Jetstream/Button',
  component: Button,
};

const Template = (args) => ({
  components: { Button },
  setup() {
    return { args };
  },
  template: '<Button v-bind="args">Test Button</Button>',
});

export const MyButton = Template.bind({});
Вход в полноэкранный режим Выход из полноэкранного режима

Это не должно работать, потому что Storybook не может разрешить '@/Jetstream/Button.vue'.

Давайте исправим это.

Исправление псевдонимов

Внутри .storybook/main.js, сразу после ключа core, который мы объявили несколько шагов назад, мы добавим новый под названием webpackFinal и поместим туда псевдонимы, которые у нас есть в webpack.mix.js, вот так:

"webpackFinal": async (config) => {
      config.resolve = {
          ...config.resolve,
          alias: {
              ...config.resolve?.alias,
              '@': '../resources/js',
          }
      }
      return config;
  }
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь мы можем перезапустить наш Storybook с помощью npm run storybook и все должно быть хорошо!

Ну… не совсем. Где находится Tailwind?

Импорт Tailwind

Нам нужно сказать Storybook делать некоторые причудливые вещи с postcss, потому что… ну, я не знаю и, честно говоря, боюсь спрашивать. Но добавление этого правила к ключу webpackFinal, который мы добавили ранее, заставляет его работать. Это круто, да? Верно…?

config.module.rules.push({
          test: /.css$/,
          use: [
              {
                  loader: 'postcss-loader',
                  options: {
                      postcssOptions: {
                          implementation: 'postcss',
                          plugins: {
                              tailwindcss,
                          }
                      },
                  },
              },
          ],
          include: path.resolve(__dirname, '../'),
      });
      config.resolve = {
          ...config.resolve,
          alias: {
              ...config.resolve?.alias,
              '@': '../resources/js',
          }
      }
      return config;
  }
Войти в полноэкранный режим Выйти из полноэкранного режима

Я предполагаю, что это говорит webpack использовать postcss с плагином Tailwind’s для компиляции нашего css. Дайте мне знать, если у вас есть лучшее определение того, что здесь происходит, и я обновлю его.

Чтобы это работало, нам нужно импортировать некоторые вещи, поэтому в верхней части файла:

const path = require('path');
const tailwindcss = require('../tailwind.config');
Войти в полноэкранный режим Выйти из полноэкранного режима

И мы также импортируем app.css внутри .storybook/preview.js:

import '../resources/css/app.css';
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь мы снова перезапускаем Storybook и вуаля! Бим! Вы запустили свой story-nertia-wind.

Финальные файлы

Посмотрите на финальные файлы здесь

Бонус: Используйте Storybook на Ландо

Вы используете Ландо? Я написал небольшой пост о том, как заставить Storybook работать с Ландо.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *