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

Invalid assignment target in v-model data binding with type assertion when building for production #12620

Closed
kingyue737 opened this issue Dec 26, 2024 · 5 comments

Comments

@kingyue737
Copy link

kingyue737 commented Dec 26, 2024

Vue version

3.5.13

Link to minimal reproduction

https://stackblitz.com/edit/github-4n1bjaud

Steps to reproduce

  1. Add type assertion in v-model, for example, v-model="foo as any"
  2. npm run build

What is expected?

Project successfully building for production.

What is actually happening?

type assertion is not removed:
image

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (6) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    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
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    vue: latest => 3.5.13

Any additional comments?

It works fine in development.

Very similar to #8306

@edison1105
Copy link
Member

edison1105 commented Dec 27, 2024

It seems related to https://github.com/unjs/unimport. This issue only occurs when the ref is not imported, see Playground. If the ref is explicitly imported, it works fine, see Playground

The following code will work as expected.

<script setup lang="ts">
+import { ref } from "vue";
const data = ref(1);
</script>

<template>
  <div>
    <FooBar v-model="data as any" />
  </div>
</template>

@kingyue737
Copy link
Author

Thanks! I forgot Playground can be run in production mode. It is much easier to reproduce!

@noootwo
Copy link
Contributor

noootwo commented Jan 7, 2025

I do some research, I set a breakpoint during unimport initialization, but it never reached the breakpoint before the program crashed.
This error is threw by esbuild, before unimport do anything.

And I find this, when v-model without as any, the template is compiled as:
image

When with as any, the template is compiled as:
image
In this case, this grammar ((_unref(data) ) = $event) is not standard in ECMAScript, and the error Invalid assignment target also points to this line.

So, is this should do some fix in vue? @edison1105

@edison1105
Copy link
Member

edison1105 commented Jan 7, 2025

@noootwo

I do some research, I set a breakpoint during unimport initialization, but it never reached the breakpoint before the program crashed.

This is the exact reason for the problem. unimport should automatically import ref before the Vue code compilation, but it does not. Maybe it's enforce should be pre rather than post. see https://github.com/unjs/unimport/blob/6d1076fff99a4ec586b8e81f1f5671a5fd988473/src/unplugin.ts#L48

Vue analyzes the variable types during compilation, if ref is not imported, then the type of data is setup-maybe-ref. If ref is explicitly imported, the type of data is setup-ref. The type of data is important as it determines whether unref(data) or data.value is required to access it in the render function. Additionally, without unimport, ref must be imported from vue before use, otherwise it will cause a runtime error, right? Therefore, I don't think this issue needs to be fixed by Vue.

@noootwo
Copy link
Contributor

noootwo commented Jan 8, 2025

@noootwo

I do some research, I set a breakpoint during unimport initialization, but it never reached the breakpoint before the program crashed.

This is the exact reason for the problem. unimport should automatically import ref before the Vue code compilation, but it does not. Maybe it's enforce should be pre rather than post. see https://github.com/unjs/unimport/blob/6d1076fff99a4ec586b8e81f1f5671a5fd988473/src/unplugin.ts#L48

Vue analyzes the variable types during compilation, if ref is not imported, then the type of data is setup-maybe-ref. If ref is explicitly imported, the type of data is setup-ref. The type of data is important as it determines whether unref(data) or data.value is required to access it in the render function. Additionally, without unimport, ref must be imported from vue before use, otherwise it will cause a runtime error, right? Therefore, I don't think this issue needs to be fixed by Vue.

Ok, I understand what you mean. Thanks!

@edison1105 But there is one thing I don't quite understand:
In the two cases I mentioned, the only difference is whether it includes as any, all other conditions are consistent, but the compile results are different.
Is this also expected result? In my feel, the as any just is types, it seems that it should not have an impact on compilation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants