Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b3ec0ae
Update addon migration guide link
yannbf Oct 28, 2025
6dc1b36
Merge branch 'next' into yann/update-addon-kit-docs
jonniebigodes Oct 28, 2025
8c504ca
Merge pull request #32870 from storybookjs/yann/update-addon-kit-docs
jonniebigodes Oct 28, 2025
b773208
Update preset exports to use 'dist' directory and fix loader referenc…
ndelangen Oct 29, 2025
3e593a8
Merge pull request #32875 from storybookjs/norbert/fix-presets-after-…
ndelangen Oct 29, 2025
755c8b0
Upgrade @chromatic-com/storybook to version 4.1.2 in package.json and…
ndelangen Oct 29, 2025
9d7469b
Upgrade @storybook/addon-designs to version 11.0.1 in package.json an…
ndelangen Oct 29, 2025
6d8af15
Merge pull request #32877 from storybookjs/norbert/bump-vta
ndelangen Oct 29, 2025
b2763dc
Update CHANGELOG.md for v10.0.1 [skip ci]
storybook-bot Oct 29, 2025
d1b825a
Update optimizeViteDeps to include '@storybook/addon-docs > @mdx-js/r…
ndelangen Oct 29, 2025
b416cd9
Fix codemod glob string formatting in csf-factories.ts
yannbf Oct 29, 2025
a201601
Do not filter manually added optimizeDeps include entries
ndelangen Oct 29, 2025
6d82c5d
Merge branch 'next' into norbert/improve-optimizedeps-array
ndelangen Oct 29, 2025
399d680
Add TODO comment to rework getOptimizeDeps function due to outdated code
ndelangen Oct 29, 2025
02609c1
Merge branch 'norbert/improve-optimizedeps-array' of github.com:story…
ndelangen Oct 29, 2025
1342fd5
Merge pull request #32880 from storybookjs/yann/fix-csf-factories-pre…
yannbf Oct 29, 2025
b3d0932
Merge pull request #32881 from storybookjs/norbert/improve-optimizede…
ndelangen Oct 29, 2025
331baf0
Refactor imports in core server and webpack builder to use 'pathe' in…
yannbf Oct 30, 2025
86ba4ac
fix test for windows
ndelangen Oct 30, 2025
1b61b21
make favicon test OS agnostic
yannbf Oct 30, 2025
dd000a8
Merge pull request #32893 from storybookjs/yann/fix-preset-path-joini…
ndelangen Oct 30, 2025
b1b4106
Docs: Fix Vitest option instructions
valentinpalkovic Oct 30, 2025
86fd92c
Update CHANGELOG.md for v10.0.2 [skip ci]
storybook-bot Oct 30, 2025
b512412
Merge branch 'next' into valentin/fix-vitest-documentation
jonniebigodes Oct 30, 2025
b079045
Merge pull request #32896 from storybookjs/valentin/fix-vitest-docume…
jonniebigodes Oct 30, 2025
b583ccc
Write changelog for 10.1.0-alpha.1 [skip ci]
storybook-bot Oct 30, 2025
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## 10.0.2

- CLI: Fix glob string formatting in csf-factories codemod - [#32880](https://github.com/storybookjs/storybook/pull/32880), thanks @yannbf!
- Core: Improve file path resolution on Windows - [#32893](https://github.com/storybookjs/storybook/pull/32893), thanks @yannbf!
- Vite: Update `optimizeViteDeps` for addon-docs and addon-vitest - [#32881](https://github.com/storybookjs/storybook/pull/32881), thanks @ndelangen!

## 10.0.1

- Presets: Fix incorrect imports - [#32875](https://github.com/storybookjs/storybook/pull/32875), thanks @ndelangen!
- Upgrade: Satellite compatible with 10.1 prerelease - [#32877](https://github.com/storybookjs/storybook/pull/32877), thanks @ndelangen!

## 10.0.0

Storybook 10 contains one breaking change: it’s ESM-only. This simplifies our distribution and reduces install size by 29% while simultaneously unminifying dist code for easier debugging.
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 10.1.0-alpha.1

- CLI: Fix glob string formatting in csf-factories codemod - [#32880](https://github.com/storybookjs/storybook/pull/32880), thanks @yannbf!
- Core: Improve file path resolution on Windows - [#32893](https://github.com/storybookjs/storybook/pull/32893), thanks @yannbf!
- Presets: Fix incorrect imports - [#32875](https://github.com/storybookjs/storybook/pull/32875), thanks @ndelangen!
- Vite: Update `optimizeViteDeps` for addon-docs and addon-vitest - [#32881](https://github.com/storybookjs/storybook/pull/32881), thanks @ndelangen!

## 10.1.0-alpha.0


Expand Down
3 changes: 1 addition & 2 deletions code/addons/docs/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,9 @@ export const resolvedReact = async (existing: any) => ({
});

const optimizeViteDeps = [
'@mdx-js/react',
'@storybook/addon-docs',
'@storybook/addon-docs/blocks',
'markdown-to-jsx',
'@storybook/addon-docs > @mdx-js/react',
];

export { webpackX as webpack, docsX as docs, optimizeViteDeps };
9 changes: 4 additions & 5 deletions code/builders/builder-vite/src/optimizeDeps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { listStories } from './list-stories';
const asyncFilter = async (arr: string[], predicate: (val: string) => Promise<boolean>) =>
Promise.all(arr.map(predicate)).then((results) => arr.filter((_v, index) => results[index]));

// TODO: This function should be reworked. The code it uses is outdated and we need to investigate
// More info: https://github.com/storybookjs/storybook/issues/32462#issuecomment-3421326557
export async function getOptimizeDeps(config: ViteInlineConfig, options: Options) {
const extraOptimizeDeps = await options.presets.apply('optimizeViteDeps', []);

Expand All @@ -27,18 +29,15 @@ export async function getOptimizeDeps(config: ViteInlineConfig, options: Options
// This function converts ids which might include ` > ` to a real path, if it exists on disk.
// See https://github.com/vitejs/vite/blob/67d164392e8e9081dc3f0338c4b4b8eea6c5f7da/packages/vite/src/node/optimizer/index.ts#L182-L199
const resolve = resolvedConfig.createResolver({ asSrc: false });
const include = await asyncFilter(
Array.from(new Set([...INCLUDE_CANDIDATES, ...extraOptimizeDeps])),
async (id) => Boolean(await resolve(id))
);
const include = await asyncFilter(INCLUDE_CANDIDATES, async (id) => Boolean(await resolve(id)));

const optimizeDeps: UserConfig['optimizeDeps'] = {
...config.optimizeDeps,
// We don't need to resolve the glob since vite supports globs for entries.
entries: stories,
// We need Vite to precompile these dependencies, because they contain non-ESM code that would break
// if we served it directly to the browser.
include: [...include, ...(config.optimizeDeps?.include || [])],
include: [...include, ...extraOptimizeDeps, ...(config.optimizeDeps?.include || [])],
};

return optimizeDeps;
Expand Down
2 changes: 1 addition & 1 deletion code/builders/builder-webpack5/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { cp } from 'node:fs/promises';
import { dirname, join, parse } from 'node:path';
import { fileURLToPath } from 'node:url';

import { PREVIEW_BUILDER_PROGRESS } from 'storybook/internal/core-events';
Expand All @@ -13,6 +12,7 @@ import type { Builder, Options } from 'storybook/internal/types';

import { checkWebpackVersion } from '@storybook/core-webpack';

import { dirname, join, parse } from 'pathe';
import prettyTime from 'pretty-hrtime';
import sirv from 'sirv';
import type { Configuration, Stats, StatsOptions } from 'webpack';
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/core-server/build-dev.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { readFile } from 'node:fs/promises';
import { join, relative, resolve } from 'node:path';

import {
JsPackageManagerFactory,
Expand All @@ -20,6 +19,7 @@ import type { BuilderOptions, CLIOptions, LoadOptions, Options } from 'storybook

import { global } from '@storybook/global';

import { join, relative, resolve } from 'pathe';
import prompts from 'prompts';
import invariant from 'tiny-invariant';
import { dedent } from 'ts-dedent';
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/core-server/build-static.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { cp, mkdir } from 'node:fs/promises';
import { rm } from 'node:fs/promises';
import { join, relative, resolve } from 'node:path';

import {
loadAllPresets,
Expand All @@ -15,6 +14,7 @@ import type { BuilderOptions, CLIOptions, LoadOptions, Options } from 'storybook

import { global } from '@storybook/global';

import { join, relative, resolve } from 'pathe';
import picocolors from 'picocolors';

import { resolvePackageDir } from '../shared/utils/module';
Expand Down
4 changes: 2 additions & 2 deletions code/core/src/core-server/load.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { join, relative, resolve } from 'node:path';

import {
getProjectRoot,
loadAllPresets,
Expand All @@ -12,6 +10,8 @@ import type { BuilderOptions, CLIOptions, LoadOptions, Options } from 'storybook

import { global } from '@storybook/global';

import { join, relative, resolve } from 'pathe';

import { resolvePackageDir } from '../shared/utils/module';

export async function loadStorybook(
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/core-server/presets/common-preset.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { existsSync } from 'node:fs';
import { readFile } from 'node:fs/promises';
import { isAbsolute, join } from 'node:path';
import { fileURLToPath } from 'node:url';

import type { Channel } from 'storybook/internal/channels';
Expand All @@ -26,6 +25,7 @@ import type {
PresetPropertyFn,
} from 'storybook/internal/types';

import { isAbsolute, join } from 'pathe';
import * as pathe from 'pathe';
import { dedent } from 'ts-dedent';

Expand Down
47 changes: 28 additions & 19 deletions code/core/src/core-server/presets/favicon.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import * as fs from 'node:fs';
import { dirname, join } from 'node:path';

import { expect, it, vi } from 'vitest';

import { logger } from 'storybook/internal/node-logger';

import { dirname, join, normalize } from 'pathe';

import * as m from './common-preset';

// mock src/core-server/utils/constants.ts:8:27
Expand Down Expand Up @@ -75,67 +76,73 @@ it('with no staticDirs favicon should return default', async () => {
it('with staticDirs referencing a favicon.ico directly should return the found favicon', async () => {
const location = 'favicon.ico';
existsSyncMock.mockImplementation((p) => {
return p === createPath(location);
return normalize(String(p)) === normalize(createPath(location));
});
statSyncMock.mockImplementation((p) => {
return {
isFile: () => p === createPath('favicon.ico'),
isFile: () => normalize(String(p)) === normalize(createPath('favicon.ico')),
} as any;
});
const options = createOptions([location]);

expect(await m.favicon(undefined, options)).toBe(createPath('favicon.ico'));
expect(normalize(await m.favicon(undefined, options))).toBe(normalize(createPath('favicon.ico')));
});

it('with staticDirs containing a single favicon.ico should return the found favicon', async () => {
const location = 'static';
existsSyncMock.mockImplementation((p) => {
if (p === createPath(location)) {
if (normalize(String(p)) === normalize(createPath(location))) {
return true;
}
if (p === createPath(location, 'favicon.ico')) {
if (normalize(String(p)) === normalize(createPath(location, 'favicon.ico'))) {
return true;
}
return false;
});
const options = createOptions([location]);

expect(await m.favicon(undefined, options)).toBe(createPath(location, 'favicon.ico'));
expect(normalize(await m.favicon(undefined, options))).toBe(
normalize(createPath(location, 'favicon.ico'))
);
});

it('with staticDirs containing a single favicon.svg should return the found favicon', async () => {
const location = 'static';
existsSyncMock.mockImplementation((p) => {
if (p === createPath(location)) {
if (normalize(String(p)) === normalize(createPath(location))) {
return true;
}
if (p === createPath(location, 'favicon.svg')) {
if (normalize(String(p)) === normalize(createPath(location, 'favicon.svg'))) {
return true;
}
return false;
});
const options = createOptions([location]);

expect(await m.favicon(undefined, options)).toBe(createPath(location, 'favicon.svg'));
expect(normalize(await m.favicon(undefined, options))).toBe(
normalize(createPath(location, 'favicon.svg'))
);
});

it('with staticDirs containing a multiple favicons should return the first favicon and warn', async () => {
const location = 'static';
existsSyncMock.mockImplementation((p) => {
if (p === createPath(location)) {
if (normalize(String(p)) === normalize(createPath(location))) {
return true;
}
if (p === createPath(location, 'favicon.ico')) {
if (normalize(String(p)) === normalize(createPath(location, 'favicon.ico'))) {
return true;
}
if (p === createPath(location, 'favicon.svg')) {
if (normalize(String(p)) === normalize(createPath(location, 'favicon.svg'))) {
return true;
}
return false;
});
const options = createOptions([location]);

expect(await m.favicon(undefined, options)).toBe(createPath(location, 'favicon.svg'));
expect(normalize(await m.favicon(undefined, options))).toBe(
normalize(createPath(location, 'favicon.svg'))
);

expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('multiple favicons'));
});
Expand All @@ -144,23 +151,25 @@ it('with multiple staticDirs containing a multiple favicons should return the fi
const locationA = 'static-a';
const locationB = 'static-b';
existsSyncMock.mockImplementation((p) => {
if (p === createPath(locationA)) {
if (normalize(String(p)) === normalize(createPath(locationA))) {
return true;
}
if (p === createPath(locationB)) {
if (normalize(String(p)) === normalize(createPath(locationB))) {
return true;
}
if (p === createPath(locationA, 'favicon.ico')) {
if (normalize(String(p)) === normalize(createPath(locationA, 'favicon.ico'))) {
return true;
}
if (p === createPath(locationB, 'favicon.svg')) {
if (normalize(String(p)) === normalize(createPath(locationB, 'favicon.svg'))) {
return true;
}
return false;
});
const options = createOptions([locationA, locationB]);

expect(await m.favicon(undefined, options)).toBe(createPath(locationA, 'favicon.ico'));
expect(normalize(await m.favicon(undefined, options))).toBe(
normalize(createPath(locationA, 'favicon.ico'))
);

expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('multiple favicons'));
});
3 changes: 1 addition & 2 deletions code/lib/cli-storybook/src/codemod/csf-factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ async function runStoriesCodemod(options: {
command: packageManager.getRemoteRunCommand('storybook', [
'migrate',
'csf-2-to-3',
'--glob',
globString,
`--glob='${globString}'`,
]),
args: [],
stdio: 'ignore',
Expand Down
7 changes: 4 additions & 3 deletions code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@
"typescript": "^5.8.3"
},
"dependencies": {
"@chromatic-com/storybook": "^4.1.1",
"@chromatic-com/storybook": "^4.1.2",
"@nx/vite": "20.8.2",
"@nx/workspace": "20.8.2",
"@playwright/test": "1.52.0",
"@storybook/addon-a11y": "workspace:*",
"@storybook/addon-designs": "^11.0.0",
"@storybook/addon-designs": "^11.0.1",
"@storybook/addon-docs": "workspace:*",
"@storybook/addon-links": "workspace:*",
"@storybook/addon-onboarding": "workspace:*",
Expand Down Expand Up @@ -283,5 +283,6 @@
"Dependency Upgrades"
]
]
}
},
"deferredNextVersion": "10.1.0-alpha.1"
}
2 changes: 1 addition & 1 deletion code/presets/create-react-app/preset.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './src/index.js';
export * from './dist/index.js';
2 changes: 1 addition & 1 deletion code/presets/react-webpack/preset.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './src/index.js';
export * from './dist/index.js';
2 changes: 1 addition & 1 deletion code/presets/server-webpack/preset.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './src/index.js';
export * from './dist/index.js';
4 changes: 2 additions & 2 deletions code/presets/server-webpack/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ export const webpack: StorybookConfig['webpack'] = (config) => {
{
type: 'javascript/auto',
test: /\.stories\.json$/,
use: fileURLToPath(import.meta.resolve('@storybook/preset-server-webpack/webpack-loader')),
use: fileURLToPath(import.meta.resolve('@storybook/preset-server-webpack/loader')),
},

{
type: 'javascript/auto',
test: /\.stories\.ya?ml/,
use: [
fileURLToPath(import.meta.resolve('@storybook/preset-server-webpack/webpack-loader')),
fileURLToPath(import.meta.resolve('@storybook/preset-server-webpack/loader')),
{
loader: fileURLToPath(import.meta.resolve('yaml-loader')),
options: { asJSON: true },
Expand Down
Loading
Loading