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

$setup.bar is not a function with script setup #4599

Closed
henribru opened this issue Sep 15, 2021 · 3 comments · Fixed by #4608
Closed

$setup.bar is not a function with script setup #4599

henribru opened this issue Sep 15, 2021 · 3 comments · Fixed by #4608
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working scope: compiler scope: script-setup

Comments

@henribru
Copy link

henribru commented Sep 15, 2021

Version

3.2.11

Reproduction link

github.com

Steps to reproduce

Run npm run serve in the reproduction repository, go to http://localhost:8080/ and check the dev console

What is expected?

The code should work fine and we should see "Hello World" in the browser

What is actually happening?

I get an error about $setup.bar is not a function in the dev console

@edison1105
Copy link
Member

works fine in sfc, It's not a vue core bug. Maybe relate to vue-loader.

@LinusBorg
Copy link
Member

LinusBorg commented Sep 16, 2021

The compiler fails to detect that bar is actually used in the template. It seems to not handle the inline class expression correctly.

The error must be somewhere in this function:

https://github.com/vuejs/vue-next/blob/a6e5f82d8ea5fe55432d0277e88300045eca4237/packages/compiler-sfc/src/compileScript.ts#L1779-L1779

More specifically, it likely strips out the bar() call somewhere in this stripStrings function:

https://github.com/vuejs/vue-next/blob/a6e5f82d8ea5fe55432d0277e88300045eca4237/packages/compiler-sfc/src/compileScript.ts#L1824

It's not just the function signature though, as it works for a simple interpolation like {{ bar() }}.

PS: The repo project doesn't use the inlineTemplate compiler option while the SFC playground does, which explains why it works on the playground - in inlineTemplate mode, the compiler doesn't have to detect usage of imports in the template.

@LinusBorg LinusBorg added 🐞 bug Something isn't working scope: compiler scope: script-setup 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. and removed 🐞 bug Something isn't working scope: compiler scope: script-setup labels Sep 16, 2021
@LinusBorg
Copy link
Member

LinusBorg commented Sep 16, 2021

Okay, got it. It's actually the empty string that is tripping up stripStrings. If you use a non-empty Sting like so, it works:

<div
    :class="[
      foo ? 'xxx'  : bar(),
      'foo',
    ]"
  >

The issue is that the regex in stripStrings only matches if the quotation marks contain at least one character. This would be a fix to the issue but right now I'm not sure about potential side effects:

function stripStrings(exp) {
    return exp
-        .replace(/'[^']+'|"[^"]+"/g, '')
+        .replace(/'[^']*'|"[^"]*"/g, '')
        .replace(/`[^`]+`/g, stripTemplateString);
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working scope: compiler scope: script-setup
Projects
None yet
3 participants