histoire-dev / histoire

⚡ Fast and beautiful interactive component playgrounds, powered by Vite
https://histoire.dev
MIT License
3.19k stars 190 forks source link

Attribute/prop pollution in Variant #554

Open KCMertens opened 1 year ago

KCMertens commented 1 year ago

Describe the bug

A bizarre thing, I have a component that when mounted in a Variant it somehow causes all variables declared inside <script setup> to leak into the component props, even those not set as attributes!

This may seem relatively innocent, but it breaks stories for any component that uses v-bind=$attrs on an html element, because one of the leaked/injected attributes is called $data, which is an illegal HTML attribute name, causing the browser to throw an exception deep inside vue when the attribute is patched into the DOM.


In the repro I've managed to narrow it down to the component sending an update event before onMounted fires (it's a form component that will self-correct an illegal modelValue during setup). If I delay the update event to after onMounted the bug goes away.

I've worked around it by delaying the modelValue update to after onMounted, but it's a bit of a headache (and very weird).

Reproduction

https://stackblitz.com/edit/histoire-vue3-starter-oz33k1?file=src%2FReproComponent.story.vue

Switch between the two variant stories and the bug will show up. Even weirder, switch a few more times and it seems to break completely, and the entire component disappears.

System Info

System:
    OS: Windows 10 10.0.22621
    CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12700K
    Memory: 49.16 GB / 63.83 GB
  Binaries:
    Node: 16.13.1 - C:\program files\nodejs\node.EXE
    Yarn: 1.22.19 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 9.7.2 - C:\program files\nodejs\npm.CMD
  Browsers:
    Chrome: 114.0.5735.135
    Edge: Spartan (44.22621.1848.0), Chromium (114.0.1823.58)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    @histoire/plugin-vue: ^0.16.1 => 0.16.1
    @vitejs/plugin-vue: ^4.2.3 => 4.2.3
    histoire: ^0.16.1 => 0.16.1
    vite: ^4.3.9 => 4.3.9

Used Package Manager

npm

Validations

stackblitz[bot] commented 1 year ago

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

KCMertens commented 1 year ago

I've done a bit of digging and the data seems to originate here https://github.com/histoire-dev/histoire/blob/7b4411f359dbf59bf4d6bda377bd47d38736ac45/packages/histoire-plugin-vue/src/client/app/Story.ts#L30-L50 This code then picks it up and copies it into the {state} of the Variant, which passes it into the default template, etc. https://github.com/histoire-dev/histoire/blob/7b4411f359dbf59bf4d6bda377bd47d38736ac45/packages/histoire-plugin-vue/src/client/app/Variant.ts#L47-L54

But I've never seen this pattern before, so I don't fully understand the flow of data (I'd love an explainer on the design and the data flow!) It also seems the wrongly injected properties ($data and whatever is declared in script setup) aren't used anywhere in the codebase, so why add them to the state at all?