
开始使用 Storybook 和 Next.js
在四个简单步骤中将 Storybook 与 Next.js 集成

2023 年更新:Storybook 创建了与 NextJS 的零配置集成。了解如何使用它此处。
Next.js 是一个出色的框架,用于在 React 中构建高性能应用程序。但是,随着它变得越来越高级——具有诸如 next/image 等功能——它变得更难以与文档和测试环境(如 Storybook)集成。
我深入研究了如何使 Storybook 成为 Next.js 页面的最佳组件驱动 UI 环境。本文向您展示了如何通过四个简单的步骤完成同样的操作
- 📦 使用 Webpack 5 初始化新的 Storybook
- 📑 为 Next.js 页面创建 stories
- 🌎 在 preview.js 中导入共享的全局样式
- ⬇️ 取消优化 Next Image 以在 Stories 中使用
如果您喜欢视频,请跳转到结尾。我们在一个 27 分钟的代码演示 YouTube 视频中涵盖了所有这些步骤(以及更多内容)!
从 Next.js 应用程序开始
在我们开始之前,我们需要一个 Next.js 应用程序。本教程使用了 nextjs.org 上的出色入门指南。

我建议在一个新的应用程序中跟随操作,然后在现有应用程序中重复这些步骤。这是 Github 上的完整源代码,已针对 Next.js 12 更新。
使用 Webpack 5 初始化新的 Storybook
Storybook 有一个初始化程序,可以为我们完成繁重的工作:npx sb init
。此脚本检测您的项目类型并进行调整。但是我们也可以给它一些提示。
Next.js v11 及更高版本使用 Webpack 5。我们也可以在 Storybook 中使用 Webpack 5 以获得改进的集成和性能。为此,我们使用 builder
选项并运行此命令
npx sb init --builder webpack5
阅读更多关于 Storybook 的 Webpack 5 构建器的优势。
为完整的 Next.js 页面创建 stories
Next.js 和 Storybook 具有极其兼容的组件模型。Next.js 将组件用于页面,而 Storybook 将组件用于文档和测试。这使 Storybook 成为 Next.js 的出色组件驱动开发环境!
让我们为我们的 Next.js 主页创建一个 story。
- 创建一个新文件
/stories/pages/home.stories.jsx
- 导入
/pages/index.js
- 导出一个默认 story 对象,其中包含
title
和component
属性 - 为
Home
导出 story
// /stories/pages/home.stories.jsx
import Home from "../../pages/index";
export default {
title: "Pages/Home",
component: Home,
};
export const HomePage = () => <Home />
我们现在在 Storybook 中有了我们的主页。但它现在看起来并不怎么样。我们需要导入全局样式。

在 preview.js 中导入共享的全局样式表
大多数应用程序都有用于全局重置或字体样式的样式表,这些样式表是全局共享的。我们的 Next.js 教程应用程序将全局样式保存在 /styles/globals.css
中。
我们可以将全局样式表导入到我们的 home.stories.jsx
story 文件中。但是这样做需要在 story 文件中进行大量重复——这是一个非常容易出错的过程。最好为所有 story 导入一个全局样式表。
Storybook 将共享的 story 配置保存在 .storybook/preview.js
中。此文件控制所有 story 的渲染方式。可以使用模块导入来导入样式表
// .storybook/preview.js
import "../styles/globals.css";


我们做到了!除了图像损坏外,我们的 story 看起来像从 Next.js 提供的首页。
有关在 Storybook 中处理样式的更多方法,请查看我们的样式和 CSS 指南。
取消优化 stories 中的 Next.js Image
Next.js 和 Storybook 集成中最具挑战性的部分是处理图像。

Next.js v10 及更高版本包括 Next.js Image 组件。用他们的话来说,它是 “HTML <img>
元素的扩展,专为现代网络而发展。” 利用它可以优化文件大小、视觉稳定性和加载时间。它是 UI 工程的奇迹。
由于 Storybook 在 Next.js 框架集成的隔离中运行这些组件,我们需要通过两种重要方式对其进行配置
- 在 Storybook 中提供 Next.js
public
目录 - 在所有 story 中将
unoptimized
prop 添加到 Next.js Image 组件
1. 在 Storybook 中提供 public 目录
sb init
脚本在我们的 package.json
中创建了两个 Storybook 脚本。更新它们以提供 public
目录(Next.js 图像的存放位置)。我们为此使用的 CLI 选项是 -s
或 --static-dir
。
// package.json
"scripts": {
- "storybook": "start-storybook -p 6006",
- "build-storybook": "build-storybook"
+ "storybook": "start-storybook -p 6006 -s ./public",
+ "build-storybook": "build-storybook -s public"
}
在我们的CLI 选项文档中查找更多 CLI 选项。并了解更多关于通过 Storybook 提供静态文件的信息。
2. 在 Storybook 中为 Next.js Images 使用 unoptimized prop
在使用 Next.js Image 组件的任何地方,图像都从 /_next
前缀路径提供。我们想利用 Next Image 的 prop API 和属性,但我们不想要求 Next.js 开发服务器正在运行。我们可以使用 unoptimized
prop 完全做到这一点。但是我们如何在 Storybook 中做到这一点,而不是在 Next.js 中做到这一点 🤔
通过一些模块技巧,我们可以仅在 stories 中取消优化 Next.js Image。
// .storybook/preview.js
import * as NextImage from "next/image";
const OriginalNextImage = NextImage.default;
Object.defineProperty(NextImage, "default", {
configurable: true,
value: (props) => <OriginalNextImage {...props} unoptimized />,
});
此配置代码段修改了 Storybook 评估 next/image
模块的方式。在使用 Next.js Image 的默认导出的任何地方,都会应用 unoptimized
prop。
重启您的服务器并查看底部的 Vercel SVG。我们又可以工作了!
有关此技术的更多信息,请阅读如何在 Storybook 中使用 Next.js Image 组件——Jonas Schumacher 的一篇精彩文章。


下一步是什么?
您已经在这个 Next.js 和 Storybook 集成方面做得非常出色。但是我们还可以做更多的事情!
如果您渴望了解更多,请查看我的 YouTube 教程。我通过 Mock Service Worker 将这种集成更进一步,以用于 getServerSideProps
和 getStaticProps
。
您有哪些 Next.js🤝Storybook 技巧?
我们想听到您的声音!
关于使 Next.js 和 Storybook 成为超级开发环境,您有什么智慧可以分享?在此处评论或加入Storybook Discord 服务器!我们迫不及待想见到您 🤩
Next.js 12 来了!@chantastic 分享了四个快速提示,以充分利用 Next.js 和 Storybook!
— Storybook (@storybookjs) 2021 年 11 月 10 日
📦 使用 Webpack 5
📑 为 Next.js 页面编写 stories
🌎 在 preview.js 中导入共享的全局样式
⬇️ 集成 next/imagehttps://#/By5EfB4XnI pic.twitter.com/jED2qN0crP