Merge branch 'next' into vite/plugin-cleanup

This commit is contained in:
Michael Shilman 2022-09-02 18:41:42 +08:00
commit bc41d6666c
93 changed files with 420 additions and 147 deletions

View File

@ -59,7 +59,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addon-highlight": "7.0.0-alpha.28",

View File

@ -32,7 +32,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -59,7 +59,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -54,7 +54,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -46,7 +46,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@babel/plugin-transform-react-jsx": "^7.12.12",

View File

@ -30,7 +30,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addon-actions": "7.0.0-alpha.28",

View File

@ -34,7 +34,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -32,7 +32,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@devtools-ds/object-inspector": "^1.1.2",

View File

@ -56,7 +56,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -60,7 +60,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -58,7 +58,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -61,7 +61,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -33,7 +33,7 @@
"scripts": {
"build-storybook": "sb build",
"example": "jest storyshot.test",
"prep": "node ../../../../scripts/prepare.js",
"prepare": "node ../../../../scripts/prepare.js",
"storybook": "yarn sb dev -p 6006"
},
"dependencies": {

View File

@ -30,7 +30,7 @@
"*.d.ts"
],
"scripts": {
"prep": "node ../../../../scripts/prepare.js"
"prepare": "node ../../../../scripts/prepare.js"
},
"dependencies": {
"@axe-core/puppeteer": "^4.2.0",

View File

@ -32,7 +32,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -54,7 +54,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -56,7 +56,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -27,7 +27,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/builder-webpack5": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/builder-webpack5": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/builder-webpack5": "7.0.0-alpha.28",

View File

@ -48,7 +48,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@joshwooding/vite-plugin-react-docgen-typescript": "^0.0.5",

View File

@ -48,7 +48,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/builder-webpack5": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/builder-webpack5": "7.0.0-alpha.28",

View File

@ -48,7 +48,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addon-svelte-csf": "^2.0.0",

View File

@ -48,7 +48,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/builder-webpack5": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/builder-webpack5": "7.0.0-alpha.28",

View File

@ -48,7 +48,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/builder-vite": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/builder-webpack5": "7.0.0-alpha.28",

View File

@ -49,7 +49,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@babel/preset-env": "^7.12.11",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/api": "7.0.0-alpha.28",

View File

@ -29,7 +29,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/channels": "7.0.0-alpha.28",

View File

@ -38,7 +38,7 @@
"*.d.ts"
],
"scripts": {
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/api": "7.0.0-alpha.28",

View File

@ -38,7 +38,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",

View File

@ -15,7 +15,7 @@
"types": "dist/types/index.d.ts",
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@joshwooding/vite-plugin-react-docgen-typescript": "0.0.5",

View File

@ -30,7 +30,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@babel/core": "^7.12.10",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/channels": "7.0.0-alpha.28",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/channels": "7.0.0-alpha.28",

View File

@ -39,7 +39,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"core-js": "^3.8.2",

View File

@ -22,7 +22,7 @@
"bin": "./index.js",
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/cli": "7.0.0-alpha.28"

View File

@ -25,7 +25,7 @@
},
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/cli": "7.0.0-alpha.28"

View File

@ -35,7 +35,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js",
"prepare": "node ../../../scripts/prepare.js",
"test": "jest test/**/*.test.js"
},
"dependencies": {

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -39,7 +39,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"core-js": "^3.8.2",

View File

@ -32,7 +32,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@babel/types": "^7.12.11",

View File

@ -48,7 +48,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/client-logger": "7.0.0-alpha.28",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -43,7 +43,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@babel/core": "^7.12.10",

View File

@ -39,7 +39,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"core-js": "^3.8.2"

View File

@ -30,7 +30,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@aw-web-design/x-default-browser": "1.4.88",

View File

@ -39,7 +39,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/core-common": "7.0.0-alpha.28",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@babel/core": "^7.12.10",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@babel/core": "^7.12.10",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@types/npmlog": "^4.1.2",

View File

@ -32,7 +32,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"core-js": "^3.8.2"

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -1,5 +1,5 @@
/// <reference types="@types/jest" />;
import { jest, jest as mockJest, it, describe, beforeEach, afterEach, expect } from '@jest/globals';
import global from 'global';
import merge from 'lodash/merge';
import {
@ -31,7 +31,6 @@ import { logger } from '@storybook/client-logger';
import { addons, mockChannel as createMockChannel } from '@storybook/addons';
import type { AnyFramework } from '@storybook/csf';
import type { ModuleImportFn, WebProjectAnnotations } from '@storybook/store';
import { expect } from '@jest/globals';
import { mocked } from 'ts-jest/utils';
import { PreviewWeb } from './PreviewWeb';
@ -60,8 +59,8 @@ const mockStoryIndex = jest.fn(() => storyIndex);
let mockFetchResult;
jest.mock('global', () => ({
...(jest.requireActual('global') as any),
history: { replaceState: jest.fn() },
...(mockJest.requireActual('global') as any),
history: { replaceState: mockJest.fn() },
document: {
location: {
pathname: 'pathname',
@ -70,7 +69,7 @@ jest.mock('global', () => ({
},
window: {
location: {
reload: jest.fn(),
reload: mockJest.fn(),
},
},
FEATURES: {
@ -349,8 +348,12 @@ describe('PreviewWeb', () => {
});
describe('after selection changes', () => {
beforeEach(() => jest.useFakeTimers());
afterEach(() => jest.useRealTimers());
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
it('DOES NOT try again if CSF file changes', async () => {
document.location.search = '?id=component-one--missing';
@ -1563,49 +1566,140 @@ describe('PreviewWeb', () => {
expect(teardownRenderToDOM).not.toHaveBeenCalled();
});
// For https://github.com/storybookjs/storybook/issues/17214
it('does NOT render a second time if preparing', async () => {
document.location.search = '?id=component-one--a';
describe('while preparing', () => {
// For https://github.com/storybookjs/storybook/issues/17214
it('does NOT render a second time in story mode', async () => {
document.location.search = '?id=component-one--a';
const [gate, openGate] = createGate();
const [importedGate, openImportedGate] = createGate();
importFn
.mockImplementationOnce(async (...args) => {
await gate;
return importFn(...args);
})
.mockImplementationOnce(async (...args) => {
// The second time we `import()` we open the "imported" gate
openImportedGate();
await gate;
return importFn(...args);
const [gate, openGate] = createGate();
const [importedGate, openImportedGate] = createGate();
importFn
.mockImplementationOnce(async (...args) => {
await gate;
return importFn(...args);
})
.mockImplementationOnce(async (...args) => {
// The second time we `import()` we open the "imported" gate
openImportedGate();
await gate;
return importFn(...args);
});
const preview = new PreviewWeb();
// We can't wait for the initialize function, as it waits for `renderSelection()`
// which prepares, but it does emit `CURRENT_STORY_WAS_SET` right before that
preview.initialize({ importFn, getProjectAnnotations });
await waitForEvents([CURRENT_STORY_WAS_SET]);
mockChannel.emit.mockClear();
projectAnnotations.renderToDOM.mockClear();
emitter.emit(SET_CURRENT_STORY, {
storyId: 'component-one--a',
viewMode: 'story',
});
await importedGate;
// We are blocking import so this won't render yet
expect(projectAnnotations.renderToDOM).not.toHaveBeenCalled();
const preview = new PreviewWeb();
// We can't wait for the initialize function, as it waits for `renderSelection()`
// which prepares, but it does emit `CURRENT_STORY_WAS_SET` right before that
preview.initialize({ importFn, getProjectAnnotations });
await waitForEvents([CURRENT_STORY_WAS_SET]);
mockChannel.emit.mockClear();
openGate();
await waitForRender();
mockChannel.emit.mockClear();
projectAnnotations.renderToDOM.mockClear();
emitter.emit(SET_CURRENT_STORY, {
storyId: 'component-one--a',
viewMode: 'story',
// We should only render *once*
expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(1);
// We should not show an error either
expect(preview.view.showErrorDisplay).not.toHaveBeenCalled();
});
await importedGate;
// We are blocking import so this won't render yet
expect(projectAnnotations.renderToDOM).not.toHaveBeenCalled();
mockChannel.emit.mockClear();
openGate();
await waitForRender();
// For https://github.com/storybookjs/storybook/issues/19015
it('does NOT render a second time in template docs mode', async () => {
document.location.search = '?id=component-one--docs&viewMode=docs';
// We should only render *once*
expect(projectAnnotations.renderToDOM).toHaveBeenCalledTimes(1);
const [gate, openGate] = createGate();
const [importedGate, openImportedGate] = createGate();
importFn
.mockImplementationOnce(async (...args) => {
await gate;
return importFn(...args);
})
.mockImplementationOnce(async (...args) => {
// The second time we `import()` we open the "imported" gate
openImportedGate();
await gate;
return importFn(...args);
});
// We should not show an error either
expect(preview.view.showErrorDisplay).not.toHaveBeenCalled();
const preview = new PreviewWeb();
// We can't wait for the initialize function, as it waits for `renderSelection()`
// which prepares, but it does emit `CURRENT_STORY_WAS_SET` right before that
preview.initialize({ importFn, getProjectAnnotations });
await waitForEvents([CURRENT_STORY_WAS_SET]);
mockChannel.emit.mockClear();
projectAnnotations.renderToDOM.mockClear();
emitter.emit(SET_CURRENT_STORY, {
storyId: 'component-one--docs',
viewMode: 'docs',
});
await importedGate;
// We are blocking import so this won't render yet
expect(docsRenderer.render).not.toHaveBeenCalled();
mockChannel.emit.mockClear();
openGate();
await waitForRender();
// We should only render *once*
expect(docsRenderer.render).toHaveBeenCalledTimes(1);
// We should not show an error either
expect(preview.view.showErrorDisplay).not.toHaveBeenCalled();
});
it('does NOT render a second time in standalone docs mode', async () => {
document.location.search = '?id=introduction--docs&viewMode=docs';
const [gate, openGate] = createGate();
const [importedGate, openImportedGate] = createGate();
importFn
.mockImplementationOnce(async (...args) => {
await gate;
return importFn(...args);
})
.mockImplementationOnce(async (...args) => {
// The second time we `import()` we open the "imported" gate
openImportedGate();
await gate;
return importFn(...args);
});
const preview = new PreviewWeb();
// We can't wait for the initialize function, as it waits for `renderSelection()`
// which prepares, but it does emit `CURRENT_STORY_WAS_SET` right before that
preview.initialize({ importFn, getProjectAnnotations });
await waitForEvents([CURRENT_STORY_WAS_SET]);
mockChannel.emit.mockClear();
projectAnnotations.renderToDOM.mockClear();
emitter.emit(SET_CURRENT_STORY, {
storyId: 'introduction--docs',
viewMode: 'docs',
});
await importedGate;
// We are blocking import so this won't render yet
expect(docsRenderer.render).not.toHaveBeenCalled();
mockChannel.emit.mockClear();
openGate();
await waitForRender();
// We should only render *once*
expect(docsRenderer.render).toHaveBeenCalledTimes(1);
// We should not show an error either
expect(preview.view.showErrorDisplay).not.toHaveBeenCalled();
});
});
});
@ -2715,8 +2809,12 @@ describe('PreviewWeb', () => {
});
describe('if it was previously rendered', () => {
beforeEach(() => jest.useFakeTimers());
afterEach(() => jest.useRealTimers());
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
it('is reloaded when it is re-selected', async () => {
document.location.search = '?id=component-one--a';
const preview = await createAndRenderPreview();

View File

@ -34,7 +34,8 @@ import { MaybePromise, Preview } from './Preview';
import { UrlStore } from './UrlStore';
import { WebView } from './WebView';
import { PREPARE_ABORTED, StoryRender } from './render/StoryRender';
import { PREPARE_ABORTED } from './render/Render';
import { StoryRender } from './render/StoryRender';
import { TemplateDocsRender } from './render/TemplateDocsRender';
import { StandaloneDocsRender } from './render/StandaloneDocsRender';

View File

@ -19,3 +19,5 @@ export interface Render<TFramework extends AnyFramework> {
torndown: boolean;
renderToElement: (canvasElement: HTMLElement, renderStoryToElement?: any) => Promise<void>;
}
export const PREPARE_ABORTED = new Error('prepareAborted');

View File

@ -0,0 +1,52 @@
import { jest, describe, it, expect } from '@jest/globals';
import { Channel } from '@storybook/channels';
import { AnyFramework } from '@storybook/csf';
import { StoryStore } from '@storybook/store';
import type { StandaloneDocsIndexEntry } from '@storybook/store';
import { PREPARE_ABORTED } from './Render';
import { StandaloneDocsRender } from './StandaloneDocsRender';
const entry = {
type: 'docs',
id: 'introduction--docs',
name: 'Docs',
title: 'Introduction',
importPath: './Introduction.mdx',
storiesImports: [],
standalone: true,
} as StandaloneDocsIndexEntry;
const createGate = (): [Promise<any | undefined>, (_?: any) => void] => {
let openGate = (_?: any) => {};
const gate = new Promise<any | undefined>((resolve) => {
openGate = resolve;
});
return [gate, openGate];
};
describe('StandaloneDocsRender', () => {
it('throws PREPARE_ABORTED if torndown during prepare', async () => {
const [importGate, openImportGate] = createGate();
const mockStore = {
loadEntry: jest.fn(async () => {
await importGate;
return {};
}),
};
const render = new StandaloneDocsRender(
new Channel(),
mockStore as unknown as StoryStore<AnyFramework>,
entry
);
const preparePromise = render.prepare();
render.teardown();
openImportGate();
await expect(preparePromise).rejects.toThrowError(PREPARE_ABORTED);
});
});

View File

@ -3,7 +3,7 @@ import { CSFFile, ModuleExports, StoryStore } from '@storybook/store';
import { Channel, IndexEntry } from '@storybook/addons';
import { DOCS_RENDERED } from '@storybook/core-events';
import { Render, RenderType } from './Render';
import { Render, RenderType, PREPARE_ABORTED } from './Render';
import type { DocsContextProps } from '../docs-context/DocsContextProps';
import type { DocsRenderFunction } from '../docs-context/DocsRenderFunction';
import { DocsContext } from '../docs-context/DocsContext';
@ -26,7 +26,7 @@ export class StandaloneDocsRender<TFramework extends AnyFramework> implements Re
public rerender?: () => Promise<void>;
public teardown?: (options: { viewModeChanged?: boolean }) => Promise<void>;
public teardownRender?: (options: { viewModeChanged?: boolean }) => Promise<void>;
public torndown = false;
@ -51,6 +51,8 @@ export class StandaloneDocsRender<TFramework extends AnyFramework> implements Re
async prepare() {
this.preparing = true;
const { entryExports, csfFiles = [] } = await this.store.loadEntry(this.id);
if (this.torndown) throw PREPARE_ABORTED;
this.csfFiles = csfFiles;
this.exports = entryExports;
@ -96,7 +98,7 @@ export class StandaloneDocsRender<TFramework extends AnyFramework> implements Re
};
this.rerender = async () => renderDocs();
this.teardown = async ({ viewModeChanged }: { viewModeChanged?: boolean } = {}) => {
this.teardownRender = async ({ viewModeChanged }: { viewModeChanged?: boolean } = {}) => {
if (!viewModeChanged || !canvasElement) return;
renderer.unmount(canvasElement);
this.torndown = true;
@ -104,4 +106,9 @@ export class StandaloneDocsRender<TFramework extends AnyFramework> implements Re
return renderDocs();
}
async teardown({ viewModeChanged }: { viewModeChanged?: boolean } = {}) {
this.teardownRender?.({ viewModeChanged });
this.torndown = true;
}
}

View File

@ -0,0 +1,54 @@
import { jest, describe, it, expect } from '@jest/globals';
import { Channel } from '@storybook/channels';
import { AnyFramework } from '@storybook/csf';
import { StoryStore } from '@storybook/store';
import type { StoryIndexEntry } from '@storybook/store';
import { PREPARE_ABORTED } from './Render';
import { StoryRender } from './StoryRender';
const entry = {
type: 'story',
id: 'component--a',
name: 'A',
title: 'component',
importPath: './component.stories.ts',
} as StoryIndexEntry;
const createGate = (): [Promise<any | undefined>, (_?: any) => void] => {
let openGate = (_?: any) => {};
const gate = new Promise<any | undefined>((resolve) => {
openGate = resolve;
});
return [gate, openGate];
};
describe('StoryRender', () => {
it('throws PREPARE_ABORTED if torndown during prepare', async () => {
const [importGate, openImportGate] = createGate();
const mockStore = {
loadStory: jest.fn(async () => {
await importGate;
return {};
}),
cleanupStory: jest.fn(),
};
const render = new StoryRender(
new Channel(),
mockStore as unknown as StoryStore<AnyFramework>,
jest.fn(),
{} as any,
entry.id,
'story'
);
const preparePromise = render.prepare();
render.teardown();
openImportGate();
await expect(preparePromise).rejects.toThrowError(PREPARE_ABORTED);
});
});

View File

@ -20,7 +20,7 @@ import {
STORY_RENDERED,
PLAY_FUNCTION_THREW_EXCEPTION,
} from '@storybook/core-events';
import { Render, RenderType } from './Render';
import { Render, RenderType, PREPARE_ABORTED } from './Render';
const { AbortController } = global;
@ -60,8 +60,6 @@ export type RenderContextCallbacks<TFramework extends AnyFramework> = Pick<
'showMain' | 'showError' | 'showException'
>;
export const PREPARE_ABORTED = new Error('prepareAborted');
export class StoryRender<TFramework extends AnyFramework> implements Render<TFramework> {
public type: RenderType = 'story';
@ -275,7 +273,7 @@ export class StoryRender<TFramework extends AnyFramework> implements Render<TFra
this.abortController?.abort();
}
async teardown(options: {} = {}) {
async teardown() {
this.torndown = true;
this.cancelRender();

View File

@ -0,0 +1,52 @@
import { jest, describe, it, expect } from '@jest/globals';
import { Channel } from '@storybook/channels';
import { AnyFramework } from '@storybook/csf';
import { StoryStore } from '@storybook/store';
import type { TemplateDocsIndexEntry } from '@storybook/store';
import { PREPARE_ABORTED } from './Render';
import { TemplateDocsRender } from './TemplateDocsRender';
const entry = {
type: 'docs',
id: 'component--docs',
name: 'Docs',
title: 'Component',
importPath: './Component.stories.ts',
storiesImports: [],
standalone: false,
} as TemplateDocsIndexEntry;
const createGate = (): [Promise<any | undefined>, (_?: any) => void] => {
let openGate = (_?: any) => {};
const gate = new Promise<any | undefined>((resolve) => {
openGate = resolve;
});
return [gate, openGate];
};
describe('TemplateDocsRender', () => {
it('throws PREPARE_ABORTED if torndown during prepare', async () => {
const [importGate, openImportGate] = createGate();
const mockStore = {
loadEntry: jest.fn(async () => {
await importGate;
return {};
}),
};
const render = new TemplateDocsRender(
new Channel(),
mockStore as unknown as StoryStore<AnyFramework>,
entry
);
const preparePromise = render.prepare();
render.teardown();
openImportGate();
await expect(preparePromise).rejects.toThrowError(PREPARE_ABORTED);
});
});

View File

@ -3,7 +3,7 @@ import { CSFFile, Story, StoryStore } from '@storybook/store';
import { Channel, IndexEntry } from '@storybook/addons';
import { DOCS_RENDERED } from '@storybook/core-events';
import { Render, RenderType } from './Render';
import { Render, RenderType, PREPARE_ABORTED } from './Render';
import type { DocsContextProps } from '../docs-context/DocsContextProps';
import type { DocsRenderFunction } from '../docs-context/DocsRenderFunction';
import { DocsContext } from '../docs-context/DocsContext';
@ -29,7 +29,7 @@ export class TemplateDocsRender<TFramework extends AnyFramework> implements Rend
public rerender?: () => Promise<void>;
public teardown?: (options: { viewModeChanged?: boolean }) => Promise<void>;
public teardownRender?: (options: { viewModeChanged?: boolean }) => Promise<void>;
public torndown = false;
@ -54,9 +54,10 @@ export class TemplateDocsRender<TFramework extends AnyFramework> implements Rend
async prepare() {
this.preparing = true;
const { entryExports, csfFiles = [] } = await this.store.loadEntry(this.id);
if (this.torndown) throw PREPARE_ABORTED;
const { importPath, title } = this.entry;
const primaryCsfFile = await this.store.processCSFFileWithCache<TFramework>(
const primaryCsfFile = this.store.processCSFFileWithCache<TFramework>(
entryExports,
importPath,
title
@ -112,12 +113,16 @@ export class TemplateDocsRender<TFramework extends AnyFramework> implements Rend
};
this.rerender = async () => renderDocs();
this.teardown = async ({ viewModeChanged }: { viewModeChanged?: boolean } = {}) => {
this.teardownRender = async ({ viewModeChanged }: { viewModeChanged?: boolean }) => {
if (!viewModeChanged || !canvasElement) return;
renderer.unmount(canvasElement);
this.torndown = true;
};
return renderDocs();
}
async teardown({ viewModeChanged }: { viewModeChanged?: boolean } = {}) {
this.teardownRender?.({ viewModeChanged });
this.torndown = true;
}
}

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "ts-node ../../../scripts/prebundle.ts"
"prepare": "ts-node ../../../scripts/prebundle.ts"
},
"dependencies": {
"@storybook/client-logger": "7.0.0-alpha.28",

View File

@ -32,7 +32,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -31,7 +31,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/client-logger": "7.0.0-alpha.28",

View File

@ -44,7 +44,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/client-logger": "7.0.0-alpha.28",

View File

@ -49,7 +49,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"devDependencies": {
"@babel/core": "^7.12.10",

View File

@ -10,8 +10,8 @@
"default": {
"runner": "@nrwl/nx-cloud",
"options": {
"cacheableOperations": ["build", "test", "lint", "package", "prep"],
"strictlyOrderedTargets": ["build", "package", "prep"],
"cacheableOperations": ["build", "test", "lint", "package", "prepare"],
"strictlyOrderedTargets": ["build", "package", "prepare"],
"accessToken": "NGVmYTkxMmItYzY3OS00MjkxLTk1ZDktZDFmYTFmNmVlNGY4fHJlYWQ=",
"canTrackAnalytics": false,
"showUsageWarnings": true

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/core-webpack": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@babel/plugin-transform-react-jsx": "^7.12.12",

View File

@ -68,7 +68,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@babel/preset-flow": "^7.12.1",

View File

@ -52,7 +52,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/core-server": "7.0.0-alpha.28",

View File

@ -62,7 +62,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/core-webpack": "7.0.0-alpha.28",

View File

@ -57,7 +57,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/core-webpack": "7.0.0-alpha.28",

View File

@ -57,7 +57,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/core-webpack": "7.0.0-alpha.28",

View File

@ -49,7 +49,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@babel/plugin-syntax-dynamic-import": "^7.8.3",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -48,7 +48,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -51,7 +51,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -47,7 +47,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

View File

@ -49,7 +49,7 @@
],
"scripts": {
"check": "tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
"prepare": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.28",

10
scripts/bootstrap.js vendored
View File

@ -74,9 +74,9 @@ function run() {
defaultValue: true,
option: '--prep',
command: () => {
log.info(prefix, 'prep');
log.info(prefix, 'prepare');
spawn(
`nx run-many --target="prep" --all --parallel --exclude=@storybook/addon-storyshots,@storybook/addon-storyshots-puppeteer -- --reset`
`nx run-many --target="prepare" --all --parallel --exclude=@storybook/addon-storyshots,@storybook/addon-storyshots-puppeteer -- --reset`
);
},
order: 2,
@ -86,9 +86,9 @@ function run() {
defaultValue: true,
option: '--retry',
command: () => {
log.info(prefix, 'prep');
log.info(prefix, 'prepare');
spawn(
`nx run-many --target=prep --all --parallel --only-failed ${
`nx run-many --target=prepare --all --parallel --only-failed ${
process.env.CI ? `--max-parallel=${maxConcurrentTasks}` : ''
}`
);
@ -122,7 +122,7 @@ function run() {
command: () => {
log.info(prefix, 'build');
spawn(
`nx run-many --target="prep" --all --parallel=8 ${
`nx run-many --target="prepare" --all --parallel=8 ${
process.env.CI ? `--max-parallel=${maxConcurrentTasks}` : ''
} -- --reset --optimized`
);

View File

@ -113,7 +113,7 @@ async function run() {
}
selection?.filter(Boolean).forEach(async (v) => {
const commmand = (await readJSON(resolve(v.location, 'package.json'))).scripts.prep;
const commmand = (await readJSON(resolve(v.location, 'package.json'))).scripts.prepare;
const cwd = resolve(__dirname, '..', 'code', v.location);
const sub = require('execa').command(
`${commmand}${watchMode ? ' --watch' : ''}${prodMode ? ' --optimized' : ''}`,

View File

@ -68,7 +68,7 @@ const hasFlag = (flags, name) => !!flags.find((s) => s.startsWith(`--${name}`));
const modules = true;
async function prep({ cwd, flags }) {
async function prepare({ cwd, flags }) {
const { packageJson } = await readPkgUp(cwd);
const message = chalk.gray(`Built: ${chalk.bold(`${packageJson.name}@${packageJson.version}`)}`);
console.time(message);
@ -101,4 +101,4 @@ async function prep({ cwd, flags }) {
const flags = process.argv.slice(2);
const cwd = process.cwd();
prep({ cwd, flags });
prepare({ cwd, flags });

View File

@ -267,7 +267,11 @@ async function addStories(paths: string[], { mainConfig }: { mainConfig: ConfigF
const relativeCodeDir = path.join('..', '..', '..', 'code');
const extraStories = extraStoryDirsAndExistence
.filter(([, exists]) => exists)
.map(([p]) => path.join(relativeCodeDir, p, '*.stories.@(js|jsx|ts|tsx)'));
.map(([p]) => ({
directory: path.join(relativeCodeDir, p),
titlePrefix: p.split('/').slice(-4, -2).join('/'),
files: '*.stories.@(js|jsx|ts|tsx)',
}));
mainConfig.setFieldValue(['stories'], [...stories, ...extraStories]);
}