diff --git a/code/frameworks/nextjs/src/config/webpack.ts b/code/frameworks/nextjs/src/config/webpack.ts index 13c1a251cebe..f5e72bc360d8 100644 --- a/code/frameworks/nextjs/src/config/webpack.ts +++ b/code/frameworks/nextjs/src/config/webpack.ts @@ -5,6 +5,14 @@ import type { NextConfig } from 'next'; import { DefinePlugin } from 'webpack'; import { addScopedAlias, getNextjsVersion, resolveNextConfig } from '../utils'; +const tryResolve = (path: string) => { + try { + return require.resolve(path); + } catch (err) { + return false; + } +}; + export const configureConfig = async ({ baseConfig, nextConfigPath, @@ -17,8 +25,12 @@ export const configureConfig = async ({ const nextConfig = await resolveNextConfig({ baseConfig, nextConfigPath, configDir }); addScopedAlias(baseConfig, 'next/config'); - addScopedAlias(baseConfig, 'react', 'next/dist/compiled/react'); - addScopedAlias(baseConfig, 'react-dom', 'next/dist/compiled/react-dom'); + if (tryResolve('next/dist/compiled/react')) { + addScopedAlias(baseConfig, 'react', 'next/dist/compiled/react'); + } + if (tryResolve('next/dist/compiled/react-dom')) { + addScopedAlias(baseConfig, 'react-dom', 'next/dist/compiled/react-dom'); + } setupRuntimeConfig(baseConfig, nextConfig); return nextConfig; diff --git a/code/frameworks/nextjs/src/dependency-map.ts b/code/frameworks/nextjs/src/dependency-map.ts new file mode 100644 index 000000000000..70ad2ece94e0 --- /dev/null +++ b/code/frameworks/nextjs/src/dependency-map.ts @@ -0,0 +1,36 @@ +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': { + 'next/dist/shared/lib/router-context': 'next/dist/shared/lib/router-context', + }, + '>=13.5.0': { + 'next/dist/shared/lib/router-context': 'next/dist/shared/lib/router-context.shared-runtime', + 'next/dist/shared/lib/head-manager-context': + 'next/dist/shared/lib/head-manager-context.shared-runtime', + 'next/dist/shared/lib/app-router-context': + 'next/dist/shared/lib/app-router-context.shared-runtime', + 'next/dist/shared/lib/hooks-client-context': + 'next/dist/shared/lib/hooks-client-context.shared-runtime', + }, +}; + +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/preset.ts b/code/frameworks/nextjs/src/preset.ts index 4aa06d54c4d0..db1c276da9b4 100644 --- a/code/frameworks/nextjs/src/preset.ts +++ b/code/frameworks/nextjs/src/preset.ts @@ -7,7 +7,6 @@ import { getProjectRoot } from '@storybook/core-common'; import { configureConfig } from './config/webpack'; import { configureCss } from './css/webpack'; import { configureImports } from './imports/webpack'; -import { configureRouting } from './routing/webpack'; import { configureStyledJsx } from './styledJsx/webpack'; import { configureImages } from './images/webpack'; import { configureRuntimeNextjsVersionResolution } from './utils'; @@ -17,6 +16,7 @@ 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'; export const addons: PresetProperty<'addons', StorybookConfig> = [ dirname(require.resolve(join('@storybook/preset-react-webpack', 'package.json'))), @@ -143,13 +143,13 @@ export const webpackFinal: StorybookConfig['webpackFinal'] = async (baseConfig, configDir: options.configDir, }); + configureAliasing(baseConfig); configureNextFont(baseConfig); configureNextImport(baseConfig); configureRuntimeNextjsVersionResolution(baseConfig); configureImports({ baseConfig, configDir: options.configDir }); configureCss(baseConfig, nextConfig); configureImages(baseConfig, nextConfig); - configureRouting(baseConfig); configureStyledJsx(baseConfig); configureNodePolyfills(baseConfig); diff --git a/code/frameworks/nextjs/src/routing/webpack.tsx b/code/frameworks/nextjs/src/routing/webpack.tsx deleted file mode 100644 index c0d245219742..000000000000 --- a/code/frameworks/nextjs/src/routing/webpack.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import type { Configuration as WebpackConfig } from 'webpack'; -import semver from 'semver'; -import { addScopedAlias, getNextjsVersion } from '../utils'; - -export const configureRouting = (baseConfig: WebpackConfig): void => { - // here we resolve the router context path with the installed version of Next.js - const routerContextPath = getRouterContextPath(); - addScopedAlias(baseConfig, routerContextPath); -}; - -const getRouterContextPath = () => { - const version = getNextjsVersion(); - if (semver.gte(version, '11.1.0')) { - return 'next/dist/shared/lib/router-context'; - } - - return 'next/dist/next-server/lib/router-context'; -};