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

Not working with Vue 3.0.3 and latest <script setup> #263

Closed
lmiller1990 opened this issue Nov 30, 2020 · 11 comments
Closed

Not working with Vue 3.0.3 and latest <script setup> #263

lmiller1990 opened this issue Nov 30, 2020 · 11 comments

Comments

@lmiller1990
Copy link
Member

Related: vuejs/vue-jest#304

Seems 3.0.3 breaks test utils. The return value either here and here are different to normal.

I am not sure if we should fix this right now, or wait for the <script setup> to stop been so experimental. It's important to let people try the latest features, but I am not sure <script setup> is meant for production yet - thoughts?

@lmiller1990
Copy link
Member Author

Here is my analysis:

  • new <script setup> introduced in 3.0.3. It breaks things.

Using [email protected] and the same version of compiler-sfc with this component works:

<script setup lang="ts">
// imported components are also directly usable in template
import { ref } from 'vue'

// write Composition API code just like in a normal setup()
// but no need to manually return everything
export const count = ref(0)
export const inc = () => { count.value++ }
</script>

<template>
  <button @click="inc">{{ count }}</button>
</template>

To make this work with the new <script setup> you just need to remove export from count and inc - those are automatically exposed. Doing that, then upgrading to [email protected] breaks things.

If you do a log here on [email protected] you get:

vm { __emitted: {} }

And here:

App { count: [Getter/Setter], inc: [Getter/Setter], __emitted: {} }

With [email protected]:

vm { __emitted: {} }

and:

App {}

Seems this line is where things break. vm.$refs[MOUNT_COMPONENT_REF] is not returning the expected vm.

@martinszeltins
Copy link

Related: vuejs/vue-jest#304

Seems 3.0.3 breaks test utils. The return value either here and here are different to normal.

I am not sure if we should fix this right now, or wait for the <script setup> to stop been so experimental. It's important to let people try the latest features, but I am not sure <script setup> is meant for production yet - thoughts?

I am actually using the new <script setup> syntax in a production app already. So I think we should fix it now. The RFC was well discussed and approved by the community.

@afontcu
Copy link
Member

afontcu commented Nov 30, 2020

new <script setup> implementation is literally listed under "Experimental Features" on release docs: https://github.com/vuejs/vue-next/blob/master/CHANGELOG.md#experimental-features

@lmiller1990
Copy link
Member Author

While I prefer to be conservative generally, I think the right move is to support this RFC as soon as possible. If people cannot try it out, it'll be difficult for Evan and co. to get feedback. Some people might get surprised when they update from 3.0.2 to 3.0.3 and things break... well, that is the cost of using an experiemental feature. 🤷‍♂️ #264 should not impact anyone using the regular options or composition APIs.

@lmiller1990
Copy link
Member Author

Users wanting to use this feature should install the latest vue-jest: https://github.com/vuejs/vue-jest/releases/tag/v5.0.0-alpha.7. Run yarn add vue-jest@next.

@lmiller1990
Copy link
Member Author

They are both out.

@martinszeltins give this a try and see how you go. It works for the basic example given in the RFC, I do not have a large code-base using <script setup> to test this more thoroughly.

@afontcu
Copy link
Member

afontcu commented Dec 1, 2020

I think the right move is to support this RFC as soon as possible

Agree on that! Just wanted to point out that these are, in fact, experimental features, so even if we decide to provide support as soon as possible, people need to be aware what's the current situation with them, and expect some breaking changes from time to time 😉

Nice work tracking down the issue!

@chojnicki
Copy link

chojnicki commented Mar 9, 2021

@lmiller1990 Are You sure this is 100% fixed? I'm missing something?

I was not able to use/mock custom store build with composition api. No matter what I did, my store was undefined, but it works on live. So I just did console.log('wrapper.vm'). And my store does not exist in component vm even that my IDE/TS correctly autocomplete it.

So I added just dummy consts data, and they also do not show up. Then I changed my component to standard exported setup() and voila - it works. So for me there is still problem with <script setup> syntax.

I'm missing some simple option on mount() or something? I spend literally hours trying to debugging this and find solution in issues, docs etc.

Reproduction code:

import { mount } from '@vue/test-utils'
import Model from '@/components/Demo.vue'

it('demo', () => {
  const wrapper = mount(Model)
  console.log(wrapper.vm)
})

This works:

<script lang="ts">
export default {
  setup() {
    const demo = () => {
      console.log('demo')
    }
    const demo2 = 'demo2'

    return {
      demo, demo2,
    }
  },
}
</script>
  console.log
    {
      demo: [Getter/Setter],
      demo2: [Getter/Setter],
      hasOwnProperty: [Function (anonymous)]
    }

This does not:

<script setup lang="ts">
const demo = () => {
  console.log('demo')
}
const demo2 = 'demo2'
</script>
  console.log
    { hasOwnProperty: [Function (anonymous)] }

Latest vue, vue-test-utils, vue-jest.

@lmiller1990
Copy link
Member Author

I think this is an intended part of the <script setup> RFC. It's worded quite confusingly, but see this part.

... therefore a component using <script setup> will be closed by default. That is to say, its public imperative interface will be an empty object ...

Follow up question: if you do console.log(wrapper.html()), does it show the HTML?

@chojnicki
Copy link

chojnicki commented Mar 9, 2021

@lmiller1990 Yes, it does. All my components template works great, I just cannot access anything from script.

Ok so I guess I'm using expect() with <script setup> wrong? Now trying to find way to expose it, since expose() from RFC is not implemented yet I think. Some workaround is needed for vue-test-utils, and I just hope it already exists because I do not believe that I'm first person doing this ;)

expect(wrapper.vm.demo).toHaveBeenCalled()

It of course works fine without setup.

P.S Thanks for that fast reply!

@lmiller1990
Copy link
Member Author

lmiller1990 commented Mar 10, 2021

You are definitely not the first person to try this: #435

Slight tangent, it feels like a bit of a code smell if you need to expose internals for testing - you cannot make an assertion based on the DOM state?

I am not really a fan of the "closed by default" behavior. Well, I am, but I don't like how it's different to regular component. I think they should be consistent.

I posted about this in the RFC for script setup. You can follow there if you are interested.

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

4 participants