storybook [Bug]:如果我们将一个函数传递给参数,则显示代码已损坏(Vue3)

nvbavucw  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(62)

描述bug

你好,
我正在将一个大型的storybook(vite,vue3和typescript)从版本7迁移到8。
在故事中,他们使用了很多带有console.log()的函数来记录是否调用了带有回调函数的props。

export const showCodeBroken: Story = {
  args: {
    callbackFunction: () => {
      console.log('log callback');
    },
  },
};

这个用法在版本8中破坏了文档页面中的代码显示(使用docgen:vue-docgen-api或vue-component-meta)。
show code 在版本7中是有效的。

复现链接

https://stackblitz.com/edit/github-zwdpby?file=src%2Fstories%2FButton.stories.ts

复现步骤

转到: https://stackblitz.com/edit/github-zwdpby?file=src%2Fstories%2FButton.stories.ts
点击故事的代码显示 Show code broken

代码为空。
开发者控制台中还有错误。

githubzwdpby-ycm0--6…utton--docs&args=:1 Uncaught (in promise) SyntaxError: Opening tag "Button" not terminated. (3:2)
    at fo (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:2638:11)
    at Hs (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:2831:9)
    at Vs (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:2779:16)
    at Us (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:2834:221)
    at Object.parse (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:2854:29)
    at co2 (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:4549:17)
    at async qn2 (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:5168:29)
    at async Xt2 (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:5234:198)
    at async Object.cu (formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:5358:26)
    at async formatter-2WMMO6ZP-LTB2HDVI.js?v=453fcf9c:5399:158
Promise.then (async)
(anonymous) @ chunk-HTCFZXJC.js?v=453fcf9c:1966
commitHookEffectListMount @ chunk-BOZK2MRR.js?v=453fcf9c:16936
commitPassiveMountOnFiber @ chunk-BOZK2MRR.js?v=453fcf9c:18189
commitPassiveMountEffects_complete @ chunk-BOZK2MRR.js?v=453fcf9c:18157
commitPassiveMountEffects_begin @ chunk-BOZK2MRR.js?v=453fcf9c:18147
commitPassiveMountEffects @ chunk-BOZK2MRR.js?v=453fcf9c:18137
flushPassiveEffectsImpl @ chunk-BOZK2MRR.js?v=453fcf9c:19518
flushPassiveEffects @ chunk-BOZK2MRR.js?v=453fcf9c:19475
commitRootImpl @ chunk-BOZK2MRR.js?v=453fcf9c:19444
commitRoot @ chunk-BOZK2MRR.js?v=453fcf9c:19305
performSyncWorkOnRoot @ chunk-BOZK2MRR.js?v=453fcf9c:18923
flushSyncCallbacks @ chunk-BOZK2MRR.js?v=453fcf9c:9135
(anonymous) @ chunk-BOZK2MRR.js?v=453fcf9c:18655

系统

Storybook Environment Info:
 
  System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm <----- active
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    @storybook/addon-essentials: ^8.2.0-alpha.3 => 8.2.0-alpha.3 
    @storybook/addon-interactions: ^8.2.0-alpha.3 => 8.2.0-alpha.3 
    @storybook/addon-links: ^8.2.0-alpha.3 => 8.2.0-alpha.3 
    @storybook/blocks: ^8.2.0-alpha.3 => 8.2.0-alpha.3 
    @storybook/test: ^8.2.0-alpha.3 => 8.2.0-alpha.3 
    @storybook/vue3: ^8.2.0-alpha.3 => 8.2.0-alpha.3 
    @storybook/vue3-vite: ^8.2.0-alpha.3 => 8.2.0-alpha.3 
    storybook: ^8.2.0-alpha.3 => 8.2.0-alpha.3

附加上下文

  • 无响应*
bkhjykvo

bkhjykvo1#

我正在面临这个问题,storybook版本^8.0.9。我发现问题出在如何处理函数属性上。当我使用静态构建时,这个问题只会出现,但在使用开发服务器时,它可以正常工作,这就是为什么我能看到问题的原因。

以下是发生的情况的代码示例:

故事定义:

export const Default = {
    args: {
        somePropWhichIsPlainText: "hello world",
        somePropWhichIsAJavaSciptValue: 9,

        // the error also happens if you declare a function and reference it here, not only when using arrow functions
        somePropWhichIsAFunction: () => { alert('hello world'); } 
    }
}

这是在Storybook <Source />组件中输出的代码(即点击“显示代码”时显示的内容)

<template>
    <ExampleComponent
        some-prop-which-is-plain-text="hello world"
        :some-prop-which-is-a-java-script-value="9"
        some-prop-which-is-a-function="() => {
alert('hello world');
}"
    />
</template>

请注意,在some-prop-which-is-a-function前面没有冒号。这意味着该属性是多行字符串,解析器似乎对此有问题。这导致了“没有关闭标签”的错误。除了解析器无法处理这个值之外,它还无法创建一个有效的v-bind绑定,因此无法调用该函数(其类型为string,而不是function)。

解决方法是为故事使用显式的渲染函数,以确保将函数属性作为函数传递。

解决方法的故事代码:

export const Default = {
    render: (args) => ({
        components: { ExampleComponent },
        setup: () => {
            function somePropWhichIsAFunction() {
                alert('hello world');
            }
            return { args, somePropWhichIsAFunction };
      },
      template: '<ExampleComponent v-bind="args" :some-prop-which-is-a-function="somePropWhichIsAFunction" />'
    }),
    args: {
        somePropWhichIsPlainText: "hello world",
        somePropWhichIsAJavaSciptValue: 9

        // do not pass the function prop here, only place it in the render function
    }
}

注意,这对于嵌套在其中的对象或数组属性也是必需的。

相关问题