Skip to content

Commit

Permalink
Merge pull request #28589 from storybookjs/larsrickert/26647-out-of-m…
Browse files Browse the repository at this point in the history
…emory

Vue: Fix out of memory error when using vue-component-meta
  • Loading branch information
kasperpeulen authored Jul 17, 2024
2 parents 0b54024 + 9601e82 commit 3590a1c
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 62 deletions.
20 changes: 20 additions & 0 deletions code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,26 @@ export async function vueComponentMeta(tsconfigPath = 'tsconfig.json'): Promise<

const exportName = exportNames[index];

// 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) => {
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)
},
});
});
});

const exposed =
// the meta also includes duplicated entries in the "exposed" array with "on"
// prefix (e.g. onClick instead of click), so we need to filter them out here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1
"value": {
"name": "object",
"required": false,
"value": {
"nestedProp": {
"name": "string",
"required": true,
},
},
"value": {},
},
},
},
Expand All @@ -183,12 +178,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1
"value": {
"name": "object",
"required": false,
"value": {
"nestedProp": {
"name": "string",
"required": true,
},
},
"value": {},
},
},
},
Expand Down Expand Up @@ -279,12 +269,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1
"type": {
"name": "object",
"required": true,
"value": {
"foo": {
"name": "string",
"required": true,
},
},
"value": {},
},
},
"literalFromContext": {
Expand Down Expand Up @@ -325,12 +310,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1
"type": {
"name": "object",
"required": true,
"value": {
"nestedProp": {
"name": "string",
"required": true,
},
},
"value": {},
},
},
"nestedIntersection": {
Expand All @@ -347,16 +327,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1
"type": {
"name": "object",
"required": true,
"value": {
"additionalProp": {
"name": "string",
"required": true,
},
"nestedProp": {
"name": "string",
"required": true,
},
},
"value": {},
},
},
"nestedOptional": {
Expand All @@ -377,22 +348,12 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1
{
"name": "object",
"required": false,
"value": {
"nestedProp": {
"name": "string",
"required": true,
},
},
"value": {},
},
{
"name": "object",
"required": false,
"value": {
"nestedProp": {
"name": "string",
"required": true,
},
},
"value": {},
},
],
},
Expand All @@ -411,13 +372,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1
"type": {
"name": "object",
"required": false,
"value": {
"recursive": {
"name": "other",
"required": true,
"value": "MyNestedRecursiveProps",
},
},
"value": {},
},
},
"stringArray": {
Expand Down
13 changes: 4 additions & 9 deletions code/renderers/vue3/src/docs/extractArgTypes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { VueDocgenInfo, VueDocgenInfoEntry, VueDocgenPlugin } from '@storybook/vue3-vite';
import type { ExtractedProp } from 'storybook/internal/docs-tools';
import {
convert,
Expand All @@ -6,7 +7,6 @@ import {
type ArgTypesExtractor,
} from 'storybook/internal/docs-tools';
import type { SBType, StrictArgTypes, StrictInputType } from 'storybook/internal/types';
import type { VueDocgenInfo, VueDocgenInfoEntry, VueDocgenPlugin } from '@storybook/vue3-vite';

type PropertyMetaSchema = VueDocgenInfoEntry<'vue-component-meta', 'props'>['schema'];

Expand Down Expand Up @@ -283,17 +283,12 @@ export const convertVueComponentMetaProp = (
};
}

// recursively/deeply convert all properties of the object
case 'object':
return {
name: 'object',
value: Object.entries(schema.schema ?? {}).reduce<Record<string, SBType>>(
(obj, [propName, propSchema]) => {
obj[propName] = convertVueComponentMetaProp(propSchema);
return obj;
},
{}
),
// while Storybook generates simple JSON object controls, nested schemas don't have specialized controls
// so we don't need to recursively map the object schema here
value: {},
required,
};

Expand Down

0 comments on commit 3590a1c

Please sign in to comment.