该插件已被弃用 @Storybook/NextJS,这是Storybook官方插件,用于支持Storybook中的Next.js功能。它支持storybook-addon-next所做的一切!我什至努力与他们一起开发它,所以您应该掌握良好的手段。
有关如何迁移的详细信息,请咨询迁移文档。
?没有配置支持Next.js :厌倦了写作和调试WebPack配置? Next.js开箱即用的支持,此插件在故事书中成为可能
Next.js的图像组件(部分支持)
next.js路由
SASS/SCSS
CSS/SASS/SCSS模块
风格的JSX
Postcss
绝对进口
运行时配置
自定义WebPack配置
打字稿
.js扩展名而不是.mjs扩展名(即next.config.js而不是next.config.mjs )要运行任何示例,请首先通过在此存储库的根部运行
yarn build插件。
使用yarn安装storybook-addon-next :
yarn add --dev storybook-addon-next或npm :
npm install --save-dev storybook-addon-next // .storybook/main.js
module . exports = {
// other config ommited for brevity
addons : [
// ...
'storybook-addon-next'
// ...
]
}?就是这样!支持的功能应开箱即用。
有关支持功能如何在此附加组中起作用的更多详细信息,请参见文档。
如果某些事情无法正常工作,请随时开放一个问题。
如果需要,可以将此插件传递给添加配置的选项对象。
例如:
// .storybook/main.js
const path = require ( 'path' )
module . exports = {
// other config ommited for brevity
addons : [
// ...
{
name : 'storybook-addon-next' ,
options : {
nextConfigPath : path . resolve ( __dirname , '../next.config.js' )
}
}
// ...
]
}nextConfigPath : next.config.js的绝对路径众所周知,很难使用Storybook工作。此插件允许您使用Next.js的Image组件而无需配置!
因为图像组件具有由需要Next.js配置文件的选项配置的功能,例如图像优化。
如果您想看到更好的支持,请随时为Next.js的讨论做出贡献。
本地图像与此插件可以正常工作!请记住,此功能仅在Next.js V11中添加。
import Image from 'next/image'
import profilePic from '../public/me.png'
function Home ( ) {
return (
< >
< h1 > My Homepage </ h1 >
< Image
src = { profilePic }
alt = "Picture of the author"
// width={500} automatically provided
// height={500} automatically provided
// blurDataURL="../public/me.png" set to equal the image itself (for this addon)
// placeholder="blur" // Optional blur-up while loading
/>
< p > Welcome to my homepage! </ p >
</ >
)
} 远程图像也可以正常工作!
import Image from 'next/image'
export default function Home ( ) {
return (
< >
< h1 > My Homepage </ h1 >
< Image
src = "/me.png"
alt = "Picture of the author"
width = { 500 }
height = { 500 }
/>
< p > Welcome to my homepage! </ p >
</ >
)
} 所有Next.js Image S自动为您不利。
如果使用占位符=“ blur”,则使用的Blurdataurl是图像的SRC(从而有效地禁用了占位符)。
有关Sorybook的处理方式,请参阅此问题以获取有关Next.js Image S的更多讨论。
此插件尚未支持这种格式。如果您想看到的话,请随时打开一个问题。
该解决方案在Storybook-Addon-next-Router上大量基于,非常感谢lifeiscontent提供了一个很好的解决方案,该解决方案可以使该解决方案可以使用。
Next.js的路由器自动为您固定,因此当路由器与路由器进行交互时,如果您拥有Actions Addon,则将其所有交互都自动记录到Storybook Action Tab。
可以通过将nextRouter属性添加到故事参数中来完成每个层次的覆盖。插件将浅薄地合并您在这里放入路由器的任何东西。
import SomeComponentThatUsesTheRouter from "./SomeComponentThatUsesTheRouter" ;
export default {
title : "My Story" ,
} ;
// if you have the actions addon
// you can click the links and see the route change events there
export const Example = ( ) => < SomeComponentThatUsesTheRouter /> ;
Example . parameters : {
nextRouter : {
path : "/profile/[id]" ,
asPath : "/profile/ryanclementshax" ,
query : {
id : "ryanclementshax"
}
}
}请参阅此示例以获取参考。
可以在preview.js中设置全局默认值,并将与默认路由器合并。
export const parameters = {
nextRouter : {
path : '/some-default-path' ,
asPath : '/some-default-path' ,
query : { }
}
}请参阅此示例以获取参考。
固定路由器上的默认值如下(有关全球群体的工作方式,请参见Globals)
const defaultRouter = {
locale : context ?. globals ?. locale ,
route : '/' ,
pathname : '/' ,
query : { } ,
asPath : '/' ,
push ( ... args : unknown [ ] ) {
action ( 'nextRouter.push' ) ( ... args )
return Promise . resolve ( true )
} ,
replace ( ... args : unknown [ ] ) {
action ( 'nextRouter.replace' ) ( ... args )
return Promise . resolve ( true )
} ,
reload ( ... args : unknown [ ] ) {
action ( 'nextRouter.reload' ) ( ... args )
} ,
back ( ... args : unknown [ ] ) {
action ( 'nextRouter.back' ) ( ... args )
} ,
prefetch ( ... args : unknown [ ] ) {
action ( 'nextRouter.prefetch' ) ( ... args )
return Promise . resolve ( )
} ,
beforePopState ( ... args : unknown [ ] ) {
action ( 'nextRouter.beforePopState' ) ( ... args )
} ,
events : {
on ( ... args : unknown [ ] ) {
action ( 'nextRouter.events.on' ) ( ... args )
} ,
off ( ... args : unknown [ ] ) {
action ( 'nextRouter.events.off' ) ( ... args )
} ,
emit ( ... args : unknown [ ] ) {
action ( 'nextRouter.events.emit' ) ( ... args )
}
} ,
isFallback : false
} 如果您覆盖功能,则会将失去“自动操作”选项卡集成,因此必须自己构建它。
export const parameters = {
nextRouter : {
push ( ) {
// we lose the default implementation that logs the action into the action tab
}
}
}自己做这个看起来像这样的东西(请确保安装@storybook/addon-actions软件包):
import { action } from '@storybook/addon-actions'
export const parameters = {
nextRouter : {
push ( ... args ) {
// custom logic can go here
// this logs to the actions tab
action ( 'nextRouter.push' ) ( ... args )
// return whatever you want here
return Promise . resolve ( true )
}
}
}支持全局SASS/SCSS样式表,也没有任何其他配置。只需将它们导入Preview.js
import '../styles/globals.scss'这将在您的next.config.js文件中自动包含您的任何自定义SASS配置。
目前,仅支持Next.js配置的
.js扩展名,而不是.mjs。有关更多详细信息,请参见Next.config.js。
const path = require ( 'path' )
module . exports = {
// any options here are included in sass compilation for your stories
sassOptions : {
includePaths : [ path . join ( __dirname , 'styles' ) ]
}
}Next.js支持CSS模块开箱即用,因此此插件也支持它。
// this import works just fine in Storybook now
import styles from './Button.module.css'
// sass/scss is also supported
// import styles from './Button.module.scss'
// import styles from './Button.module.sass'
export function Button ( ) {
return (
< button type = "button" className = { styles . error } >
Destroy
</ button >
)
}next.js中的JS解决方案中的内置CSS是样式的JSX,此插件也支持开箱即用的零配置。
// This works just fine in Storybook with this addon
function HelloWorld ( ) {
return (
< div >
Hello world
< p > scoped! </ p >
< style jsx > { `
p {
color: blue;
}
div {
background: red;
}
@media (max-width: 600px) {
div {
background: blue;
}
}
` } </ style >
< style global jsx > { `
body {
background: black;
}
` } </ style >
</ div >
)
}
export default HelloWorld您也可以使用自己的babel配置。这是您如何自定义样式JSX的一个示例。
// .babelrc or whatever config file you use
{
"presets" : [
[
" next/babel " ,
{
"styled-jsx" : {
"plugins" : [ " @styled-jsx/plugin-sass " ]
}
}
]
]
}如果您使用MonorePo,则可能需要将Babel配置添加到故事书项目中。只需将Babel配置添加到您的故事书项目中,并使用以下内容开始。
{
"presets" : [ " next/babel " ]
}Next.js可让您自定义PostCSS配置。因此,此插件将自动为您处理您的PostCSS配置。
这允许零配置parwindcss之类的很酷的东西!请参阅with-tailwindcss示例以获取参考!它是Next.js的tailwindcss示例,该示例与故事书和此插件建立。
再见../ !从根目录工作中的绝对导入此插件可以很好地进口。
// All good!
import Button from 'components/button'
// Also good!
import styles from 'styles/HomePage.module.css'
export default function HomePage ( ) {
return (
< >
< h1 className = { styles . title } > Hello World </ h1 >
< Button />
</ >
)
} // preview.js
// Also ok in preview.js!
import 'styles/globals.scss'
// ...next.js允许运行时配置,该配置使您可以导入方便的getConfig函数,以在运行时在next.config.js文件中获取某些配置。
在使用此插件的故事书的上下文中,您可以期待Next.js的运行时配置功能可以正常工作。
注意,由于Storybook没有渲染您的组件,因此您的组件只会看到他们通常在客户端看到的内容(即他们不会看到serverRuntimeConfig ,但会看到publicRuntimeConfig )。
例如,请考虑以下Next.js配置:
// next.config.js
module . exports = {
serverRuntimeConfig : {
mySecret : 'secret' ,
secondSecret : process . env . SECOND_SECRET // Pass through env variables
} ,
publicRuntimeConfig : {
staticFolder : '/static'
}
}在Storybook中调用时, getConfig的呼叫将返回以下对象:
{
"serverRuntimeConfig" : {},
"publicRuntimeConfig" : {
"staticFolder" : " /static "
}
}next.js提供了很多免费的东西,例如SASS支持,但有时我们将自定义的WebPack配置修改添加到Next.js。该插件负责您要添加的大多数WebPack修改。如果Next.js支持开箱即用的功能,那么此插件将使该功能在Storybook中开箱即用。如果Next.js不支持开箱即用的东西,但是可以易于配置,那么此插件将为故事书做同样的事情。如果您发现仍然需要配置WebPack以获取next.js功能以在添加此插件后在故事书中工作的内容,这可能是一个错误,请随时打开问题。
根据Storybook的文档,应在.Storybook/Main.js中进行故事书所需的任何WebPack修改。
注意:并非所有的WebPack修改都是在next.config.js和.storybook/main.js之间复制/粘贴的。建议您对如何正确修改Storybook的WebPack配置以及WebPack的工作方式进行重新搜索。
请随时为帮助社区提供榜样。
以下是如何使用此插件将SVGR支持添加到Storybook中的示例。完整的示例可以在这里找到。
// .storybook/main.js
module . exports = {
// other config omitted for brevity
webpackFinal : async config => {
// this modifies the existing image rule to exclude .svg files
// since we want to handle those files with @svgr/webpack
const imageRule = config . module . rules . find ( rule => rule . test . test ( '.svg' ) )
imageRule . exclude = / .svg$ /
// configure .svg files to be loaded with @svgr/webpack
config . module . rules . push ( {
test : / .svg$ / ,
use : [ '@svgr/webpack' ]
} )
return config
}
}Storybook处理大多数打字稿配置,但是此插件为Next.js对绝对导入和模块路径别名的支持增加了支持。简而言之,它考虑了您的tsconfig.json的baseurl和路径。因此,像下面的tsconfig.json可以从开箱即用。
{
"compilerOptions" : {
"baseUrl" : " . " ,
"paths" : {
"@/components/*" : [ " components/* " ]
}
}
}目前,此插件支持的唯一支持的next.js是config的commonjs版本(即next.config.js )。这主要是因为我尚未弄清楚如何从故事书插件中需要.mjs文件(据我所知,该文件与CommonJS模块绑定在一起)。如果您能够提供帮助,那么如果您可以为此提供支持,我会很喜欢它,如果可能的支持甚至可以为.mjs版本提供支持。
如果您使用的是纱线V2或V3,则可能会遇到故事书无法解析style-loader或css-loader问题。例如,您可能会遇到错误:
Module not found: Error: Can't resolve 'css-loader'
Module not found: Error: Can't resolve 'style-loader'
这是因为这些版本的纱线具有不同的包装分辨率规则与纱线V1.x。如果是您的情况,只需直接安装软件包。
确保您在正常开发中使用下一个图像时,以相同的方式处理图像导入。
在storybook-addon-next之前,Image导入了图像的原始路径(例如'static/media/stories/assets/plugin.svg' )。使用storybook-addon-next图像导入工作“ next.js方式”,这意味着我们现在在导入图像时会得到一个对象。例如:
{
"src" : " static/media/stories/assets/plugin.svg " ,
"height" : 48 ,
"width" : 48 ,
"blurDataURL" : " static/media/stories/assets/plugin.svg "
}因此,如果故事书中的某些内容未正确显示图像,请确保您期望将对象从导入而不是资产路径返回。
有关Next.js如何处理静态图像导入的更多详细信息,请参见本地图像。
现在使用next.config.mjs不支持此插件。有关更多详细信息,请参见Next.config.js。现在,您需要使用.js扩展名。请随时提供讨论,以获得支持。
如果您使用纱线V2或V3,则可能会得到这个。有关更多详细信息,请参见YARN V2和V3用户的注释。
我愿意讨论。随时开放一个问题。
这个文档不足您吗?
很困惑吗?
是...我敢说...不准确吗?
如果以上任何一个描述了您对本文档的感觉。随时开放一个问题。