You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Just open the stackblitz reproduction and check the console. You'll see:
[Vue warn]: onScopeDispose() is called when there is no active effect scope to be associated with.
In general though, you can cause the issue like so:
Create a detached effect scope before creating a regular vue VM
Do something in the run block of that scope (like lazily import a file with a store definition) that causes a Vue VM to be created
Call onScopeDispose()
What is expected?
The active scope tracking should be maintained, and not get "tricked" by not having an ancestor VM.
What is actually happening?
When setCurrentInstance(vm) is called, it passes prev as the vm argument, which is null. This leads to .off being called on the detached EffectScope that Vue 2.7 creates when a VM is initialized. This is not the detached scope that we created manually, mind you. And since .off is not supposed to be called on a detached EffectScope (it says this in explicitly in code comments), bad stuff happens and Vue's global activeEffectScope becomes undefined.
This doesn't currently happen in our app at runtime (though I think it easily could), it happens during our test suite. We try to be as lazy as possible in our test environment when it comes to the code that each test imports, because it substantially helps jest run time, especially when running individual test files. Because of this, we use the lazy option of the commonjs babel plugin. This means the Vuex store that would normally be instantiated before the detached effect scope ends up getting created after the detached effect scope. But I haven't seen anything in the Vue docs to say I shouldn't be able to create a detached effect scope before any other Vue VM, so I think this is a legitimate bug?
I'd be willing to work on a PR to fix this, but I'd need guidance, since my limited knowledge base of Vue's internals would probably mean any solutions I would try might break other things.
Update: Just adding a reference to related issue in Vue 3. Not sure how similar the internals of the effect scope implementation/tracking are, but right here@posva makes a comment that "you would never call off on a detached effect scope". But that does, indeed seem to be exactly what Vue 2.7 does. It seems like the buggy behavior the person who brought this up was worried about does indeed occur in some cases.
The text was updated successfully, but these errors were encountered:
Update: I don't actually see the reason why .off() is ever called on currentInstance._scope. From what I can see _scope is only ever assigned to a detached scope. The only assignment to that field I can find is in initMixin, where vm._scope = new EffectScope(true) is called.
Version
2.7.12
Reproduction link
Super slim repro on stackblitz
Steps to reproduce
Just open the stackblitz reproduction and check the console. You'll see:
[Vue warn]: onScopeDispose() is called when there is no active effect scope to be associated with.
In general though, you can cause the issue like so:
onScopeDispose()
What is expected?
The active scope tracking should be maintained, and not get "tricked" by not having an ancestor VM.
What is actually happening?
When
setCurrentInstance(vm)
is called, it passesprev
as thevm
argument, which isnull
. This leads to.off
being called on the detachedEffectScope
that Vue 2.7 creates when a VM is initialized. This is not the detached scope that we created manually, mind you. And since.off
is not supposed to be called on a detachedEffectScope
(it says this in explicitly in code comments), bad stuff happens and Vue's globalactiveEffectScope
becomesundefined
.This doesn't currently happen in our app at runtime (though I think it easily could), it happens during our test suite. We try to be as lazy as possible in our test environment when it comes to the code that each test imports, because it substantially helps jest run time, especially when running individual test files. Because of this, we use the
lazy
option of thecommonjs
babel plugin. This means the Vuex store that would normally be instantiated before the detached effect scope ends up getting created after the detached effect scope. But I haven't seen anything in the Vue docs to say I shouldn't be able to create a detached effect scope before any other Vue VM, so I think this is a legitimate bug?I'd be willing to work on a PR to fix this, but I'd need guidance, since my limited knowledge base of Vue's internals would probably mean any solutions I would try might break other things.
Update: Just adding a reference to related issue in Vue 3. Not sure how similar the internals of the effect scope implementation/tracking are, but right here @posva makes a comment that "you would never call
off
on a detached effect scope". But that does, indeed seem to be exactly what Vue 2.7 does. It seems like the buggy behavior the person who brought this up was worried about does indeed occur in some cases.The text was updated successfully, but these errors were encountered: