Skip to content
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a064053
stop using serverRequire from storybook common, because it's about to…
ndelangen Jun 18, 2025
958c7be
Update Node.js version to 20.16.0 in .nvmrc and workflows; reintroduc…
ndelangen Jun 18, 2025
fd3c654
Refactor typecheck workflow and update test mocks to use local server…
ndelangen Jun 18, 2025
b6bd5f6
Add error handling to getTestRunnerConfig function
ndelangen Jun 18, 2025
2094e4b
Update tsup configuration to include Storybook dependencies and adjus…
ndelangen Jun 19, 2025
7fd5891
Add semver dependency to package.json and update yarn.lock
ndelangen Jun 19, 2025
f4b51e6
Remove console error logging from getTestRunnerConfig function
ndelangen Jun 19, 2025
49024ff
Enable treeshaking in tsup configuration for optimized builds
ndelangen Jun 19, 2025
de6531a
Update tsup configuration to exclude additional Storybook internal mo…
ndelangen Jun 19, 2025
d23885c
bundle in the whole core of storybook into the test-runner, since eve…
ndelangen Jun 24, 2025
2a1e346
Update GitHub Actions workflow to set NODE_ENV and increase memory li…
ndelangen Jun 24, 2025
8fcb31b
Refactor test commands in package.json and update GitHub Actions work…
ndelangen Jun 24, 2025
4da85c2
babel everything
ndelangen Jun 24, 2025
52a3bda
Merge pull request #570 from storybookjs/norbert/bundle-in-storybook
ndelangen Jun 24, 2025
9afc71c
Update package.json to include multiple authors for better collaboration
ndelangen Jun 24, 2025
6552af9
Update dependencies in package.json and yarn.lock, including the addi…
ndelangen Jun 24, 2025
d9d46ef
Enhance project structure by refactoring internal imports, adding new…
ndelangen Jun 24, 2025
020e626
Remove TypeScript error suppression in transformCsf and update test c…
ndelangen Jun 24, 2025
8609766
Update storybook-src dependency in package.json and yarn.lock to poin…
ndelangen Jul 7, 2025
f3d1819
Update Jest configuration to support ES2022 syntax by modifying the S…
ndelangen Jul 9, 2025
9fa10a3
bump to new non-version-bundled
ndelangen Jul 9, 2025
7e6c71c
fix tests
ndelangen Jul 9, 2025
db60cb3
Update storybook-src dependency in yarn.lock to point to the latest c…
ndelangen Jul 9, 2025
f437d4a
Update storybook version in package.json and yarn.lock to support 10.…
ndelangen Aug 20, 2025
5cf9d6b
Merge branch 'next' into norbert/asyng-serverRequire-alt
ndelangen Aug 20, 2025
dbc63e2
Update storybook and storybook-src dependencies in package.json and y…
ndelangen Aug 20, 2025
29f1ef4
Discard changes to tsconfig.json
ndelangen Aug 20, 2025
d0c3175
Discard changes to src/playwright/transformPlaywrightJson.ts
ndelangen Aug 20, 2025
2c9779a
Enable TypeScript declaration file generation in tsup.config.ts, upda…
ndelangen Sep 12, 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
19 changes: 4 additions & 15 deletions .babelrc.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
'@babel/preset-react',
],
presets: [['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript'],
env: {
esm: {
presets: [
[
'@babel/preset-env',
{
modules: false,
targets: { node: 'current' },
},
],
],
test: {
presets: ['@babel/preset-typescript'],
plugins: ['@babel/plugin-transform-modules-commonjs'],
},
},
};
2 changes: 1 addition & 1 deletion .github/workflows/tests-extended.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x, 22.x]
node-version: [20.16.0, 22.x]
steps:
- uses: actions/checkout@v4

Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]
node-version: [20.16.0]
steps:
- uses: actions/checkout@v4

Expand All @@ -19,17 +19,19 @@ jobs:
- name: Install dependencies
uses: bahmutov/npm-install@v1

- name: Run unit tests
- name: Build
run: |
yarn build

- name: Run unit tests
run: |
yarn test --coverage

- name: Install Playwright Browsers
run: npx playwright install --with-deps

- name: Run test runner
run: |
yarn build
yarn test-storybook:ci-coverage

- name: Generate code coverage
Expand Down
25 changes: 12 additions & 13 deletions .github/workflows/typecheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ name: Typecheck
on: [push, pull_request]

jobs:
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Use Node.js 20.x
uses: actions/setup-node@v1
with:
node-version: '20.x'
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version-file: .nvmrc

- name: Install dependencies
uses: bahmutov/npm-install@v1

- name: Type check
run: yarn tsc
- name: Install dependencies
uses: bahmutov/npm-install@v1

- name: Type check
run: yarn tsc
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18
v20.16.0
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module.exports = {
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.[t|j]sx?$': 'babel-jest',
},
Comment on lines +3 to +5
Copy link
Member Author

Choose a reason for hiding this comment

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

Is this "the recipe"? 🤔💭❗

moduleNameMapper: {
'@storybook/test-runner/playwright/global-setup': '<rootDir>/playwright/global-setup',
'@storybook/test-runner/playwright/global-teardown': '<rootDir>/playwright/global-teardown',
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
"@jest/types": "^29.6.3",
"@swc/core": "^1.5.22",
"@swc/jest": "^0.2.23",
"esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0",
Copy link
Member

Choose a reason for hiding this comment

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

This looks pretty annoying to keep up to date. Is the intention that each time esbuild releases a new version, this will be updated? Why not use >= 0.18.0?

Copy link
Member Author

Choose a reason for hiding this comment

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

You're right @IanVS

However the version range you mention promises to be compatible with "all future versions" of esbuild.

I think that's a promise that can't be kept.
And it locks libraries into a really bad spot.. if they release a new major version, they risk breaking the ecosystem.

Copy link
Member

Choose a reason for hiding this comment

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

That's fair. Though I think you can use 0.18 - 0.25 just to keep the list from becoming unmanageably long.

"esbuild-register": "^3.6.0",
"expect-playwright": "^0.8.0",
"jest": "^29.6.4",
"jest-circus": "^29.6.4",
Expand All @@ -68,7 +70,8 @@
"jest-serializer-html": "^7.1.0",
"jest-watch-typeahead": "^2.0.0",
"nyc": "^15.1.0",
"playwright": "^1.14.0"
"playwright": "^1.14.0",
"semver": "^7.6.2"
},
"devDependencies": {
"@auto-it/released": "^11.1.6",
Expand All @@ -81,7 +84,7 @@
"@storybook/addon-docs": "next",
"@storybook/react-vite": "next",
"@types/jest": "^29.0.0",
"@types/node": "^16.4.1",
"@types/node": "^20.0.0",
"@types/node-fetch": "^2.6.11",
"@vitejs/plugin-react": "^4.0.3",
"auto": "^11.1.6",
Expand All @@ -101,7 +104,7 @@
"react": "^17.0.1",
"react-dom": "^17.0.1",
"read-pkg-up": "^7.0.1",
"storybook": "next",
"storybook": "^0.0.0-0 || ^8.2.0 || ^9.0.0 || ^9.1.0-0",
"tempy": "^1.0.1",
"ts-dedent": "^2.0.0",
"ts-jest": "^29.0.0",
Expand Down
1 change: 0 additions & 1 deletion src/playwright/transformPlaywright.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import * as storybookMain from '../util/getStorybookMain';
import { transformPlaywright } from './transformPlaywright';

jest.mock('storybook/internal/common', () => ({
...jest.requireActual('storybook/internal/common'),
getProjectRoot: jest.fn(() => '/foo/bar'),
normalizeStories: jest.fn(() => [
{
Expand Down
2 changes: 1 addition & 1 deletion src/playwright/transformPlaywright.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { relative } from 'path';
import template from '@babel/template';
import { userOrAutoTitle } from 'storybook/internal/preview-api';
import dedent from 'ts-dedent';

import { getStorybookMetadata } from '../util';
import { transformCsf } from '../csf/transformCsf';
import type { TestPrefixer } from '../csf/transformCsf';
import { userOrAutoTitle } from '../util/autoTitle';

const coverageErrorMessage = dedent`
[Test runner] An error occurred when evaluating code coverage:
Expand Down
2 changes: 1 addition & 1 deletion src/test-storybook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import canBindToHost from 'can-bind-to-host';
import dedent from 'ts-dedent';
import path, { join, resolve } from 'path';
import tempy from 'tempy';
import { getInterpretedFile } from 'storybook/internal/common';
import { readConfig } from 'storybook/internal/csf-tools';
import { telemetry } from 'storybook/internal/telemetry';
import { glob } from 'glob';
Expand All @@ -17,6 +16,7 @@ import { getStorybookMetadata } from './util/getStorybookMetadata';
import { getTestRunnerConfig } from './util/getTestRunnerConfig';
import { transformPlaywrightJson } from './playwright/transformPlaywrightJson';
import { TestRunnerConfig } from './playwright/hooks';
import { getInterpretedFile } from './util/serverRequire';

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
Expand Down
98 changes: 98 additions & 0 deletions src/util/autoTitle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import type { NormalizedStoriesSpecifier } from 'storybook/internal/types';

import slash from 'slash';
import { dedent } from 'ts-dedent';

// FIXME: types duplicated type from `core-common', to be
// removed when we remove v6 back-compat.

// deal with files like "atoms/button/{button,index}.stories.js"
const sanitize = (parts: string[]) => {
if (parts.length === 0) {
return parts;
}

const last = parts[parts.length - 1];
const lastStripped = last?.replace(/(?:[.](?:story|stories))?([.][^.]+)$/i, '');

if (parts.length === 1) {
return [lastStripped];
}

const nextToLast = parts[parts.length - 2];
if (lastStripped && nextToLast && lastStripped.toLowerCase() === nextToLast.toLowerCase()) {
return [...parts.slice(0, -2), lastStripped];
}

return lastStripped &&
(/^(story|stories)([.][^.]+)$/i.test(last) || /^index$/i.test(lastStripped))
? parts.slice(0, -1)
: [...parts.slice(0, -1), lastStripped];
};

/**
* Combines path parts together, without duplicating separators (slashes). Used instead of
* `path.join` because this code runs in the browser.
*
* @param paths Array of paths to join together.
* @returns Joined path string, with single '/' between parts
*/
function pathJoin(paths: string[]): string {
return paths
.flatMap((p) => p.split('/'))
.filter(Boolean)
.join('/');
}

export const userOrAutoTitleFromSpecifier = (
fileName: string | number,
entry: NormalizedStoriesSpecifier,
userTitle?: string
) => {
const { directory, importPathMatcher, titlePrefix = '' } = entry || {};
// On Windows, backslashes are used in paths, which can cause problems here
// slash makes sure we always handle paths with unix-style forward slash

if (typeof fileName === 'number') {
console.warn(dedent`
CSF Auto-title received a numeric fileName. This typically happens when
webpack is mis-configured in production mode. To force webpack to produce
filenames, set optimization.moduleIds = "named" in your webpack config.
`);
}

const normalizedFileName = slash(String(fileName));

if (importPathMatcher.exec(normalizedFileName)) {
if (!userTitle) {
const suffix = normalizedFileName.replace(directory, '');
let parts = pathJoin([titlePrefix, suffix]).split('/');
parts = sanitize(parts);
return parts.join('/');
}

if (!titlePrefix) {
return userTitle;
}

return pathJoin([titlePrefix, userTitle]);
}

return undefined;
};

export const userOrAutoTitle = (
fileName: string,
storiesEntries: NormalizedStoriesSpecifier[],
userTitle?: string
) => {
for (let i = 0; i < storiesEntries.length; i += 1) {
const title = userOrAutoTitleFromSpecifier(fileName, storiesEntries[i], userTitle);

if (title) {
return title;
}
}

return userTitle || undefined;
};
4 changes: 2 additions & 2 deletions src/util/getStorybookMain.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getStorybookMain, resetStorybookMainCache, storybookMainConfig } from './getStorybookMain';
import * as coreCommon from 'storybook/internal/common';
import * as coreCommon from './serverRequire';

jest.mock('storybook/internal/common');
jest.mock('./serverRequire');

describe('getStorybookMain', () => {
beforeEach(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/util/getStorybookMain.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { join, resolve } from 'path';
import { serverRequire } from 'storybook/internal/common';
import type { StorybookConfig } from 'storybook/internal/types';
import dedent from 'ts-dedent';
import { serverRequire } from './serverRequire';

export const storybookMainConfig = new Map<string, StorybookConfig>();

Expand Down
1 change: 0 additions & 1 deletion src/util/getStorybookMetadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as storybookMain from './getStorybookMain';
import { getStorybookMetadata } from './getStorybookMetadata';

jest.mock('storybook/internal/common', () => ({
...jest.requireActual('storybook/internal/common'),
getProjectRoot: jest.fn(() => '/foo/bar'),
normalizeStories: jest.fn(() => [
{
Expand Down
2 changes: 1 addition & 1 deletion src/util/getStorybookMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { join } from 'path';
import { normalizeStories, getProjectRoot } from 'storybook/internal/common';
import { StoriesEntry } from 'storybook/internal/types';
import type { StoriesEntry } from 'storybook/internal/types';

import { getStorybookMain } from './getStorybookMain';

Expand Down
12 changes: 4 additions & 8 deletions src/util/getTestRunnerConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const testRunnerConfig: TestRunnerConfig = {
},
};

jest.mock('storybook/internal/common', () => ({
jest.mock('./serverRequire', () => ({
serverRequire: jest.fn(),
}));

Expand All @@ -37,23 +37,19 @@ describe('getTestRunnerConfig', () => {

it('should load the test runner config', () => {
const configDir = '.storybook';
(require('storybook/internal/common').serverRequire as jest.Mock).mockReturnValueOnce(
testRunnerConfig
);
(require('./serverRequire').serverRequire as jest.Mock).mockReturnValueOnce(testRunnerConfig);

const result = getTestRunnerConfig(configDir);

expect(result).toEqual(testRunnerConfig);
expect(require('storybook/internal/common').serverRequire).toHaveBeenCalledWith(
expect(require('./serverRequire').serverRequire).toHaveBeenCalledWith(
join(resolve('.storybook', 'test-runner'))
);
});

it('should cache the test runner config', () => {
const configDir = '.storybook';
(require('storybook/internal/common').serverRequire as jest.Mock).mockReturnValueOnce(
testRunnerConfig
);
(require('./serverRequire').serverRequire as jest.Mock).mockReturnValueOnce(testRunnerConfig);

const result1 = getTestRunnerConfig(configDir);
const result2 = getTestRunnerConfig(configDir);
Expand Down
16 changes: 10 additions & 6 deletions src/util/getTestRunnerConfig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { join, resolve } from 'path';
import { serverRequire } from 'storybook/internal/common';
import { TestRunnerConfig } from '../playwright/hooks';
import { join, resolve } from 'node:path';
import type { TestRunnerConfig } from '../playwright/hooks';
import { serverRequire } from './serverRequire';

let testRunnerConfig: TestRunnerConfig;
let loaded = false;
Expand All @@ -13,7 +13,11 @@ export const getTestRunnerConfig = (
return testRunnerConfig;
}

testRunnerConfig = serverRequire(join(resolve(configDir), 'test-runner'));
loaded = true;
return testRunnerConfig;
try {
testRunnerConfig = serverRequire(join(resolve(configDir), 'test-runner'));
loaded = true;
return testRunnerConfig;
} catch (error) {
return undefined;
}
};
Loading