mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-02 05:03:44 +08:00
Merge remote-tracking branch 'origin/next' into valentin/remove-preact-webpack-support
This commit is contained in:
commit
4740a15e69
25
MIGRATION.md
25
MIGRATION.md
@ -30,6 +30,7 @@
|
||||
- [Angular = Require v18 and up](#angular--require-v18-and-up)
|
||||
- [Next.js = Require v14 and up](#nextjs--require-v14-and-up)
|
||||
- [Preact = Dropped webpack5 builder support](#preact--dropped-webpack5-builder-support)
|
||||
- [Next.js = Vite builder stabilized](#nextjs--vite-builder-stabilized)
|
||||
- [From version 8.5.x to 8.6.x](#from-version-85x-to-86x)
|
||||
- [Angular: Support experimental zoneless support](#angular-support-experimental-zoneless-support)
|
||||
- [Framework-specific Vite plugins have to be explicitly added](#framework-specific-vite-plugins-have-to-be-explicitly-added)
|
||||
@ -843,6 +844,30 @@ export default {
|
||||
};
|
||||
```
|
||||
|
||||
#### Next.js = Vite builder stabilized
|
||||
|
||||
The experimental Next.js Vite builder (`@storybook/experimental-nextjs-vite`) has been stabilized and renamed to `@storybook/nextjs-vite`. If you were using the experimental package, you should update your dependencies to use the new stable package name.
|
||||
|
||||
```diff
|
||||
{
|
||||
"dependencies": {
|
||||
- "@storybook/experimental-nextjs-vite": "^x.x.x"
|
||||
+ "@storybook/nextjs-vite": "^9.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Also update your `.storybook/main.<js|ts>` file accordingly:
|
||||
|
||||
```diff
|
||||
export default {
|
||||
addons: [
|
||||
- "@storybook/experimental-nextjs-vite",
|
||||
+ "@storybook/nextjs-vite"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## From version 8.5.x to 8.6.x
|
||||
|
||||
### Angular: Support experimental zoneless support
|
||||
|
@ -18,7 +18,7 @@ export const COVERAGE_DIRECTORY = 'coverage';
|
||||
|
||||
export const SUPPORTED_FRAMEWORKS = [
|
||||
'@storybook/nextjs',
|
||||
'@storybook/experimental-nextjs-vite',
|
||||
'@storybook/nextjs-vite',
|
||||
'@storybook/sveltekit',
|
||||
];
|
||||
|
||||
|
@ -72,12 +72,12 @@ export default async function postInstall(options: PostinstallOptions) {
|
||||
if (info.frameworkPackageName === '@storybook/nextjs' && !hasCustomWebpackConfig) {
|
||||
const out =
|
||||
options.yes || !isInteractive
|
||||
? { migrateToExperimentalNextjsVite: !!options.yes }
|
||||
? { migrateToNextjsVite: !!options.yes }
|
||||
: await prompts({
|
||||
type: 'confirm',
|
||||
name: 'migrateToExperimentalNextjsVite',
|
||||
name: 'migrateToNextjsVite',
|
||||
message: dedent`
|
||||
The addon requires the use of @storybook/experimental-nextjs-vite to work with Next.js.
|
||||
The addon requires the use of @storybook/nextjs-vite to work with Next.js.
|
||||
https://storybook.js.org/docs/writing-tests/test-addon#install-and-set-up
|
||||
|
||||
Do you want to migrate?
|
||||
@ -85,9 +85,9 @@ export default async function postInstall(options: PostinstallOptions) {
|
||||
initial: true,
|
||||
});
|
||||
|
||||
if (out.migrateToExperimentalNextjsVite) {
|
||||
if (out.migrateToNextjsVite) {
|
||||
await packageManager.addDependencies({ installAsDevDependencies: true }, [
|
||||
`@storybook/experimental-nextjs-vite@${versions['@storybook/experimental-nextjs-vite']}`,
|
||||
`@storybook/nextjs-vite@${versions['@storybook/nextjs-vite']}`,
|
||||
]);
|
||||
|
||||
await packageManager.removeDependencies({}, ['@storybook/nextjs']);
|
||||
@ -96,21 +96,21 @@ export default async function postInstall(options: PostinstallOptions) {
|
||||
traverse(config._ast, {
|
||||
StringLiteral(path) {
|
||||
if (path.node.value === '@storybook/nextjs') {
|
||||
path.node.value = '@storybook/experimental-nextjs-vite';
|
||||
path.node.value = '@storybook/nextjs-vite';
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
await writeConfig(config, mainJsPath);
|
||||
|
||||
info.frameworkPackageName = '@storybook/experimental-nextjs-vite';
|
||||
info.frameworkPackageName = '@storybook/nextjs-vite';
|
||||
info.builderPackageName = '@storybook/builder-vite';
|
||||
}
|
||||
}
|
||||
|
||||
const annotationsImport = SUPPORTED_FRAMEWORKS.includes(info.frameworkPackageName)
|
||||
? info.frameworkPackageName === '@storybook/nextjs'
|
||||
? '@storybook/experimental-nextjs-vite'
|
||||
? '@storybook/nextjs-vite'
|
||||
: info.frameworkPackageName
|
||||
: info.rendererPackageName && SUPPORTED_RENDERERS.includes(info.rendererPackageName)
|
||||
? info.rendererPackageName
|
||||
@ -215,18 +215,16 @@ export default async function postInstall(options: PostinstallOptions) {
|
||||
dedent`
|
||||
It looks like you're using Next.js.
|
||||
|
||||
Adding ${picocolors.bold(colors.pink(`@storybook/experimental-nextjs-vite/vite-plugin`))} so you can use it with Vitest.
|
||||
Adding ${picocolors.bold(colors.pink(`@storybook/nextjs-vite/vite-plugin`))} so you can use it with Vitest.
|
||||
|
||||
More info about the plugin at ${picocolors.cyan(`https://github.com/storybookjs/vite-plugin-storybook-nextjs`)}
|
||||
`
|
||||
);
|
||||
try {
|
||||
const storybookVersion = await packageManager.getInstalledVersion('storybook');
|
||||
dependencies.push(`@storybook/experimental-nextjs-vite@^${storybookVersion}`);
|
||||
dependencies.push(`@storybook/nextjs-vite@^${storybookVersion}`);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'Failed to install @storybook/experimental-nextjs-vite. Please install it manually'
|
||||
);
|
||||
console.error('Failed to install @storybook/nextjs-vite. Please install it manually');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ export const experimental_serverChannel = async (channel: Channel, options: Opti
|
||||
if (!builderName?.includes('vite')) {
|
||||
if (framework.includes('nextjs')) {
|
||||
log(dedent`
|
||||
You're using ${framework}, which is a Webpack-based builder. In order to use Storybook Test, with your project, you need to use '@storybook/experimental-nextjs-vite', a high performance Vite-based equivalent.
|
||||
You're using ${framework}, which is a Webpack-based builder. In order to use Storybook Test, with your project, you need to use '@storybook/nextjs-vite', a high performance Vite-based equivalent.
|
||||
|
||||
Information on how to upgrade here: ${picocolors.yellow('https://storybook.js.org/docs/get-started/frameworks/nextjs#with-vite')}\n
|
||||
`);
|
||||
|
@ -30,7 +30,7 @@ const INCLUDE_CANDIDATES = [
|
||||
'@storybook/addon-themes',
|
||||
'@storybook/addon-themes/preview',
|
||||
'@storybook/blocks',
|
||||
'@storybook/experimental-nextjs-vite/dist/preview.mjs',
|
||||
'@storybook/nextjs-vite/dist/preview.mjs',
|
||||
'@storybook/html',
|
||||
'@storybook/html/dist/entry-preview-docs.mjs',
|
||||
'@storybook/html/dist/entry-preview.mjs',
|
||||
|
@ -152,7 +152,7 @@ export const frameworkToDefaultBuilder: Record<
|
||||
'html-webpack5': CoreBuilder.Webpack5,
|
||||
nextjs: CoreBuilder.Webpack5,
|
||||
nuxt: CoreBuilder.Vite,
|
||||
'experimental-nextjs-vite': CoreBuilder.Vite,
|
||||
'nextjs-vite': CoreBuilder.Vite,
|
||||
'preact-vite': CoreBuilder.Vite,
|
||||
qwik: CoreBuilder.Vite,
|
||||
'react-native-web-vite': CoreBuilder.Vite,
|
||||
|
@ -11,7 +11,7 @@ export const frameworkToRenderer: Record<
|
||||
'html-vite': 'html',
|
||||
'html-webpack5': 'html',
|
||||
nextjs: 'react',
|
||||
'experimental-nextjs-vite': 'react',
|
||||
'nextjs-vite': 'react',
|
||||
'preact-vite': 'preact',
|
||||
qwik: 'qwik',
|
||||
'react-vite': 'react',
|
||||
|
@ -40,7 +40,7 @@ export const frameworkPackages: Record<string, SupportedFrameworks> = {
|
||||
'@storybook/svelte-webpack5': 'svelte-webpack5',
|
||||
'@storybook/sveltekit': 'sveltekit',
|
||||
'@storybook/vue3-vite': 'vue3-vite',
|
||||
'@storybook/experimental-nextjs-vite': 'experimental-nextjs-vite',
|
||||
'@storybook/nextjs-vite': 'nextjs-vite',
|
||||
'@storybook/react-native-web-vite': 'react-native-web-vite',
|
||||
'@storybook/vue3-webpack5': 'vue3-webpack5',
|
||||
'@storybook/web-components-vite': 'web-components-vite',
|
||||
|
@ -19,10 +19,10 @@ export default {
|
||||
storybook: '9.0.0-alpha.11',
|
||||
'@storybook/angular': '9.0.0-alpha.11',
|
||||
'@storybook/ember': '9.0.0-alpha.11',
|
||||
'@storybook/experimental-nextjs-vite': '9.0.0-alpha.11',
|
||||
'@storybook/html-vite': '9.0.0-alpha.11',
|
||||
'@storybook/html-webpack5': '9.0.0-alpha.11',
|
||||
'@storybook/nextjs': '9.0.0-alpha.11',
|
||||
'@storybook/nextjs-vite': '9.0.0-alpha.11',
|
||||
'@storybook/preact-vite': '9.0.0-alpha.11',
|
||||
'@storybook/react-native-web-vite': '9.0.0-alpha.11',
|
||||
'@storybook/react-vite': '9.0.0-alpha.11',
|
||||
|
@ -12,7 +12,7 @@ globalPackages.forEach((key) => {
|
||||
|
||||
globalThis.sendTelemetryError = (error) => {
|
||||
if (!shouldSkipError(error)) {
|
||||
const channel = global.__STORYBOOK_ADDONS_CHANNEL__;
|
||||
const channel = globalThis.__STORYBOOK_ADDONS_CHANNEL__;
|
||||
channel.emit(TELEMETRY_ERROR, prepareForTelemetry(error));
|
||||
}
|
||||
};
|
||||
@ -20,9 +20,9 @@ globalThis.sendTelemetryError = (error) => {
|
||||
// handle all uncaught errors at the root of the application and log to telemetry
|
||||
globalThis.addEventListener('error', (args) => {
|
||||
const error = args.error || args;
|
||||
global.sendTelemetryError(error);
|
||||
globalThis.sendTelemetryError(error);
|
||||
});
|
||||
|
||||
globalThis.addEventListener('unhandledrejection', ({ reason }) => {
|
||||
global.sendTelemetryError(reason);
|
||||
globalThis.sendTelemetryError(reason);
|
||||
});
|
||||
|
@ -2,10 +2,10 @@
|
||||
export type SupportedFrameworks =
|
||||
| 'angular'
|
||||
| 'ember'
|
||||
| 'experimental-nextjs-vite'
|
||||
| 'html-vite'
|
||||
| 'html-webpack5'
|
||||
| 'nextjs'
|
||||
| 'nextjs-vite'
|
||||
| 'preact-vite'
|
||||
| 'react-native-web-vite'
|
||||
| 'react-vite'
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@storybook/experimental-nextjs-vite",
|
||||
"name": "@storybook/nextjs-vite",
|
||||
"version": "9.0.0-alpha.11",
|
||||
"description": "Storybook for Next.js and Vite",
|
||||
"keywords": [
|
||||
@ -7,7 +7,7 @@
|
||||
"nextjs",
|
||||
"vite"
|
||||
],
|
||||
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/experimental-nextjs-vite",
|
||||
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/nextjs-vite",
|
||||
"bugs": {
|
||||
"url": "https://github.com/storybookjs/storybook/issues"
|
||||
},
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "experimental-nextjs-vite",
|
||||
"name": "nextjs-vite",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "library",
|
||||
"targets": {
|
@ -3,7 +3,7 @@
|
||||
// is the only way to achieve it actually being a singleton
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore we must ignore types here as during compilation they are not generated yet
|
||||
import { headers } from '@storybook/experimental-nextjs-vite/headers.mock';
|
||||
import { headers } from '@storybook/nextjs-vite/headers.mock';
|
||||
|
||||
import { RequestCookies } from 'next/dist/compiled/@edge-runtime/cookies';
|
||||
import { fn } from 'storybook/test';
|
@ -15,7 +15,7 @@ export * from './types';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
declare module '@storybook/experimental-nextjs-vite/vite-plugin' {
|
||||
declare module '@storybook/nextjs-vite/vite-plugin' {
|
||||
export const storybookNextJsPlugin: typeof vitePluginStorybookNextJs;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import * as nextJsAnnotations from './preview';
|
||||
*
|
||||
* ```jsx
|
||||
* // setup-file.js
|
||||
* import { setProjectAnnotations } from '@storybook/experimental-nextjs-vite';
|
||||
* import { setProjectAnnotations } from '@storybook/nextjs-vite';
|
||||
* import projectAnnotations from './.storybook/preview';
|
||||
*
|
||||
* setProjectAnnotations(projectAnnotations);
|
||||
@ -70,7 +70,7 @@ const INTERNAL_DEFAULT_PROJECT_ANNOTATIONS: ProjectAnnotations<ReactRenderer> =
|
||||
*
|
||||
* ```jsx
|
||||
* import { render } from '@testing-library/react';
|
||||
* import { composeStory } from '@storybook/experimental-nextjs-vite';
|
||||
* import { composeStory } from '@storybook/nextjs-vite';
|
||||
* import Meta, { Primary as PrimaryStory } from './Button.stories';
|
||||
*
|
||||
* const Primary = composeStory(PrimaryStory, Meta);
|
||||
@ -114,7 +114,7 @@ export function composeStory<TArgs extends Args = Args>(
|
||||
*
|
||||
* ```jsx
|
||||
* import { render } from '@testing-library/react';
|
||||
* import { composeStories } from '@storybook/experimental-nextjs-vite';
|
||||
* import { composeStories } from '@storybook/nextjs-vite';
|
||||
* import * as stories from './Button.stories';
|
||||
*
|
||||
* const { Primary, Secondary } = composeStories(stories);
|
@ -29,7 +29,7 @@ export const core: PresetProperty<'core'> = async (config, options) => {
|
||||
};
|
||||
|
||||
export const previewAnnotations: PresetProperty<'previewAnnotations'> = (entry = []) => {
|
||||
const nextDir = dirname(require.resolve('@storybook/experimental-nextjs-vite/package.json'));
|
||||
const nextDir = dirname(require.resolve('@storybook/nextjs-vite/package.json'));
|
||||
const result = [...entry, join(nextDir, 'dist/preview.mjs')];
|
||||
return result;
|
||||
};
|
@ -6,10 +6,10 @@ import type { ReactRenderer, StoryFn } from '@storybook/react';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore we must ignore types here as during compilation they are not generated yet
|
||||
import { createNavigation } from '@storybook/experimental-nextjs-vite/navigation.mock';
|
||||
import { createNavigation } from '@storybook/nextjs-vite/navigation.mock';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore we must ignore types here as during compilation they are not generated yet
|
||||
import { createRouter } from '@storybook/experimental-nextjs-vite/router.mock';
|
||||
import { createRouter } from '@storybook/nextjs-vite/router.mock';
|
||||
|
||||
import { isNextRouterError } from 'next/dist/client/components/is-next-router-error';
|
||||
|
@ -5,7 +5,7 @@ import React, { useMemo } from 'react';
|
||||
// is the only way to achieve it actually being a singleton
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore we must ignore types here as during compilation they are not generated yet
|
||||
import { getRouter } from '@storybook/experimental-nextjs-vite/navigation.mock';
|
||||
import { getRouter } from '@storybook/nextjs-vite/navigation.mock';
|
||||
|
||||
import type { FlightRouterState } from 'next/dist/server/app-render/types';
|
||||
import {
|
@ -6,7 +6,7 @@ import React from 'react';
|
||||
// is the only way to achieve it actually being a singleton
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore we must ignore types here as during compilation they are not generated yet
|
||||
import { getRouter } from '@storybook/experimental-nextjs-vite/router.mock';
|
||||
import { getRouter } from '@storybook/nextjs-vite/router.mock';
|
||||
|
||||
import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime';
|
||||
|
@ -5,7 +5,7 @@ import type { StorybookConfig as StorybookConfigReactVite } from '@storybook/rea
|
||||
|
||||
import type { NextRouter } from 'next/router';
|
||||
|
||||
type FrameworkName = CompatibleString<'@storybook/experimental-nextjs-vite'>;
|
||||
type FrameworkName = CompatibleString<'@storybook/nextjs-vite'>;
|
||||
type BuilderName = CompatibleString<'@storybook/builder-vite'>;
|
||||
|
||||
export type FrameworkOptions = {
|
@ -1,4 +1,4 @@
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import { fn } from 'storybook/test';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import { fn } from 'storybook/test';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import { expect, userEvent, within } from 'storybook/test';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Suspense } from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import Font from './Font';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import { type ImageProps, getImageProps } from 'next/image';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta } from '@storybook/experimental-nextjs-vite';
|
||||
import type { StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta } from '@storybook/nextjs-vite';
|
||||
import type { StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import Head from 'next/head';
|
||||
import { expect, waitFor } from 'storybook/test';
|
@ -1,6 +1,6 @@
|
||||
import React, { useRef, useState } from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import Image from 'next/image';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import Image from 'next/legacy/image';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import Link from 'next/link';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import { getRouter } from '@storybook/experimental-nextjs-vite/navigation.mock';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
import { getRouter } from '@storybook/nextjs-vite/navigation.mock';
|
||||
|
||||
import {
|
||||
useParams,
|
@ -1,6 +1,6 @@
|
||||
import type { Meta } from '@storybook/experimental-nextjs-vite';
|
||||
import type { StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import { cookies, headers } from '@storybook/experimental-nextjs-vite/headers.mock';
|
||||
import type { Meta } from '@storybook/nextjs-vite';
|
||||
import type { StoryObj } from '@storybook/nextjs-vite';
|
||||
import { cookies, headers } from '@storybook/nextjs-vite/headers.mock';
|
||||
|
||||
import { expect, userEvent, within } from 'storybook/test';
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* eslint-disable local-rules/no-uncategorized-errors */
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import { Nested, RSC } from './RSC';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
import { redirect } from 'next/navigation';
|
||||
import { userEvent, within } from 'storybook/test';
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import { getRouter } from '@storybook/experimental-nextjs-vite/router.mock';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
import { getRouter } from '@storybook/nextjs-vite/router.mock';
|
||||
|
||||
import Router, { useRouter } from 'next/router';
|
||||
import { expect, userEvent, within } from 'storybook/test';
|
@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import { revalidatePath } from '@storybook/experimental-nextjs-vite/cache.mock';
|
||||
import { cookies } from '@storybook/experimental-nextjs-vite/headers.mock';
|
||||
import { getRouter, redirect } from '@storybook/experimental-nextjs-vite/navigation.mock';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
import { revalidatePath } from '@storybook/nextjs-vite/cache.mock';
|
||||
import { cookies } from '@storybook/nextjs-vite/headers.mock';
|
||||
import { getRouter, redirect } from '@storybook/nextjs-vite/navigation.mock';
|
||||
|
||||
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/experimental-nextjs-vite';
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
||||
|
||||
const Component = () => (
|
||||
<div>
|
@ -11,6 +11,16 @@ import {
|
||||
transformPackageJsonFiles,
|
||||
} from './consolidated-imports';
|
||||
|
||||
// mock picocolors yellow and cyan
|
||||
vi.mock('picocolors', () => {
|
||||
return {
|
||||
default: {
|
||||
cyan: (str: string) => str,
|
||||
red: (str: string) => str,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('node:fs/promises');
|
||||
vi.mock('globby', () => ({
|
||||
globby: vi.fn(),
|
||||
@ -104,6 +114,33 @@ describe('check', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('prompt', () => {
|
||||
it('should return a prompt', () => {
|
||||
const result = consolidatedImports.prompt({
|
||||
packageJsonFiles: ['test/package.json'],
|
||||
consolidatedDeps: new Set(['@storybook/core-common', '@storybook/experimental-nextjs-vite']),
|
||||
});
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"Found package.json files that contain consolidated or renamed Storybook packages that need to be updated:
|
||||
- test/package.json
|
||||
|
||||
We will automatically rename the following packages:
|
||||
- @storybook/core-common -> storybook/internal/common
|
||||
- @storybook/experimental-nextjs-vite -> storybook/nextjs-vite
|
||||
|
||||
These packages have been renamed or consolidated into the main storybook package and should be removed.
|
||||
The main storybook package will be added to devDependencies if not already present.
|
||||
|
||||
Would you like to:
|
||||
1. Update these package.json files
|
||||
2. Scan your codebase and update any imports from these updated packages
|
||||
|
||||
This will ensure your project is properly updated to use the new updated package structure and to use the latest package names."
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('transformPackageJsonFiles', () => {
|
||||
it('should transform package.json files', async () => {
|
||||
const contents = JSON.stringify(mockPackageJson);
|
||||
|
@ -2,6 +2,7 @@ import { readFile, writeFile } from 'node:fs/promises';
|
||||
|
||||
import { commonGlobOptions, getProjectRoot } from 'storybook/internal/common';
|
||||
|
||||
import picocolors from 'picocolors';
|
||||
import prompts from 'prompts';
|
||||
import { dedent } from 'ts-dedent';
|
||||
|
||||
@ -10,28 +11,23 @@ import type { Fix, RunOptions } from '../types';
|
||||
|
||||
export interface ConsolidatedOptions {
|
||||
packageJsonFiles: string[];
|
||||
consolidatedDeps: Set<keyof typeof consolidatedPackages>;
|
||||
}
|
||||
|
||||
function transformPackageJson(content: string): string | null {
|
||||
const packageJson = JSON.parse(content);
|
||||
let hasChanges = false;
|
||||
|
||||
// Check dependencies
|
||||
if (packageJson.dependencies) {
|
||||
for (const [dep, version] of Object.entries(packageJson.dependencies)) {
|
||||
if (dep in consolidatedPackages) {
|
||||
delete packageJson.dependencies[dep];
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check both dependencies and devDependencies
|
||||
const depTypes = ['dependencies', 'devDependencies'] as const;
|
||||
|
||||
// Check devDependencies
|
||||
if (packageJson.devDependencies) {
|
||||
for (const [dep, version] of Object.entries(packageJson.devDependencies)) {
|
||||
if (dep in consolidatedPackages) {
|
||||
delete packageJson.devDependencies[dep];
|
||||
hasChanges = true;
|
||||
for (const depType of depTypes) {
|
||||
if (packageJson[depType]) {
|
||||
for (const [dep] of Object.entries(packageJson[depType])) {
|
||||
if (dep in consolidatedPackages) {
|
||||
delete packageJson[depType][dep];
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,38 +116,63 @@ export const consolidatedImports: Fix<ConsolidatedOptions> = {
|
||||
gitignore: true,
|
||||
});
|
||||
|
||||
// check if any of the package.json files have consolidated packages
|
||||
const hasConsolidatedDependencies = await Promise.all(
|
||||
const consolidatedDeps = new Set<keyof typeof consolidatedPackages>();
|
||||
const affectedPackageJSONFiles = new Set<string>();
|
||||
|
||||
// Check all package.json files for consolidated packages
|
||||
await Promise.all(
|
||||
packageJsonFiles.map(async (file) => {
|
||||
const contents = await readFile(file, 'utf-8');
|
||||
const packageJson = JSON.parse(contents);
|
||||
return (
|
||||
Object.keys(packageJson.dependencies || {}).some((dep) => dep in consolidatedPackages) ||
|
||||
Object.keys(packageJson.devDependencies || {}).some((dep) => dep in consolidatedPackages)
|
||||
);
|
||||
})
|
||||
).then((results) => results.some(Boolean));
|
||||
|
||||
if (!hasConsolidatedDependencies) {
|
||||
// Check both dependencies and devDependencies
|
||||
const allDeps = {
|
||||
...(packageJson.dependencies || {}),
|
||||
...(packageJson.devDependencies || {}),
|
||||
};
|
||||
|
||||
// Add any consolidated packages to the set
|
||||
let hasConsolidatedDeps = false;
|
||||
Object.keys(allDeps).forEach((dep) => {
|
||||
if (dep in consolidatedPackages) {
|
||||
consolidatedDeps.add(dep as keyof typeof consolidatedPackages);
|
||||
hasConsolidatedDeps = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (hasConsolidatedDeps) {
|
||||
affectedPackageJSONFiles.add(file);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
if (consolidatedDeps.size === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
packageJsonFiles,
|
||||
consolidatedDeps,
|
||||
packageJsonFiles: Array.from(affectedPackageJSONFiles),
|
||||
};
|
||||
},
|
||||
prompt: (result: ConsolidatedOptions) => {
|
||||
return dedent`
|
||||
Found package.json files that contain consolidated Storybook packages that need to be updated:
|
||||
Found package.json files that contain consolidated or renamed Storybook packages that need to be updated:
|
||||
${result.packageJsonFiles.map((file) => `- ${file}`).join('\n')}
|
||||
|
||||
These packages have been consolidated into the main storybook package and should be removed.
|
||||
The main storybook package will be added to devDependencies if not already present.
|
||||
We will automatically rename the following packages:
|
||||
${Array.from(result.consolidatedDeps)
|
||||
.map((dep) => `- ${picocolors.red(dep)} -> ${picocolors.cyan(consolidatedPackages[dep])}`)
|
||||
.join('\n')}
|
||||
|
||||
These packages have been renamed or consolidated into the main ${picocolors.cyan('storybook')} package and should be removed.
|
||||
The main ${picocolors.cyan('storybook')} package will be added to devDependencies if not already present.
|
||||
|
||||
Would you like to:
|
||||
1. Update these package.json files
|
||||
2. Scan your codebase and update any imports from these consolidated packages
|
||||
2. Scan your codebase and update any imports from these updated packages
|
||||
|
||||
This will ensure your project is properly updated to use the new consolidated package structure.
|
||||
This will ensure your project is properly updated to use the new updated package structure and to use the latest package names.
|
||||
`;
|
||||
},
|
||||
run: async (options: RunOptions<ConsolidatedOptions>) => {
|
||||
@ -165,7 +186,7 @@ export const consolidatedImports: Fix<ConsolidatedOptions> = {
|
||||
|
||||
const projectRoot = getProjectRoot();
|
||||
|
||||
const defaultGlob = '**/*.{mjs,cjs,js,jsx,ts,tsx}';
|
||||
const defaultGlob = '**/*.{mjs,cjs,js,jsx,ts,tsx,mdx}';
|
||||
// Find all files matching the glob pattern
|
||||
const { glob } = await prompts({
|
||||
type: 'text',
|
||||
|
@ -26,6 +26,7 @@ export const consolidatedPackages = {
|
||||
'@storybook/addon-controls': 'storybook/internal/controls',
|
||||
'@storybook/addon-toolbars': 'storybook/internal/toolbars',
|
||||
'@storybook/addon-viewport': 'storybook/viewport',
|
||||
'@storybook/experimental-nextjs-vite': 'storybook/nextjs-vite',
|
||||
} as const;
|
||||
|
||||
export type ConsolidatedPackage = keyof typeof consolidatedPackages;
|
||||
|
@ -210,25 +210,20 @@ export const baseTemplates = {
|
||||
script:
|
||||
'npx create-next-app@^14 {{beforeDir}} --eslint --tailwind --app --import-alias="@/*" --src-dir',
|
||||
expected: {
|
||||
framework: '@storybook/experimental-nextjs-vite',
|
||||
framework: '@storybook/nextjs-vite',
|
||||
renderer: '@storybook/react',
|
||||
builder: '@storybook/builder-vite',
|
||||
},
|
||||
modifications: {
|
||||
useCsfFactory: true,
|
||||
mainConfig: {
|
||||
framework: '@storybook/experimental-nextjs-vite',
|
||||
framework: '@storybook/nextjs-vite',
|
||||
features: {
|
||||
experimentalRSC: true,
|
||||
developmentModeForBuild: true,
|
||||
},
|
||||
},
|
||||
extraDependencies: [
|
||||
'server-only',
|
||||
'@storybook/experimental-nextjs-vite',
|
||||
'vite',
|
||||
'prop-types',
|
||||
],
|
||||
extraDependencies: ['server-only', '@storybook/nextjs-vite', 'vite', 'prop-types'],
|
||||
},
|
||||
skipTasks: ['e2e-tests-dev', 'bench'],
|
||||
},
|
||||
@ -237,25 +232,20 @@ export const baseTemplates = {
|
||||
script:
|
||||
'npx create-next-app {{beforeDir}} --eslint --no-tailwind --app --import-alias="@/*" --src-dir',
|
||||
expected: {
|
||||
framework: '@storybook/experimental-nextjs-vite',
|
||||
framework: '@storybook/nextjs-vite',
|
||||
renderer: '@storybook/react',
|
||||
builder: '@storybook/builder-vite',
|
||||
},
|
||||
modifications: {
|
||||
useCsfFactory: true,
|
||||
mainConfig: {
|
||||
framework: '@storybook/experimental-nextjs-vite',
|
||||
framework: '@storybook/nextjs-vite',
|
||||
features: {
|
||||
experimentalRSC: true,
|
||||
developmentModeForBuild: true,
|
||||
},
|
||||
},
|
||||
extraDependencies: [
|
||||
'server-only',
|
||||
'@storybook/experimental-nextjs-vite',
|
||||
'vite',
|
||||
'prop-types',
|
||||
],
|
||||
extraDependencies: ['server-only', '@storybook/nextjs-vite', 'vite', 'prop-types'],
|
||||
},
|
||||
skipTasks: ['e2e-tests-dev', 'bench'],
|
||||
},
|
||||
|
@ -7,7 +7,7 @@ export const supportedFrameworks = [
|
||||
'html-vite',
|
||||
'html-webpack5',
|
||||
'nextjs',
|
||||
'experimental-nextjs-vite',
|
||||
'nextjs-vite',
|
||||
'nuxt',
|
||||
'preact-vite',
|
||||
'qwik',
|
||||
@ -48,7 +48,7 @@ export const supportedFrameworksPackages = {
|
||||
angular: '@storybook/angular',
|
||||
ember: '@storybook/ember',
|
||||
nextjs: '@storybook/nextjs',
|
||||
'experimental-nextjs-vite': '@storybook/experimental-nextjs-vite',
|
||||
'nextjs-vite': '@storybook/nextjs-vite',
|
||||
|
||||
nuxt: '@storybook/vue3-vite',
|
||||
qwik: 'storybook-framework-qwik',
|
||||
@ -76,7 +76,7 @@ export const supportedFrameworksNames = {
|
||||
angular: 'Angular',
|
||||
ember: 'Ember',
|
||||
nextjs: 'NextJS',
|
||||
'experimental-nextjs-vite': 'NextJS with Vite',
|
||||
'nextjs-vite': 'NextJS with Vite',
|
||||
nuxt: 'Nuxt',
|
||||
qwik: 'Qwik',
|
||||
solid: 'Solid',
|
||||
|
@ -12,13 +12,13 @@ export const SUPPORTED_FRAMEWORKS: Framework[] = [
|
||||
'svelte-vite',
|
||||
'web-components-vite',
|
||||
'nextjs',
|
||||
'experimental-nextjs-vite',
|
||||
'nextjs-vite',
|
||||
'sveltekit',
|
||||
];
|
||||
|
||||
/**
|
||||
* When selecting framework nextjs & intent includes test, prompt for experimental-nextjs-vite. When
|
||||
* selecting another framework that doesn't support test addon, prompt for ignoring test intent.
|
||||
* When selecting framework nextjs & intent includes test, prompt for nextjs-vite. When selecting
|
||||
* another framework that doesn't support test addon, prompt for ignoring test intent.
|
||||
*/
|
||||
const name = 'Framework test compatibility';
|
||||
export const frameworkTest: Check = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "experimental-nextjs-vite/default-ts",
|
||||
"name": "nextjs-vite/default-ts",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"implicitDependencies": [
|
||||
@ -8,7 +8,7 @@
|
||||
"addon-links",
|
||||
"addon-onboarding",
|
||||
"blocks",
|
||||
"experimental-nextjs-vite"
|
||||
"nextjs-vite"
|
||||
],
|
||||
"targets": {
|
||||
"sandbox": {},
|
||||
|
@ -7067,30 +7067,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/experimental-nextjs-vite@workspace:frameworks/experimental-nextjs-vite":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@storybook/experimental-nextjs-vite@workspace:frameworks/experimental-nextjs-vite"
|
||||
dependencies:
|
||||
"@storybook/builder-vite": "workspace:*"
|
||||
"@storybook/react": "workspace:*"
|
||||
"@storybook/react-vite": "workspace:*"
|
||||
"@types/node": "npm:^22.0.0"
|
||||
next: "npm:^15.0.3"
|
||||
styled-jsx: "npm:5.1.6"
|
||||
typescript: "npm:^5.7.3"
|
||||
vite-plugin-storybook-nextjs: "npm:2.0.0--canary.33.7c1f48f.0"
|
||||
peerDependencies:
|
||||
next: ^14.1.0 || ^15.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
storybook: "workspace:^"
|
||||
vite: ^5.0.0 || ^6.0.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@storybook/global@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "@storybook/global@npm:5.0.0"
|
||||
@ -7176,6 +7152,30 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/nextjs-vite@workspace:frameworks/nextjs-vite":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@storybook/nextjs-vite@workspace:frameworks/nextjs-vite"
|
||||
dependencies:
|
||||
"@storybook/builder-vite": "workspace:*"
|
||||
"@storybook/react": "workspace:*"
|
||||
"@storybook/react-vite": "workspace:*"
|
||||
"@types/node": "npm:^22.0.0"
|
||||
next: "npm:^15.0.3"
|
||||
styled-jsx: "npm:5.1.6"
|
||||
typescript: "npm:^5.7.3"
|
||||
vite-plugin-storybook-nextjs: "npm:2.0.0--canary.33.7c1f48f.0"
|
||||
peerDependencies:
|
||||
next: ^14.1.0 || ^15.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
storybook: "workspace:^"
|
||||
vite: ^5.0.0 || ^6.0.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@storybook/nextjs@workspace:*, @storybook/nextjs@workspace:frameworks/nextjs":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@storybook/nextjs@workspace:frameworks/nextjs"
|
||||
|
@ -33,7 +33,7 @@ The CSF Factories API is composed of four main functions to help you write stori
|
||||
With CSF Factories, your [main Storybook config](../main-config/main-config.mdx) is specified by the `defineMain` function. This function is type-safe and will automatically infer types for your project.
|
||||
|
||||
```ts title=".storybook/main.js|ts"
|
||||
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, experimental-nextjs-vite)
|
||||
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite)
|
||||
import { defineMain } from '@storybook/your-framework/node';
|
||||
|
||||
export default defineMain({
|
||||
@ -52,7 +52,7 @@ Importantly, by specifying addons here, their types will be available throughout
|
||||
You will import the result of this function, `preview`, in your story files to define the component meta.
|
||||
|
||||
```ts title=".storybook/preview.js|ts"
|
||||
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, experimental-nextjs-vite)
|
||||
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite)
|
||||
import { definePreview } from '@storybook/your-framework';
|
||||
import addonA11y from '@storybook/addon-a11y';
|
||||
|
||||
@ -145,7 +145,7 @@ To be able to consistently import the preview file from any location in your pro
|
||||
Update your `.storybook/main.js|ts` file to use the new [`defineMain`](#definemain) function.
|
||||
|
||||
```diff title=".storybook/main.js|ts"
|
||||
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, experimental-nextjs-vite)
|
||||
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite)
|
||||
+ import { defineMain } from '@storybook/your-framework/node';
|
||||
- import { StorybookConfig } from '@storybook/your-framework';
|
||||
|
||||
@ -177,7 +177,7 @@ If an addon provides annotations (i.e. it distributes a `./preview` export), it
|
||||
</details>
|
||||
|
||||
```diff title=".storybook/preview.js|ts"
|
||||
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, experimental-nextjs-vite)
|
||||
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite)
|
||||
+ import { definePreview } from '@storybook/your-framework';
|
||||
- import { Preview } from '@storybook/your-renderer';
|
||||
// 👇 Import the addons you are using
|
||||
|
@ -34,7 +34,7 @@ sidebar:
|
||||
|
||||
<If renderer="react">
|
||||
<Callout variant="warning">
|
||||
**Using `Next.js`?** You can test your Next.js stories with Vitest by installing and setting up the `@storybook/experimental-nextjs-vite` which re-exports [vite-plugin-storybook-nextjs](https://github.com/storybookjs/vite-plugin-storybook-nextjs) package.
|
||||
**Using `Next.js`?** You can test your Next.js stories with Vitest by installing and setting up the `@storybook/nextjs-vite` which re-exports [vite-plugin-storybook-nextjs](https://github.com/storybookjs/vite-plugin-storybook-nextjs) package.
|
||||
</Callout>
|
||||
</If>
|
||||
|
||||
|
@ -78,7 +78,7 @@ Finally, if you were using Storybook plugins to integrate with Next.js, those ar
|
||||
|
||||
(⚠️ **Experimental**)
|
||||
|
||||
You can use our freshly baked, experimental `@storybook/experimental-nextjs-vite` framework, which is based on Vite and removes the need for Webpack and Babel. It supports all of the features documented here.
|
||||
You can use our freshly baked, experimental `@storybook/nextjs-vite` framework, which is based on Vite and removes the need for Webpack and Babel. It supports all of the features documented here.
|
||||
|
||||
<Callout variant="info">
|
||||
Using the Next.js framework with Vite requires Next.js 14.1.0 or later.
|
||||
@ -195,7 +195,7 @@ const localRubikStorm = localFont({ src: './fonts/RubikStorm-Regular.ttf' });
|
||||
#### `staticDir` mapping
|
||||
|
||||
<Callout variant="info">
|
||||
You can safely skip this section if you are using [`@storybook/experimental-nextjs-vite`](#with-vite) instead of `@storybook/nextjs`. The Vite-based framework takes care of the mapping automatically.
|
||||
You can safely skip this section if you are using [`@storybook/nextjs-vite`](#with-vite) instead of `@storybook/nextjs`. The Vite-based framework takes care of the mapping automatically.
|
||||
</Callout>
|
||||
|
||||
You have to tell Storybook where the `fonts` directory is located, via the [`staticDirs` configuration](../../api/main-config/main-config-static-dirs.mdx#with-configuration-objects). The `from` value is relative to the `.storybook` directory. The `to` value is relative to the execution context of Storybook. Very likely it is the root of your project.
|
||||
@ -751,7 +751,7 @@ Calls to `getConfig` would return the following object when called within Storyb
|
||||
## Custom Webpack config
|
||||
|
||||
<Callout variant="info">
|
||||
You can safely skip this section if you are using `@storybook/experimental-nextjs-vite` instead of `@storybook/nextjs`.
|
||||
You can safely skip this section if you are using `@storybook/nextjs-vite` instead of `@storybook/nextjs`.
|
||||
The Vite-based Next.js framework does not support Webpack settings.
|
||||
</Callout>
|
||||
|
||||
@ -901,7 +901,7 @@ You might get this if you're using Yarn v2 or v3. See [Notes for Yarn v2 and v3
|
||||
|
||||
### What if I'm using the Vite builder?
|
||||
|
||||
We have introduced experimental Vite builder support. Just install the experimental framework package `@storybook/experimental-nextjs-vite` and replace all instances of `@storybook/nextjs` with `@storybook/experimental-nextjs-vite`.
|
||||
We have introduced experimental Vite builder support. Just install the experimental framework package `@storybook/nextjs-vite` and replace all instances of `@storybook/nextjs` with `@storybook/nextjs-vite`.
|
||||
|
||||
### Error: You are importing avif images, but you don't have sharp installed. You have to install sharp in order to use image optimization features in Next.js.
|
||||
|
||||
|
@ -40,7 +40,7 @@ Before installing, make sure your project meets the following requirements:
|
||||
|
||||
<If renderer="react">
|
||||
<Callout variant="info" icon="ℹ️">
|
||||
**Using with Next.js** — The Test addon is supported in Next.js ≥ 14.1 projects, but you must be using the [`@storybook/experimental-nextjs-vite` framework](../get-started/frameworks/nextjs.mdx#with-vite). When you run the setup command below, you will be prompted to install and use the framework if you haven't already.
|
||||
**Using with Next.js** — The Test addon is supported in Next.js ≥ 14.1 projects, but you must be using the [`@storybook/nextjs-vite` framework](../get-started/frameworks/nextjs.mdx#with-vite). When you run the setup command below, you will be prompted to install and use the framework if you haven't already.
|
||||
</Callout>
|
||||
</If>
|
||||
|
||||
|
@ -409,7 +409,7 @@ export async function setupVitest(details: TemplateDetails, options: PassedOptio
|
||||
|
||||
const portableStoriesFrameworks = [
|
||||
'@storybook/nextjs',
|
||||
'@storybook/experimental-nextjs-vite',
|
||||
'@storybook/nextjs-vite',
|
||||
'@storybook/sveltekit',
|
||||
// TODO: add angular once we enable their sandboxes
|
||||
];
|
||||
|
@ -85,7 +85,7 @@ export const sandbox: Task = {
|
||||
extraDeps.push('happy-dom', 'vitest', 'playwright', '@vitest/browser');
|
||||
|
||||
if (details.template.expected.framework.includes('nextjs')) {
|
||||
extraDeps.push('@storybook/experimental-nextjs-vite', 'jsdom');
|
||||
extraDeps.push('@storybook/nextjs-vite', 'jsdom');
|
||||
}
|
||||
|
||||
// if (details.template.expected.renderer === '@storybook/svelte') {
|
||||
|
Loading…
x
Reference in New Issue
Block a user