SSR watchEffect onInvalidate issue (Cannot access 'runner' before initialization)
See README in https://github.com/tjk/watcheffect-runner-bug
Version
3.0.6
Reproduction link
https://github.com/tjk/watcheffect-runner-bug
Steps to reproduce
git clone https://github.com/tjk/watcheffect-runner-bug
cd watcheffect-runner-bug
yarn
yarn dev
Then hit http://localhost:3000
What is expected?
No error
What is actually happening?
Error
During SSR, we return from doWatch
before runner
is initalized, but onInvalidate
still references it, which throws this error.
Think we need to initialize it eagerly with let runner
and also check for it to be set during onInvalidate
execution before accessing runner.options
.
But i have no idea how to write a test for this ...
I have no idea what I'm doing but I think this test is working --
// XXX find a way to not double setup and just generally not do this so hackily
it('effect onInvalidate succeeds in ssr context', (done) => {
let instance: ComponentInternalInstance | null
const noop = () => {}
const Comp = defineComponent({
setup() {
if (!instance) {
instance = getCurrentInstance()
} else {
watchEffect((onInvalidate) => {
expect(() => onInvalidate(noop)).toThrow(ReferenceError)
done()
})
}
},
render: noop,
})
createApp(Comp).mount(nodeOps.createElement('div'))
setupComponent(instance!, true /* isSSR */)
})
Started a PR https://github.com/vuejs/vue-next/pull/3323 for someone who understands better to fix up. Thanks for the guidance @LinusBorg.