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

Vue3: Add support for Global Apps install #23772

Merged
merged 14 commits into from
Aug 23, 2023
5 changes: 5 additions & 0 deletions code/renderers/vue3/src/globals.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { global } from '@storybook/global';
import type { App } from 'vue';
import type { StoryContext } from './public-types';

const { window: globalWindow } = global;

globalWindow.STORYBOOK_ENV = 'vue3';
globalWindow.PLUGINS_SETUP_FUNCTIONS ||= new Set<
(app: App<any>, context: StoryContext) => unknown
>();
9 changes: 8 additions & 1 deletion code/renderers/vue3/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ export * from './public-api';
export * from './public-types';

// optimization: stop HMR propagation in webpack
if (typeof module !== 'undefined') module?.hot?.decline();
try {
if (module?.hot?.decline) {
module.hot.decline();
}
Comment on lines 8 to +12
Copy link
Contributor

Choose a reason for hiding this comment

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

You still need the typeof module !== 'undefined' check right?

Maybe:

if (typeof module !== 'undefined') module?.hot?.decline?.();

} catch (e) {
/* do nothing */
console.log(e);
chakAs3 marked this conversation as resolved.
Show resolved Hide resolved
}
24 changes: 12 additions & 12 deletions code/renderers/vue3/src/render.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable local-rules/no-uncategorized-errors */
/* eslint-disable no-param-reassign */
import type { App } from 'vue';
import { createApp, h, reactive, isVNode, isReactive } from 'vue';
Expand All @@ -16,18 +17,17 @@ export const render: ArgsStoryFn<VueRenderer> = (props, context) => {
return () => h(Component, props, getSlots(props, context));
};

// set of setup functions that will be called when story is created
const setupFunctions = new Set<(app: App, storyContext?: StoryContext<VueRenderer>) => void>();
/** add a setup function to set that will be call when story is created a d
*
* @param fn
*/
export const setup = (fn: (app: App, storyContext?: StoryContext<VueRenderer>) => void) => {
setupFunctions.add(fn);
export const setup = (fn: (app: App, storyContext?: StoryContext<VueRenderer>) => unknown) => {
globalThis.PLUGINS_SETUP_FUNCTIONS ??= new Set();
globalThis.PLUGINS_SETUP_FUNCTIONS.add(fn);
Comment on lines +21 to +22
Copy link
Contributor

Choose a reason for hiding this comment

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

@ndelangen I thought you mentioned at some point that we prefer @storybook/global over globalThis but I don't know the reasons anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

as i know globalThis was introduced to give access to global scope regardless the system Node/Browser, it is consistency and standard rather than using window / global

Copy link
Contributor Author

Choose a reason for hiding this comment

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

and that what @storybook/global provides the global scope so if we do
declare var STORYBOOK_ENV:'type' in type.d.ts file
will be safely available on globalThis as global module

};

const runSetupFunctions = (app: App, storyContext: StoryContext<VueRenderer>) => {
setupFunctions.forEach((fn) => fn(app, storyContext));
const runSetupFunctions = async (
app: App,
storyContext: StoryContext<VueRenderer>
): Promise<any> => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Promise<void>

if (globalThis && globalThis.PLUGINS_SETUP_FUNCTIONS)
await Promise.all([...globalThis.PLUGINS_SETUP_FUNCTIONS].map((fn) => fn(app, storyContext)));
Comment on lines +29 to +30
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe Promise.allSettled as I think we don't want to short-circuit here?

};

const map = new Map<
Expand All @@ -38,7 +38,7 @@ const map = new Map<
}
>();

export function renderToCanvas(
export async function renderToCanvas(
{ storyFn, forceRemount, showMain, showException, storyContext, id }: RenderContext<VueRenderer>,
canvasElement: VueRenderer['canvasElement']
) {
Expand Down Expand Up @@ -80,7 +80,7 @@ export function renderToCanvas(
});

vueApp.config.errorHandler = (e: unknown) => showException(e as Error);
runSetupFunctions(vueApp, storyContext);
await runSetupFunctions(vueApp, storyContext);
vueApp.mount(canvasElement);

showMain();
Expand Down
6 changes: 4 additions & 2 deletions code/renderers/vue3/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { StoryContext as StoryContextBase, WebRenderer } from '@storybook/types';
import type { ConcreteComponent } from 'vue';
import { type StoryContext as StoryContextBase, type WebRenderer } from '@storybook/types';
import type { App, ConcreteComponent } from 'vue';

export type { RenderContext } from '@storybook/types';

Expand All @@ -14,6 +14,8 @@ export type StoryFnVueReturnType = ConcreteComponent<any>;

export type StoryContext = StoryContextBase<VueRenderer>;

export type StorybookVueApp = { vueApp: App<any>; storyContext: StoryContext };

/**
* @deprecated Use `VueRenderer` instead.
*/
Expand Down
1 change: 1 addition & 0 deletions code/renderers/vue3/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
declare var STORYBOOK_ENV: 'vue3';
declare var PLUGINS_SETUP_FUNCTIONS = new Set<(app, context) => unknown>();