Аддон Storybook для Next.js Image src

Недавно я столкнулся с проблемой, что изображение не отображается в компоненте image в storybook.

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

Сначала позвольте мне показать вам проблему. Я создал проект с помощью команды npx create-next-app и сделал компонент.

import Image from "next/image";
import styled from "@emotion/styled";

export const IconButton = ({
  src,
  children,
  width = 120,
  onClick,
  iconSize = 24,
}) => {
  return (
    <Button onClick={onClick} width={width}>
      <Image
        src={src}
        width={iconSize}
        height={iconSize}
        alt="icon of the button"
      />
      <Text>{children}</Text>
    </Button>
  );
};

const Button = styled.div`
  box-sizing: border-box;
  width: ${({ width }) => width}px;
  border-radius: 8px;
  height: 40px;
  padding: 8px;
  display: flex;
  alignitems: center;
  column-gap: 6px;
  background-color: #3498db;
  color: white;
  position: relative;

  &:hover {
    cursor: pointer;
    opacity: 0.7;
  }

  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
`;

const Text = styled.div`
  position: absolute;
  top: 0;
  bottom: 10%;
  left: 8px;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
`;
Вход в полноэкранный режим Выход из полноэкранного режима

Я скачал изображение (отсюда) и поместил его в публичную директорию.

Вот код индексной страницы и результат.

Пожалуйста, не обращайте внимания на дизайн

import { IconButton } from "../components/IconButton";

export default function Home() {
  return (
    <div>
      <h3>Example</h3>
      <IconButton src="/icons/home.png">Button</IconButton>
    </div>
  );
}
Войти в полноэкранный режим Выход из полноэкранного режима

Изображение отображается хорошо.

Давайте посмотрим на это в storybook. Я добавил строку в main.js для обслуживания статических файлов.

.storybook/main.js

module.exports = {
  stories: ["../components/**/*.stories.(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
  framework: "@storybook/react",
  staticDirs: ["../public"], // Here
};
Войти в полноэкранный режим Выход из полноэкранного режима

IconButton.stories.js

import { IconButton } from ".";

// eslint-disable-next-line import/no-anonymous-default-export
export default {
  title: "components/IconButton",
  component: IconButton,
  args: {
    width: 120,
    iconSize: 24,
    children: "Button",
  },
};

const Template = (args) => <IconButton {...args} />;

export const Home = Template.bind({});

Home.args = {
  src: "/icons/home.png",
};
Войти в полноэкранный режим Выход из полноэкранного режима

Изображение не появляется, верно?

src изображения указывает на /_next/image.

Теперь установите пакет storybook-addon-next.

npm install -D storybook-addon-next
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Затем добавьте addon в main.js.

module.exports = {
  stories: ["../components/**/*.stories.(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "storybook-addon-next", // Here
  ],
  framework: "@storybook/react",
  staticDirs: ["../public"],
};
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Перезапустите сборник рассказов.

…..?!

Возникает ошибка. Я столкнулся с ней во время написания этого сообщения, в то время как в своем проекте я не видел никаких ошибок.

Log

info @storybook/react v6.4.18
info
info => Loading presets
info => Serving static files from ./.public at /
(node:14304) DeprecationWarning: You have specified an invalid glob, we've attempted to fix it, please ensure that the glob you specify is valid. See: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#correct-globs-in-mainjs
(Use `node --trace-deprecation ...` to show where the warning was created)
info => Using implicit CSS loaders
info => Using default Webpack4 setup
ERR! WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
ERR!  - configuration.module.rules[12].type should be one of these:
ERR!    "javascript/auto" | "javascript/dynamic" | "javascript/esm" | "json" | "webassembly/experimental"
ERR!    -> Module type to use for the module
ERR!     at webpack (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_moduleswebpacklibwebpack.js:31:9)
ERR!     at Object.start (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_modules@storybookbuilder-webpack4distcjsindex.js:92:18)
ERR!     at async Promise.all (index 0)
ERR!     at async storybookDevServer (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_modules@storybookcore-serverdistcjsdev-server.js:126:28)
ERR!     at async buildDevStandalone (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_modules@storybookcore-serverdistcjsbuild-dev.js:115:31)
ERR!     at async buildDev (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_modules@storybookcore-serverdistcjsbuild-dev.js:161:5)
ERR!  WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
ERR!  - configuration.module.rules[12].type should be one of these:
ERR!    "javascript/auto" | "javascript/dynamic" | "javascript/esm" | "json" | "webassembly/experimental"
ERR!    -> Module type to use for the module
ERR!     at webpack (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_moduleswebpacklibwebpack.js:31:9)
ERR!     at Object.start (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_modules@storybookbuilder-webpack4distcjsindex.js:92:18)
ERR!     at async Promise.all (index 0)
ERR!     at async storybookDevServer (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_modules@storybookcore-serverdistcjsdev-server.js:126:28)
ERR!     at async buildDevStandalone (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_modules@storybookcore-serverdistcjsbuild-dev.js:115:31)
ERR!     at async buildDev (C:UsershskcoOneDrive바탕 화면devnext-storybook-image-testnode_modules@storybookcore-serverdistcjsbuild-dev.js:161:5)

WARN Broken build, fix the error above.
WARN You may need to refresh the browser.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! next-storybook-image-test@ storybook: `start-storybook -p 6006`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the next-storybook-image-test@ storybook script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.    

npm ERR! A complete log of this run can be found in:
npm ERR!     C:UsershskcoAppDataRoamingnpm-cache_logs2022-02-06T07_30_05_523Z-debug.log        
PS C:UsershskcoOneDrive바탕 화면devnext-storybook-image-test> 
Войти в полноэкранный режим Выйти из полноэкранного режима

Установленный пакет — storybook-addon-next^1.4.1. Я использовал v1.4.0 в своем проекте. Поэтому я переустановлю пакет с помощью npm install storybook-addon-next@1.4.0.

Наконец-то он работает! Я думаю, что-то не так с версией v1.4.1.

Надеюсь, этот пост будет полезен. Хорошего кодирования!


+Плюс

Я сообщил о проблеме storybook-addon-next на github и получил ответ от автора.
Это была проблема версии webpack.
Существует руководство по обновлению конструктора с webpack4 до webpack5.
После обновления storybook-addon-next@1.4.1 работает.

Если вы еще не начали свой проект, я бы рекомендовал вам инициализировать storybook с помощью npx sb init --builder webpack5.

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

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