Skip to content

Commit

Permalink
Merge pull request #28674 from storybookjs/larsrickert/out-of-memory-…
Browse files Browse the repository at this point in the history
…slots-events

Vue: Fix out of memory error when using vue-component-meta for events and slots
  • Loading branch information
kasperpeulen authored Jul 23, 2024
2 parents 7e55011 + 30efa20 commit 8bccace
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
createCheckerByJson,
type ComponentMeta,
type MetaCheckerOptions,
type PropertyMetaSchema,
} from 'vue-component-meta';
import { parseMulti } from 'vue-docgen-api';

Expand Down Expand Up @@ -52,21 +53,14 @@ export async function vueComponentMeta(tsconfigPath = 'tsconfig.json'): Promise<

// we remove nested object schemas here since they are not used inside Storybook (we don't generate controls for object properties)
// and they can cause "out of memory" issues for large/complex schemas (e.g. HTMLElement)
// it also reduced the bundle size when running "Storybook build" when such schemas are used
(['props', 'exposed'] as const).forEach((key) => {
// it also reduced the bundle size when running "storybook build" when such schemas are used
(['props', 'events', 'slots', 'exposed'] as const).forEach((key) => {
meta[key].forEach((value) => {
if (typeof value.schema !== 'object') return;

// we need to use Object.defineProperty here since schema is a getter so we can not set it directly
Object.defineProperty(value, 'schema', {
configurable: true,
enumerable: true,
value: {
kind: value.schema.kind,
type: value.schema.type,
// note that value.schema.schema is not included here (see comment above)
},
});
if (Array.isArray(value.schema)) {
value.schema.forEach((eventSchema) => removeNestedSchemas(eventSchema));
} else {
removeNestedSchemas(value.schema);
}
});
});

Expand Down Expand Up @@ -270,3 +264,12 @@ async function getTsConfigReferences(tsConfigPath: string) {
return [];
}
}

/**
* Removes any nested schemas from the given main schema (e.g. from a prop, event, slot or exposed).
* Useful to drastically reduce build size and prevent out of memory issues when large schemas (e.g. HTMLElement, MouseEvent) are used.
*/
function removeNestedSchemas(schema: PropertyMetaSchema) {
if (typeof schema !== 'object') return;
delete schema.schema;
}

0 comments on commit 8bccace

Please sign in to comment.