Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release: Prerelease 8.5.0-beta.5 #30124

Open
wants to merge 25 commits into
base: next-release
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
13e3869
React: Use Act wrapper in Storybook for component rendering
valentinpalkovic Dec 12, 2024
5a278d5
Merge remote-tracking branch 'origin/next' into valentin/act-wrapping…
valentinpalkovic Dec 13, 2024
9ea0238
Update act implementation for production environment and adjust NODE_…
valentinpalkovic Dec 13, 2024
126f504
Merge remote-tracking branch 'origin/next' into valentin/act-wrapping…
valentinpalkovic Dec 14, 2024
a52aec2
Apply NODE_ENV development for react-based projects
valentinpalkovic Dec 14, 2024
3aca753
Merge branch 'next' into valentin/act-wrapping-of-components
valentinpalkovic Dec 16, 2024
4bfde81
fix node-logger ESM export
JReinhold Dec 17, 2024
684b18f
Merge branch 'next' into jeppe/fix-node-logger
JReinhold Dec 18, 2024
d59d47b
Merge branch 'next' into valentin/act-wrapping-of-components
valentinpalkovic Dec 18, 2024
8719f06
Switch orders of stories
valentinpalkovic Dec 18, 2024
3a65dab
Merge remote-tracking branch 'origin/next' into valentin/act-wrapping…
valentinpalkovic Dec 18, 2024
4bf0f02
Add developmentModeForBuild feature and update NODE_ENV handling
valentinpalkovic Dec 18, 2024
2653516
Fix develop mode handling
valentinpalkovic Dec 19, 2024
45971d9
Refactor development mode handling in Vite build configuration
valentinpalkovic Dec 19, 2024
4f0864d
Merge remote-tracking branch 'origin/next' into valentin/act-wrapping…
valentinpalkovic Dec 20, 2024
037e928
Merge branch 'next' into valentin/act-wrapping-of-components
valentinpalkovic Dec 20, 2024
0203747
Add documentation
valentinpalkovic Dec 20, 2024
9e94c25
Refactor Button and Header components to use not use React's defaultP…
valentinpalkovic Dec 20, 2024
7a5ca27
Clarify ts-expect-error comment in webpack preset configuration
valentinpalkovic Dec 20, 2024
4d708a0
Add conditional plugin configuration for development mode in webpack …
valentinpalkovic Dec 20, 2024
d7b2b34
Update docs/writing-tests/accessibility-testing.mdx
valentinpalkovic Dec 21, 2024
b0737e7
Update docs/api/main-config/main-config-features.mdx
valentinpalkovic Dec 21, 2024
c706998
Merge pull request #30037 from storybookjs/valentin/act-wrapping-of-c…
valentinpalkovic Dec 22, 2024
f4e6a50
Merge pull request #30093 from storybookjs/jeppe/fix-node-logger
JReinhold Dec 22, 2024
421fa8e
Write changelog for 8.5.0-beta.5 [skip ci]
storybook-bot Dec 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 8.5.0-beta.5

- Core: Fix `ERR_PACKAGE_PATH_NOT_EXPORTED` in `@storybook/node-logger` - [#30093](https://github.com/storybookjs/storybook/pull/30093), thanks @JReinhold!
- React: Use Act wrapper in Storybook for component rendering - [#30037](https://github.com/storybookjs/storybook/pull/30037), thanks @valentinpalkovic!

## 8.5.0-beta.4

- Addon Themes: Deprecate useThemeParameters - [#30111](https://github.com/storybookjs/storybook/pull/30111), thanks @yannbf!
Expand Down
40 changes: 28 additions & 12 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<h1>Migration</h1>

- [From version 8.4.x to 8.5.x](#from-version-84x-to-85x)
- [Introducing features.developmentModeForBuild](#introducing-featuresdevelopmentmodeforbuild)
- [Added source code panel to docs](#added-source-code-panel-to-docs)
- [Addon-a11y: Component test integration](#addon-a11y-component-test-integration)
- [Addon-a11y: Deprecated `parameters.a11y.manual`](#addon-a11y-deprecated-parametersa11ymanual)
Expand Down Expand Up @@ -110,17 +111,17 @@
- [Tab addons cannot manually route, Tool addons can filter their visibility via tabId](#tab-addons-cannot-manually-route-tool-addons-can-filter-their-visibility-via-tabid)
- [Removed `config` preset](#removed-config-preset-1)
- [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)
- [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)
- [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)
- [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated)
- [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers)
- [From version 7.0.0 to 7.2.0](#from-version-700-to-720)
- [Addon API is more type-strict](#addon-api-is-more-type-strict)
- [Addon-controls hideNoControlsWarning parameter is deprecated](#addon-controls-hidenocontrolswarning-parameter-is-deprecated)
- [Addon API is more type-strict](#addon-api-is-more-type-strict)
- [Addon-controls hideNoControlsWarning parameter is deprecated](#addon-controls-hidenocontrolswarning-parameter-is-deprecated)
- [From version 6.5.x to 7.0.0](#from-version-65x-to-700)
- [7.0 breaking changes](#70-breaking-changes)
- [Dropped support for Node 15 and below](#dropped-support-for-node-15-and-below)
Expand All @@ -146,7 +147,7 @@
- [Deploying build artifacts](#deploying-build-artifacts)
- [Dropped support for file URLs](#dropped-support-for-file-urls)
- [Serving with nginx](#serving-with-nginx)
- [Ignore story files from node\_modules](#ignore-story-files-from-node_modules)
- [Ignore story files from node_modules](#ignore-story-files-from-node_modules)
- [7.0 Core changes](#70-core-changes)
- [7.0 feature flags removed](#70-feature-flags-removed)
- [Story context is prepared before for supporting fine grained updates](#story-context-is-prepared-before-for-supporting-fine-grained-updates)
Expand All @@ -160,7 +161,7 @@
- [Addon-interactions: Interactions debugger is now default](#addon-interactions-interactions-debugger-is-now-default)
- [7.0 Vite changes](#70-vite-changes)
- [Vite builder uses Vite config automatically](#vite-builder-uses-vite-config-automatically)
- [Vite cache moved to node\_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook)
- [Vite cache moved to node_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook)
- [7.0 Webpack changes](#70-webpack-changes)
- [Webpack4 support discontinued](#webpack4-support-discontinued)
- [Babel mode v7 exclusively](#babel-mode-v7-exclusively)
Expand Down Expand Up @@ -211,7 +212,7 @@
- [Dropped addon-docs manual babel configuration](#dropped-addon-docs-manual-babel-configuration)
- [Dropped addon-docs manual configuration](#dropped-addon-docs-manual-configuration)
- [Autoplay in docs](#autoplay-in-docs)
- [Removed STORYBOOK\_REACT\_CLASSES global](#removed-storybook_react_classes-global)
- [Removed STORYBOOK_REACT_CLASSES global](#removed-storybook_react_classes-global)
- [7.0 Deprecations and default changes](#70-deprecations-and-default-changes)
- [storyStoreV7 enabled by default](#storystorev7-enabled-by-default)
- [`Story` type deprecated](#story-type-deprecated)
Expand Down Expand Up @@ -426,6 +427,21 @@

## From version 8.4.x to 8.5.x

### Introducing features.developmentModeForBuild

As part of our ongoing efforts to improve the testability and debuggability of Storybook, we are introducing a new feature flag: `developmentModeForBuild`. This feature flag allows you to set `process.env.NODE_ENV` to `development` in built Storybooks, enabling development-related optimizations that are typically disabled in production builds.

In development mode, React and other libraries often include additional checks and warnings that help catch potential issues early. These checks are usually stripped out in production builds to optimize performance. However, when running tests or debugging issues in a built Storybook, having these additional checks can be incredibly valuable. One such feature is React's `act`, which ensures that all updates related to a test are processed and applied before making assertions. `act` is crucial for reliable and predictable test results, but it only works correctly when `NODE_ENV` is set to `development`.

```js
// main.js
export default {
features: {
developmentModeForBuild: true,
},
};
```

### Added source code panel to docs

Starting in 8.5, Storybook Docs (`@storybook/addon-docs`) automatically adds a new addon panel to stories that displays a source snippet beneath each story. This works similarly to the existing [source snippet doc block](https://storybook.js.org/docs/writing-docs/doc-blocks#source), but in the story view. It is intended to replace the [Storysource addon](https://storybook.js.org/addons/@storybook/addon-storysource).
Expand Down
1 change: 1 addition & 0 deletions code/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ const config: StorybookConfig = {
features: {
viewportStoryGlobals: true,
backgroundsStoryGlobals: true,
developmentModeForBuild: true,
},
viteFinal: async (viteConfig, { configType }) => {
const { mergeConfig } = await import('vite');
Expand Down
17 changes: 15 additions & 2 deletions code/builders/builder-vite/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,22 @@ export async function build(options: Options) {
}
: {}),
},
}).build;
} as InlineConfig).build;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Missing type assertion on config.build assignment could cause type errors


const finalConfig = await presets.apply('viteFinal', config, options);
const finalConfig = (await presets.apply('viteFinal', config, options)) as InlineConfig;

if (options.features?.developmentModeForBuild) {
finalConfig.plugins?.push({
name: 'storybook:define-env',
config: () => {
return {
define: {
'process.env.NODE_ENV': JSON.stringify('development'),
},
};
},
});
}

const turbosnapPluginName = 'rollup-plugin-turbosnap';
const hasTurbosnapPlugin =
Expand Down
2 changes: 0 additions & 2 deletions code/builders/builder-vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { readFile } from 'node:fs/promises';
import { NoStatsForViteDevError } from 'storybook/internal/server-errors';
import type { Middleware, Options } from 'storybook/internal/types';

import sirv from 'sirv';
import { corePath } from 'storybook/core-path';
import type { ViteDevServer } from 'vite';

import { build as viteBuild } from './build';
Expand Down
8 changes: 5 additions & 3 deletions code/builders/builder-webpack5/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import prettyTime from 'pretty-hrtime';
import sirv from 'sirv';
import { corePath } from 'storybook/core-path';
import type { Configuration, Stats, StatsOptions } from 'webpack';
import webpack, { ProgressPlugin } from 'webpack';
import webpackDep, { DefinePlugin, ProgressPlugin } from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';

export * from './types';
export * from './preview/virtual-module-mapping';

export const WebpackDefinePlugin = DefinePlugin;

export const printDuration = (startTime: [number, number]) =>
prettyTime(process.hrtime(startTime))
.replace(' ms', ' milliseconds')
Expand Down Expand Up @@ -51,8 +53,8 @@ export const executor = {
get: async (options: Options) => {
const version = ((await options.presets.apply('webpackVersion')) || '5') as string;
const webpackInstance =
(await options.presets.apply<{ default: typeof webpack }>('webpackInstance'))?.default ||
webpack;
(await options.presets.apply<{ default: typeof webpackDep }>('webpackInstance'))?.default ||
webpackDep;
checkWebpackVersion({ version }, '5', 'builder-webpack5');
return webpackInstance;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ export default async (
}),
new DefinePlugin({
...stringifyProcessEnvs(envs),
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
NODE_ENV: JSON.stringify(
features?.developmentModeForBuild && isProd ? 'development' : process.env.NODE_ENV
),
}),
new ProvidePlugin({ process: require.resolve('process/browser.js') }),
isProd ? null : new HotModuleReplacementPlugin(),
Expand Down
2 changes: 2 additions & 0 deletions code/core/src/types/modules/core-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ export interface StorybookConfigRaw {
viewportStoryGlobals?: boolean;
/** Use globals & globalTypes for configuring the backgrounds addon */
backgroundsStoryGlobals?: boolean;
/** Set NODE_ENV to development in built Storybooks for better testability and debuggability */
developmentModeForBuild?: boolean;
};

build?: TestBuildConfig;
Expand Down
64 changes: 32 additions & 32 deletions code/core/template/stories/rendering.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,38 @@ export const ForceRemount = {
tags: ['!test', '!vitest'],
};

let loadedLabel = 'Initial';

/**
* This story demonstrates what happens when rendering (loaders) have side effects, and can possibly
* interleave with each other Triggering multiple force remounts quickly should only result in a
* single remount in the end and the label should be 'Loaded. Click Me' at the end. If loaders are
* interleaving it would result in a label of 'Error: Interleaved loaders. Click Me' Similarly,
* changing args rapidly should only cause one rerender at a time, producing the same result.
*/
export const SlowLoader = {
parameters: {
chromatic: { disable: true },
},
loaders: [
async () => {
loadedLabel = 'Loading...';
await new Promise((resolve) => setTimeout(resolve, 1000));
loadedLabel = loadedLabel === 'Loading...' ? 'Loaded.' : 'Error: Interleaved loaders.';
return { label: loadedLabel };
},
],
decorators: [
(storyFn: any, context: any) =>
storyFn({
args: {
...context.args,
label: `${context.loaded.label} ${context.args.label}`,
},
}),
],
};

export const ChangeArgs = {
play: async ({ canvasElement, id }: PlayFunctionContext<any>) => {
const channel = globalThis.__STORYBOOK_ADDONS_CHANNEL__;
Expand Down Expand Up @@ -74,35 +106,3 @@ export const ChangeArgs = {
await expect(button).toHaveFocus();
},
};

let loadedLabel = 'Initial';

/**
* This story demonstrates what happens when rendering (loaders) have side effects, and can possibly
* interleave with each other Triggering multiple force remounts quickly should only result in a
* single remount in the end and the label should be 'Loaded. Click Me' at the end. If loaders are
* interleaving it would result in a label of 'Error: Interleaved loaders. Click Me' Similarly,
* changing args rapidly should only cause one rerender at a time, producing the same result.
*/
export const SlowLoader = {
parameters: {
chromatic: { disable: true },
},
loaders: [
async () => {
loadedLabel = 'Loading...';
await new Promise((resolve) => setTimeout(resolve, 1000));
loadedLabel = loadedLabel === 'Loading...' ? 'Loaded.' : 'Error: Interleaved loaders.';
return { label: loadedLabel };
},
],
decorators: [
(storyFn: any, context: any) =>
storyFn({
args: {
...context.args,
label: `${context.loaded.label} ${context.args.label}`,
},
}),
],
};
2 changes: 1 addition & 1 deletion code/deprecated/node-logger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"exports": {
".": {
"types": "./shim.d.ts",
"module": "./shim.mjs",
"import": "./shim.mjs",
"require": "./shim.js"
},
"./package.json": "./package.json"
Expand Down
15 changes: 14 additions & 1 deletion code/frameworks/react-webpack5/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { dirname, join } from 'node:path';

import type { PresetProperty } from 'storybook/internal/types';

import { WebpackDefinePlugin } from '@storybook/builder-webpack5';

import type { StorybookConfig } from './types';

const getAbsolutePath = <I extends string>(input: I): I =>
Expand All @@ -24,12 +26,23 @@ export const core: PresetProperty<'core'> = async (config, options) => {
};
};

export const webpack: StorybookConfig['webpack'] = async (config) => {
export const webpack: StorybookConfig['webpack'] = async (config, options) => {
config.resolve = config.resolve || {};

config.resolve.alias = {
...config.resolve?.alias,
'@storybook/react': getAbsolutePath('@storybook/react'),
};

if (options.features?.developmentModeForBuild) {
config.plugins = [
// @ts-expect-error Ignore this error, because in the `webpack` preset the user actually hasn't defined a config yet.
...config.plugins,
Comment on lines +39 to +40
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Spreading undefined plugins will cause runtime error if config.plugins is not initialized

new WebpackDefinePlugin({
NODE_ENV: JSON.stringify('development'),
}),
];
}

return config;
};
Loading
Loading