From db5ec1dcef5618de6ad4bc7a6ce5b4ae5308c6f0 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 4 Dec 2023 10:37:19 +0100 Subject: [PATCH 1/7] Next.js: Drop < 13.5.0 support --- MIGRATION.md | 8 ++ code/frameworks/nextjs/package.json | 19 +---- code/frameworks/nextjs/src/config/webpack.ts | 21 +---- code/frameworks/nextjs/src/dependency-map.ts | 42 ---------- .../google/get-font-face-declarations.ts | 26 +++--- .../local/get-font-face-declarations.ts | 9 +- .../webpack/loader/utils/google-font-utils.ts | 82 ------------------- .../webpack/loader/utils/local-font-utils.ts | 76 ----------------- .../nextjs/src/images/next-future-image.tsx | 24 ------ code/frameworks/nextjs/src/images/webpack.ts | 8 -- .../nextjs/src/nextImport/webpack.ts | 40 --------- code/frameworks/nextjs/src/preset.ts | 4 - .../src/routing/app-router-provider-mock.tsx | 6 -- .../nextjs/src/routing/decorator.tsx | 4 +- .../nextjs/src/styledJsx/decorator.tsx | 11 +-- .../nextjs/src/styledJsx/webpack.ts | 15 +--- .../ImageFuture.stories.jsx | 55 ------------- .../stories_nextjs-12-js/Link.stories.jsx | 28 ------- 18 files changed, 32 insertions(+), 446 deletions(-) delete mode 100644 code/frameworks/nextjs/src/dependency-map.ts delete mode 100644 code/frameworks/nextjs/src/font/webpack/loader/utils/google-font-utils.ts delete mode 100644 code/frameworks/nextjs/src/font/webpack/loader/utils/local-font-utils.ts delete mode 100644 code/frameworks/nextjs/src/images/next-future-image.tsx delete mode 100644 code/frameworks/nextjs/src/nextImport/webpack.ts delete mode 100644 code/frameworks/nextjs/src/routing/app-router-provider-mock.tsx delete mode 100644 code/frameworks/nextjs/template/stories_nextjs-12-js/ImageFuture.stories.jsx delete mode 100644 code/frameworks/nextjs/template/stories_nextjs-12-js/Link.stories.jsx diff --git a/MIGRATION.md b/MIGRATION.md index dbb9ed74ce83..90ed8504d39e 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -18,6 +18,8 @@ - [typescript.skipBabel deprecated](#typescriptskipbabel-deprecated) - [Primary doc block accepts of prop](#primary-doc-block-accepts-of-prop) - [Addons no longer need a peer dependency on React](#addons-no-longer-need-a-peer-dependency-on-react) + - [Framework-specific changes](#framework-specific-changes) + - [Next.js: Drop support for Angular \< 13.5](#nextjs-drop-support-for-angular--135) - [From version 7.4.0 to 7.5.0](#from-version-740-to-750) - [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated) - [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers) @@ -556,6 +558,12 @@ const allGlobalPackages = [...globalManagerPackages, ...globalPreviewPackages]; We recommend checking out [the updates we've made to the addon-kit](https://github.com/storybookjs/addon-kit/pull/60/files#diff-8fed899bdbc24789a7bb4973574e624ed6207c6ce572338bc3c3e117672b2a20), that can serve as a base for the changes you can do in your own addon. These changes are not necessary for your addon to keep working, but they will remove the need for your users to unnecessary install `react` and `react-dom` to their projects, and they'll significantly reduce the install size of your addon. These changes should not be breaking for your users, unless you support Storybook pre-v7. +### Framework-specific changes + +#### Next.js: Drop support for Angular \< 13.5 + +Starting in 8.0, we drop support for Next.js < 13.5. + ## From version 7.4.0 to 7.5.0 #### `storyStoreV6` and `storiesOf` is deprecated diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index c0318bdc95d9..c673b0de812e 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -32,16 +32,6 @@ "require": "./dist/image-context.js", "import": "./dist/image-context.mjs" }, - "./dist/routing/app-router-provider": { - "types": "./dist/routing/app-router-provider.d.ts", - "require": "./dist/routing/app-router-provider.js", - "import": "./dist/routing/app-router-provider.mjs" - }, - "./dist/routing/app-router-provider-mock": { - "types": "./dist/routing/app-router-provider-mock.d.ts", - "require": "./dist/routing/app-router-provider-mock.js", - "import": "./dist/routing/app-router-provider-mock.mjs" - }, "./preset": { "types": "./dist/preset.d.ts", "require": "./dist/preset.js" @@ -137,16 +127,12 @@ "webpack": "^5.65.0" }, "peerDependencies": { - "@next/font": "^13.0.0|| ^14.0.0", - "next": "^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0", + "next": "^13.5.0 || ^14.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", "webpack": "^5.0.0" }, "peerDependenciesMeta": { - "@next/font": { - "optional": true - }, "typescript": { "optional": true }, @@ -168,11 +154,8 @@ "./src/preview.tsx", "./src/next-image-loader-stub.ts", "./src/images/decorator.tsx", - "./src/images/next-future-image.tsx", "./src/images/next-legacy-image.tsx", "./src/images/next-image.tsx", - "./src/routing/app-router-provider.tsx", - "./src/routing/app-router-provider-mock.tsx", "./src/font/webpack/loader/storybook-nextjs-font-loader.ts", "./src/swc/next-swc-loader-patch.ts" ], diff --git a/code/frameworks/nextjs/src/config/webpack.ts b/code/frameworks/nextjs/src/config/webpack.ts index 9d7c85d8c003..be2a983fceec 100644 --- a/code/frameworks/nextjs/src/config/webpack.ts +++ b/code/frameworks/nextjs/src/config/webpack.ts @@ -1,9 +1,8 @@ import type { Configuration as WebpackConfig } from 'webpack'; -import semver from 'semver'; import type { NextConfig } from 'next'; import { DefinePlugin } from 'webpack'; -import { addScopedAlias, getNextjsVersion, resolveNextConfig } from '../utils'; +import { addScopedAlias, resolveNextConfig } from '../utils'; const tryResolve = (path: string) => { try { @@ -36,8 +35,6 @@ export const configureConfig = async ({ return nextConfig; }; -const version = getNextjsVersion(); - const setupRuntimeConfig = (baseConfig: WebpackConfig, nextConfig: NextConfig): void => { const definePluginConfig: Record = { // this mimics what nextjs does client side @@ -50,21 +47,7 @@ const setupRuntimeConfig = (baseConfig: WebpackConfig, nextConfig: NextConfig): const newNextLinkBehavior = (nextConfig.experimental as any)?.newNextLinkBehavior; - /** - * In Next 13.0.0 - 13.0.5, the `newNextLinkBehavior` option now defaults to truthy (still - * `undefined` in the config), and `next/link` was engineered to opt *out* - * of it - * - */ - if ( - semver.gte(version, '13.0.0') && - semver.lt(version, '13.0.6') && - newNextLinkBehavior !== false - ) { - definePluginConfig['process.env.__NEXT_NEW_LINK_BEHAVIOR'] = true; - } else { - definePluginConfig['process.env.__NEXT_NEW_LINK_BEHAVIOR'] = newNextLinkBehavior; - } + definePluginConfig['process.env.__NEXT_NEW_LINK_BEHAVIOR'] = newNextLinkBehavior; baseConfig.plugins?.push(new DefinePlugin(definePluginConfig)); }; diff --git a/code/frameworks/nextjs/src/dependency-map.ts b/code/frameworks/nextjs/src/dependency-map.ts deleted file mode 100644 index 2849f6b02498..000000000000 --- a/code/frameworks/nextjs/src/dependency-map.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { Configuration as WebpackConfig } from 'webpack'; -import semver from 'semver'; -import { getNextjsVersion, addScopedAlias } from './utils'; - -const mapping: Record> = { - '<11.1.0': { - 'next/dist/next-server/lib/router-context': 'next/dist/next-server/lib/router-context', - }, - '>=11.1.0 <13.5.0': { - 'next/dist/shared/lib/router-context': 'next/dist/shared/lib/router-context', - }, - '>=13.0.2 <13.5.0': { - 'next/dist/shared/lib/hooks-client-context.shared-runtime': - 'next/dist/shared/lib/hooks-client-context', - }, - '<13.0.0': { - '@storybook/nextjs/dist/routing/app-router-provider': - '@storybook/nextjs/dist/routing/app-router-provider-mock', - }, - '<13.5.0': { - 'next/dist/shared/lib/router-context.shared-runtime': 'next/dist/shared/lib/router-context', - 'next/dist/shared/lib/head-manager-context.shared-runtime': - 'next/dist/shared/lib/head-manager-context', - 'next/dist/shared/lib/app-router-context.shared-runtime': - 'next/dist/shared/lib/app-router-context', - }, -}; - -export const configureAliasing = (baseConfig: WebpackConfig): void => { - const version = getNextjsVersion(); - const result: Record = {}; - - Object.keys(mapping).forEach((key) => { - if (semver.intersects(version, key)) { - Object.assign(result, mapping[key]); - } - }); - - Object.entries(result).forEach(([name, alias]) => { - addScopedAlias(baseConfig, name, alias); - }); -}; diff --git a/code/frameworks/nextjs/src/font/webpack/loader/google/get-font-face-declarations.ts b/code/frameworks/nextjs/src/font/webpack/loader/google/get-font-face-declarations.ts index 0f8bfb1957f8..3f9db77ebb16 100644 --- a/code/frameworks/nextjs/src/font/webpack/loader/google/get-font-face-declarations.ts +++ b/code/frameworks/nextjs/src/font/webpack/loader/google/get-font-face-declarations.ts @@ -5,34 +5,28 @@ import { GoogleFontsDownloadError, GoogleFontsLoadingError, } from '@storybook/core-events/server-errors'; +import { validateGoogleFontFunctionCall } from 'next/dist/compiled/@next/font/dist/google/validate-google-font-function-call'; +import { getGoogleFontsUrl } from 'next/dist/compiled/@next/font/dist/google/get-google-fonts-url'; +import { getFontAxes } from 'next/dist/compiled/@next/font/dist/google/get-font-axes'; +import { fetchCSSFromGoogleFonts } from 'next/dist/compiled/@next/font/dist/google/fetch-css-from-google-fonts'; import type { LoaderOptions } from '../types'; -const cssCache = new Map>(); +const cssCache = new Map(); export async function getFontFaceDeclarations(options: LoaderOptions) { - const { - fetchCSSFromGoogleFonts, - getFontAxes, - getUrl, - validateData, - } = require('../utils/google-font-utils'); - - const { fontFamily, weights, styles, selectedVariableAxes, display, variable } = validateData( - options.fontFamily, - [options.props], - null - ); + const { fontFamily, weights, styles, selectedVariableAxes, display, variable } = + validateGoogleFontFunctionCall(options.fontFamily, options.props); const fontAxes = getFontAxes(fontFamily, weights, styles, selectedVariableAxes); - const url = getUrl(fontFamily, fontAxes, display); + const url = getGoogleFontsUrl(fontFamily, fontAxes, display); try { const hasCachedCSS = cssCache.has(url); const fontFaceCSS = hasCachedCSS ? cssCache.get(url) - : await fetchCSSFromGoogleFonts(url, fontFamily).catch(() => null); + : await fetchCSSFromGoogleFonts(url, fontFamily, true).catch(() => null); if (!hasCachedCSS) { - cssCache.set(url, fontFaceCSS); + cssCache.set(url, fontFaceCSS as string); } else { cssCache.delete(url); } diff --git a/code/frameworks/nextjs/src/font/webpack/loader/local/get-font-face-declarations.ts b/code/frameworks/nextjs/src/font/webpack/loader/local/get-font-face-declarations.ts index 54ef87d299bf..f3f35c2fc065 100644 --- a/code/frameworks/nextjs/src/font/webpack/loader/local/get-font-face-declarations.ts +++ b/code/frameworks/nextjs/src/font/webpack/loader/local/get-font-face-declarations.ts @@ -2,6 +2,7 @@ // @ts-expect-error import loaderUtils from 'next/dist/compiled/loader-utils3'; import { getProjectRoot } from '@storybook/core-common'; +import { validateLocalFontFunctionCall } from 'next/dist/compiled/@next/font/dist/local/validate-local-font-function-call'; import path from 'path'; import type { LoaderOptions } from '../types'; @@ -20,8 +21,12 @@ export async function getFontFaceDeclarations( ? path.dirname(path.join(getProjectRoot(), options.filename)).replace(rootContext, '') : path.dirname(options.filename).replace(rootContext, ''); - const { validateData } = require('../utils/local-font-utils'); - const { weight, style, variable, declarations = [] } = validateData('', options.props); + const { + weight, + style, + variable, + declarations = [], + } = validateLocalFontFunctionCall('', options.props); const id = `font-${loaderUtils.getHashDigest( Buffer.from(JSON.stringify(localFontSrc)), diff --git a/code/frameworks/nextjs/src/font/webpack/loader/utils/google-font-utils.ts b/code/frameworks/nextjs/src/font/webpack/loader/utils/google-font-utils.ts deleted file mode 100644 index 20fe04209947..000000000000 --- a/code/frameworks/nextjs/src/font/webpack/loader/utils/google-font-utils.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* eslint-disable import/no-mutable-exports */ - -import dedent from 'ts-dedent'; - -type FontOptions = { - fontFamily: string; - weights: string[]; - styles: string[]; - display: string; - preload: boolean; - selectedVariableAxes?: string[]; - fallback?: string[]; - adjustFontFallback: boolean; - variable?: string; - subsets: string[]; -}; - -let validateData: (functionName: string, fontData: any, config: any) => FontOptions; - -let getUrl: ( - fontFamily: string, - axes: { - wght?: string[]; - ital?: string[]; - variableAxes?: [string, string][]; - }, - display: string -) => string; - -let getFontAxes: ( - fontFamily: string, - weights: string[], - styles: string[], - selectedVariableAxes?: string[] -) => { - wght?: string[]; - ital?: string[]; - variableAxes?: [string, string][]; -}; - -let fetchCSSFromGoogleFonts: (url: string, fontFamily: string) => Promise; - -// Support @next/font -try { - const fontUtils = require('@next/font/dist/google/utils'); - validateData = fontUtils.validateData; - getUrl = fontUtils.getUrl; - getFontAxes = fontUtils.getFontAxes; - fetchCSSFromGoogleFonts = fontUtils.fetchCSSFromGoogleFonts; -} catch (_) { - // Support next/font prior to v13.2.4 - try { - const fontUtils = require('next/dist/compiled/@next/font/dist/google/utils'); - validateData = fontUtils.validateData; - getUrl = fontUtils.getUrl; - getFontAxes = fontUtils.getFontAxes; - fetchCSSFromGoogleFonts = fontUtils.fetchCSSFromGoogleFonts; - } catch (__) { - // Support next/font since v13.2.4 - try { - validateData = (functionName, fontData, config) => - require('next/dist/compiled/@next/font/dist/google/validate-google-font-function-call').validateGoogleFontFunctionCall( - functionName, - fontData[0], - config - ); - getUrl = - require('next/dist/compiled/@next/font/dist/google/get-google-fonts-url').getGoogleFontsUrl; - getFontAxes = require('next/dist/compiled/@next/font/dist/google/get-font-axes').getFontAxes; - fetchCSSFromGoogleFonts = - require('next/dist/compiled/@next/font/dist/google/fetch-css-from-google-fonts').fetchCSSFromGoogleFonts; - } catch (e) { - throw new Error(dedent` - We are unable to load the helper functions to use next/font/google. - Please downgrade Next.js to version 13.2.4 to continue to use next/font/google in Storybook. - Feel free to open a Github Issue! - `); - } - } -} - -export { validateData, getUrl, getFontAxes, fetchCSSFromGoogleFonts }; diff --git a/code/frameworks/nextjs/src/font/webpack/loader/utils/local-font-utils.ts b/code/frameworks/nextjs/src/font/webpack/loader/utils/local-font-utils.ts deleted file mode 100644 index d532f8dcc794..000000000000 --- a/code/frameworks/nextjs/src/font/webpack/loader/utils/local-font-utils.ts +++ /dev/null @@ -1,76 +0,0 @@ -import dedent from 'ts-dedent'; - -type FontOptions = { - src: Array<{ - path: string; - weight?: string; - style?: string; - ext: string; - format: string; - }>; - display: string; - weight?: string; - style?: string; - fallback?: string[]; - preload: boolean; - variable?: string; - adjustFontFallback?: string | false; - declarations?: Array<{ - prop: string; - value: string; - }>; -}; - -const trials = [ - { - module: '@next/font/dist/local/utils', - exportName: 'validateData', - description: 'Support @next/font prior to v13.2.5', - }, - { - module: '@next/font/dist/local/validate-local-font-function-call', - exportName: 'validateLocalFontFunctionCall', - description: 'Support @next/font since v13.2.5', - }, - { - module: 'next/dist/compiled/@next/font/dist/local/utils', - exportName: 'validateData', - description: 'Support next/font prior to v13.2.4', - }, - { - module: 'next/dist/compiled/@next/font/dist/local/validate-local-font-function-call', - exportName: 'validateLocalFontFunctionCall', - description: 'Support next/font since v13.2.4', - }, -]; - -const validateData: (functionName: string, fontData: any) => FontOptions = (() => { - // eslint-disable-next-line no-restricted-syntax - for (const { module, exportName } of trials) { - try { - const loadedModule = require(module); - if (exportName in loadedModule) { - return loadedModule[exportName]; - } - } catch { - // Continue to the next trial - } - } - - // Generate the dynamic error message - const errorDetails = trials - .map( - (trial) => - `- ${trial.description}: tries to import '${trial.exportName}' from '${trial.module}'` - ) - .join('\n'); - - throw new Error(dedent` - We were unable to load the helper functions to use next/font/local. The code attempted the following scenarios: - ${errorDetails} - - Please check your Next.js version and the module paths. If you resolve this issue for a version or setup not covered, consider contributing by updating the 'trials' array and making a pull request. - `); -})(); - -export { validateData }; diff --git a/code/frameworks/nextjs/src/images/next-future-image.tsx b/code/frameworks/nextjs/src/images/next-future-image.tsx deleted file mode 100644 index 306518079b38..000000000000 --- a/code/frameworks/nextjs/src/images/next-future-image.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import type * as _NextImage from 'next/image'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore import is aliased in webpack config -import OriginalNextFutureImage from 'sb-original/next/future/image'; - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore-error (this only errors during compilation for production) -// eslint-disable-next-line import/no-extraneous-dependencies -import { ImageContext as ImageContextValue } from '@storybook/nextjs/dist/image-context'; -import { type ImageContext as ImageContextType } from '../image-context'; -import { defaultLoader } from './next-image-default-loader'; - -const ImageContext = ImageContextValue as typeof ImageContextType; - -function NextFutureImage({ loader, ...props }: _NextImage.ImageProps) { - const imageParameters = React.useContext(ImageContext); - - return ( - - ); -} - -export default NextFutureImage; diff --git a/code/frameworks/nextjs/src/images/webpack.ts b/code/frameworks/nextjs/src/images/webpack.ts index e80e03545beb..31324d099e48 100644 --- a/code/frameworks/nextjs/src/images/webpack.ts +++ b/code/frameworks/nextjs/src/images/webpack.ts @@ -27,14 +27,6 @@ const configureImageDefaults = (baseConfig: WebpackConfig): void => { 'next/legacy/image': path.resolve(__dirname, './images/next-legacy-image'), }; } - - if (semver.satisfies(version, '^12.2.0')) { - resolve.alias = { - ...resolve.alias, - 'sb-original/next/future/image': require.resolve('next/future/image'), - 'next/future/image': path.resolve(__dirname, './images/next-future-image'), - }; - } }; const configureStaticImageImport = (baseConfig: WebpackConfig, nextConfig: NextConfig): void => { diff --git a/code/frameworks/nextjs/src/nextImport/webpack.ts b/code/frameworks/nextjs/src/nextImport/webpack.ts deleted file mode 100644 index 35f39a7069ed..000000000000 --- a/code/frameworks/nextjs/src/nextImport/webpack.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { Configuration as WebpackConfig } from 'webpack'; -import semver from 'semver'; -import { IgnorePlugin } from 'webpack'; -import { getNextjsVersion } from '../utils'; - -export function configureNextImport(baseConfig: WebpackConfig) { - const nextJSVersion = getNextjsVersion(); - - const isNext12 = semver.satisfies(nextJSVersion, '~12'); - const isNextVersionSmallerThan12dot2 = semver.lt(nextJSVersion, '12.2.0'); - const isNextVersionSmallerThan13 = semver.lt(nextJSVersion, '13.0.0'); - - baseConfig.plugins = baseConfig.plugins ?? []; - - if (!isNext12 || isNextVersionSmallerThan12dot2) { - baseConfig.plugins.push( - new IgnorePlugin({ - resourceRegExp: /next\/future\/image$/, - }) - ); - } - - if (isNextVersionSmallerThan13) { - baseConfig.plugins.push( - new IgnorePlugin({ - // ignore next/dist/shared/lib/hooks-client-context and next/legacy/image imports - resourceRegExp: - /(next\/dist\/shared\/lib\/hooks-client-context|next\/dist\/shared\/lib\/hooks-client-context\.shared-runtime|next\/legacy\/image)$/, - }) - ); - } - - if (isNextVersionSmallerThan12dot2) { - baseConfig.plugins.push( - new IgnorePlugin({ - resourceRegExp: /next\/dist\/shared\/lib\/app-router-context$/, - }) - ); - } -} diff --git a/code/frameworks/nextjs/src/preset.ts b/code/frameworks/nextjs/src/preset.ts index f29290209281..c12ed31877dd 100644 --- a/code/frameworks/nextjs/src/preset.ts +++ b/code/frameworks/nextjs/src/preset.ts @@ -11,12 +11,10 @@ import { configureStyledJsx } from './styledJsx/webpack'; import { configureImages } from './images/webpack'; import { configureRuntimeNextjsVersionResolution } from './utils'; import type { FrameworkOptions, StorybookConfig } from './types'; -import { configureNextImport } from './nextImport/webpack'; import TransformFontImports from './font/babel'; import { configureNextFont } from './font/webpack/configureNextFont'; import nextBabelPreset from './babel/preset'; import { configureNodePolyfills } from './nodePolyfills/webpack'; -import { configureAliasing } from './dependency-map'; import { configureSWCLoader } from './swc/loader'; export const addons: PresetProperty<'addons'> = [ @@ -142,9 +140,7 @@ export const webpackFinal: StorybookConfig['webpackFinal'] = async (baseConfig, configDir: options.configDir, }); - configureAliasing(baseConfig); configureNextFont(baseConfig, builder?.useSWC); - configureNextImport(baseConfig); configureRuntimeNextjsVersionResolution(baseConfig); configureImports({ baseConfig, configDir: options.configDir }); configureCss(baseConfig, nextConfig); diff --git a/code/frameworks/nextjs/src/routing/app-router-provider-mock.tsx b/code/frameworks/nextjs/src/routing/app-router-provider-mock.tsx deleted file mode 100644 index 38682dbcdaa6..000000000000 --- a/code/frameworks/nextjs/src/routing/app-router-provider-mock.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; - -// The mock is used for Next.js < 13, where the AppRouterProvider doesn't exist -export const AppRouterProvider: React.FC = ({ children }) => { - return <>{children}; -}; diff --git a/code/frameworks/nextjs/src/routing/decorator.tsx b/code/frameworks/nextjs/src/routing/decorator.tsx index 28f227bd259c..939c3ed0114b 100644 --- a/code/frameworks/nextjs/src/routing/decorator.tsx +++ b/code/frameworks/nextjs/src/routing/decorator.tsx @@ -1,9 +1,7 @@ import * as React from 'react'; import type { Addon_StoryContext } from '@storybook/types'; import { action } from '@storybook/addon-actions'; -// @ts-expect-error Using absolute path import to 1) avoid prebundling and 2) being able to substitute the module for Next.js < 13 -// eslint-disable-next-line import/no-extraneous-dependencies -import { AppRouterProvider } from '@storybook/nextjs/dist/routing/app-router-provider'; +import { AppRouterProvider } from './app-router-provider'; import { PageRouterProvider } from './page-router-provider'; import type { RouteParams, NextAppDirectory } from './types'; diff --git a/code/frameworks/nextjs/src/styledJsx/decorator.tsx b/code/frameworks/nextjs/src/styledJsx/decorator.tsx index d358ecf55a15..5e18664c9659 100644 --- a/code/frameworks/nextjs/src/styledJsx/decorator.tsx +++ b/code/frameworks/nextjs/src/styledJsx/decorator.tsx @@ -1,14 +1,5 @@ import * as React from 'react'; - -let StyleRegistry: React.FC; - -try { - // next >= v12 - StyleRegistry = require('styled-jsx').StyleRegistry; -} catch { - // next < v12 - StyleRegistry = React.Fragment; -} +import { StyleRegistry } from 'styled-jsx'; export const StyledJsxDecorator = (Story: React.FC): React.ReactNode => ( diff --git a/code/frameworks/nextjs/src/styledJsx/webpack.ts b/code/frameworks/nextjs/src/styledJsx/webpack.ts index 7594159659a2..891947ba41d7 100644 --- a/code/frameworks/nextjs/src/styledJsx/webpack.ts +++ b/code/frameworks/nextjs/src/styledJsx/webpack.ts @@ -1,17 +1,6 @@ -import semver from 'semver'; import type { Configuration as WebpackConfig } from 'webpack'; -import { addScopedAlias, getNextjsVersion } from '../utils'; +import { addScopedAlias } from '../utils'; export const configureStyledJsx = (baseConfig: WebpackConfig): void => { - const version = getNextjsVersion(); - if (semver.gte(version, '12.0.0')) { - addScopedAlias(baseConfig, 'styled-jsx'); - } else { - addScopedAlias(baseConfig, 'styled-jsx/babel'); - addScopedAlias(baseConfig, 'styled-jsx/css'); - addScopedAlias(baseConfig, 'styled-jsx/macro'); - addScopedAlias(baseConfig, 'styled-jsx/server'); - addScopedAlias(baseConfig, 'styled-jsx/style'); - addScopedAlias(baseConfig, 'styled-jsx/webpack'); - } + addScopedAlias(baseConfig, 'styled-jsx'); }; diff --git a/code/frameworks/nextjs/template/stories_nextjs-12-js/ImageFuture.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-12-js/ImageFuture.stories.jsx deleted file mode 100644 index aad2e8d56ac9..000000000000 --- a/code/frameworks/nextjs/template/stories_nextjs-12-js/ImageFuture.stories.jsx +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import Image from 'next/future/image'; - -import Accessibility from '../../assets/accessibility.svg'; - -export default { - component: Image, - args: { - src: Accessibility, - alt: 'Accessibility', - }, -}; - -export const Default = {}; - -export const BlurredPlaceholder = { - args: { - placeholder: 'blur', - }, -}; - -export const BlurredAbsolutePlaceholder = { - args: { - src: 'https://storybook.js.org/images/placeholders/50x50.png', - width: 50, - height: 50, - blurDataURL: - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABP5JREFUWEeNlwtz2zgMhEGKsv/k9XFp82xe11763yOJVGcXC4m2czM3GYa0E2s/LACSTi+vv1czM/7CvPpqxY/ejPeS3khmFiPHOiVLHKaZi4ux4j18GpMlS6cALupEQBCKQM4BdnGzjIcJgs//QBxAPQAem55f3yL4PWJIdyCyhlMfPdYZot0cwj3Ayg/5JwHA13paen7pADphxr/n5VI8JQsHCCGQ3gVGLLsxQ3h/LYSn5383B05rwNOws3Z576LOTOduvwfrOd5FtVat4akx0uPTrw8BNuUz23vLsY7hmg7i4ipqM2saiAdruNuirh4ff0bNdb3Qy3vkvfAQwrkHoDxTTZtDCOKrC1bMEkdnsQh/PLyetOGHkXeRAgQAQ84efQcBdUhvFofoulpdm9WGGTA+AJEe7l+i37a2c371tCFKs5zzJjxQNBMi1im7OCudP2aNghJuzZaGdSMEZjpwf/t0UgNdg9DOyLGLnY0BUHlzwVtNDkgEQhBeKkb1tUDgQrq7frwAiIJi5BKAeIFgHk5mOpPzvgltOfcoK0Rrs7lWHwsgqtXarK3N0u23h5Ne8+3Cqxn5RYSMfHCAMgDAx4CBWlA9RAGw0GA/ol0gvFB4WjAvBAFUa83SzdUdAbYMqp28uHpxCRefxwAYhksAFBlthxCiXig+zT4TYqkC+Hq7OdAfJv8lPpZiZShWBBIuRP+jspDb2lwcDkzz7OLzbO/zvAHAoXTz5eYMQL0t2yHAiCFcfPY1QDwNFylA5bPoFpsV9fsEiMl8dhcc4PP1CYD3drYcBYdIKQrx0cbRxd2JHSDcQ297/vvoZ5smRC+AyV2AQ+nm03evge08Tyy4jGqXzWWEoIvTgXHU38pWiNgH4ixB/ukAcy/xycXfp4kwdAAAt399W+OCgMjxILQacxvRQ3gEwHgKUIr/rz53CuDFNyP/Eob4+/vEWkBq6AAA/HIi62n/Lk67Q7wDYQ0UpQB7hc54T4E6gACLTYxeAwB0YKZL6U4ATEGIBwCs7qPfQJCCHkCnoK50noJKcXcAojsEAJZZKXhgCoziGKxqWV8IMNp4kP2aC+oB0TMFvhGxDQHQfIPhDrilwKOm/YCZASAHfgBABQjr3f7CyAkA0cPB03AQULRhKd4xAIjzHymo2Gp7gN0FAMAVOoA2fPz03a9ssh/RM7Iz8QKIzYF9HyB0XEZ1xJ4DzNoDOAfAslhDDTyjDfv8A2AcBeCiu/jBHQEgxnYW6Kp6BlCVAkQM8VnieF2Xyr0ivXy+XvsCzKOihwNHCCryw8HrQXVB8dgFeRfAVQiXjMbIIgXINQYB2H7Kf5wF/2Ar7h0AgKKGuAP4zOjhzlkLbpcRXKRZhNUjxG6HIQDOjN47gCn4+fWW3xVS9urPESEEwwHMo9IhAGxS2ISiA1iEnQOoA4hXRAwItp7WzL9Ow18ESJaw/ar4NgeOR49cAHCAnaH8swBhv+6CBGjeBSxEOUAI7HyKHkD4O9xKb3/feQouAI4uLBciHRRHmgbfA7h/xFc9AngNBADthvii1sMOiPwDAFeyt6s7FSFS4PmnA1v0vQvqDqQKAAPE/weAUuEgsj8c+H11Twdw/AKANXA82EDr5cJBEEzB3oI4Mb0AdR3nNw8vQnegWuvqAABwJFJEBwDgNdA7IOs3gL0LhuJdwBY8c4BfNnDdVgooHiOqn/b7JoSW/QODjTHXhU7hMQAAAABJRU5ErkJggg==', - placeholder: 'blur', - }, - parameters: { - // ignoring in Chromatic to avoid inconsistent snapshots - // given that the switch from blur to image is quite fast - chromatic: { disableSnapshot: true }, - }, -}; - -export const FilledParent = { - args: { - fill: true, - }, - decorator: [ - (Story) =>
{Story()}
, - ], -}; - -export const Sized = { - args: { - fill: true, - sizes: '(max-width: 600px) 100vw, 600px', - decorator: [ - (Story) =>
{Story()}
, - ], - }, -}; diff --git a/code/frameworks/nextjs/template/stories_nextjs-12-js/Link.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-12-js/Link.stories.jsx deleted file mode 100644 index 40631d5cf2f7..000000000000 --- a/code/frameworks/nextjs/template/stories_nextjs-12-js/Link.stories.jsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import Link from 'next/link'; - -const Component = () => ( - -); - -export default { - component: Component, -}; - -export const Default = {}; From 842db03286b28f6a0c7f49850ad7d6d0d4b23096 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 4 Dec 2023 10:48:49 +0100 Subject: [PATCH 2/7] Drop Next.js 12 sandbox and introduce Next.js 13 sandbox --- code/lib/cli/src/sandbox-templates.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index 86b28646fb10..8caf89fc8f3a 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -107,10 +107,10 @@ const baseTemplates = { builder: '@storybook/builder-webpack5', }, }, - 'nextjs/12-js': { - name: 'Next.js v12 (Webpack | JavaScript)', + 'nextjs/13-ts': { + name: 'Next.js v13.5 (Webpack | TypeScript)', script: - 'yarn create next-app {{beforeDir}} -e https://github.com/vercel/next.js/tree/next-12-3-2/examples/hello-world && cd {{beforeDir}} && npm pkg set "dependencies.next"="^12.2.0" && yarn && git add . && git commit --amend --no-edit && cd ..', + 'yarn create next-app {{beforeDir}} -e https://github.com/vercel/next.js/tree/next-13/examples/hello-world && cd {{beforeDir}} && npm pkg set "dependencies.next"="^12.2.0" && yarn && git add . && git commit --amend --no-edit && cd ..', expected: { framework: '@storybook/nextjs', renderer: '@storybook/react', From 6f805c329d8178a7f7bc2a5a14258a313b7b9158 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 4 Dec 2023 11:04:18 +0100 Subject: [PATCH 3/7] Update lock file --- code/yarn.lock | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/yarn.lock b/code/yarn.lock index 02c9286dcc9a..551e676483a2 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6002,14 +6002,11 @@ __metadata: typescript: "npm:^5.3.2" webpack: "npm:^5.65.0" peerDependencies: - "@next/font": ^13.0.0|| ^14.0.0 - next: ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 + next: ^13.5.0 || ^14.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 webpack: ^5.0.0 peerDependenciesMeta: - "@next/font": - optional: true typescript: optional: true webpack: From 4bc60185eb6997d7485ade32f6b39aeb06f1b190 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 4 Dec 2023 12:38:31 +0100 Subject: [PATCH 4/7] Fix Migration document --- MIGRATION.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 90ed8504d39e..ae382420f682 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -12,14 +12,13 @@ - [React-docgen component analysis by default](#react-docgen-component-analysis-by-default) - [Framework-specific changes](#framework-specific-changes) - [Angular: Drop support for Angular \< 15](#angular-drop-support-for-angular--15) + - [Next.js: Drop support for version \< 13.5](#nextjs-drop-support-for-version--135) - [From version 7.5.0 to 7.6.0](#from-version-750-to-760) - [CommonJS with Vite is deprecated](#commonjs-with-vite-is-deprecated) - [Using implicit actions during rendering is deprecated](#using-implicit-actions-during-rendering-is-deprecated) - [typescript.skipBabel deprecated](#typescriptskipbabel-deprecated) - [Primary doc block accepts of prop](#primary-doc-block-accepts-of-prop) - [Addons no longer need a peer dependency on React](#addons-no-longer-need-a-peer-dependency-on-react) - - [Framework-specific changes](#framework-specific-changes) - - [Next.js: Drop support for Angular \< 13.5](#nextjs-drop-support-for-angular--135) - [From version 7.4.0 to 7.5.0](#from-version-740-to-750) - [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated) - [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers) @@ -470,6 +469,10 @@ For more information see: https://storybook.js.org/docs/react/api/main-config-ty Starting in 8.0, we drop support for Angular < 15 +#### Next.js: Drop support for version \< 13.5 + +Starting in 8.0, we drop support for Next.js < 13.5. + ## From version 7.5.0 to 7.6.0 #### CommonJS with Vite is deprecated @@ -558,12 +561,6 @@ const allGlobalPackages = [...globalManagerPackages, ...globalPreviewPackages]; We recommend checking out [the updates we've made to the addon-kit](https://github.com/storybookjs/addon-kit/pull/60/files#diff-8fed899bdbc24789a7bb4973574e624ed6207c6ce572338bc3c3e117672b2a20), that can serve as a base for the changes you can do in your own addon. These changes are not necessary for your addon to keep working, but they will remove the need for your users to unnecessary install `react` and `react-dom` to their projects, and they'll significantly reduce the install size of your addon. These changes should not be breaking for your users, unless you support Storybook pre-v7. -### Framework-specific changes - -#### Next.js: Drop support for Angular \< 13.5 - -Starting in 8.0, we drop support for Next.js < 13.5. - ## From version 7.4.0 to 7.5.0 #### `storyStoreV6` and `storiesOf` is deprecated From 597ccec1235c8e4d6004a35e00d3155b3aa8b219 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 5 Dec 2023 10:33:24 +0100 Subject: [PATCH 5/7] Fix sandbox usage of Next.js 13 --- code/lib/cli/src/sandbox-templates.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index 8caf89fc8f3a..7dd785f3f67a 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -599,7 +599,7 @@ export const daily: TemplateKey[] = [ 'lit-vite/default-js', 'svelte-kit/skeleton-js', 'svelte-vite/default-js', - 'nextjs/12-js', + 'nextjs/13-ts', 'nextjs/default-js', 'nextjs/prerelease', 'qwik-vite/default-ts', From a0baf400f6ce1b7a88187f391a3d8d1f59e0f66a Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 5 Dec 2023 10:47:05 +0100 Subject: [PATCH 6/7] Next.js: Set Next.js 13 sandbox to inDevelopment=true --- code/lib/cli/src/sandbox-templates.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index 7dd785f3f67a..24fb3dc9846f 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -117,6 +117,7 @@ const baseTemplates = { builder: '@storybook/builder-webpack5', }, skipTasks: ['e2e-tests-dev', 'bench'], + inDevelopment: true, }, 'nextjs/default-js': { name: 'Next.js Latest (Webpack | JavaScript)', From 33aa426d264d8e2c66ca78e1ed3c2c1e407e5085 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 5 Dec 2023 11:13:48 +0100 Subject: [PATCH 7/7] Fix parallelism config for CircleCI --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6db12bf41959..dac362b5530b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -614,22 +614,22 @@ workflows: requires: - build - create-sandboxes: - parallelism: 36 + parallelism: 35 requires: - build # - smoke-test-sandboxes: # disabled for now # requires: # - create-sandboxes - build-sandboxes: - parallelism: 36 + parallelism: 35 requires: - create-sandboxes - chromatic-sandboxes: - parallelism: 33 + parallelism: 32 requires: - build-sandboxes - e2e-production: - parallelism: 31 + parallelism: 30 requires: - build-sandboxes - e2e-dev: @@ -637,7 +637,7 @@ workflows: requires: - create-sandboxes - test-runner-production: - parallelism: 31 + parallelism: 30 requires: - build-sandboxes # TODO: reenable once we find out the source of flakyness