I cannot use Libraries using read-only variables in the core without `markRaw`
Version
3.2.29
Reproduction link
Steps to reproduce
- Import a library that uses read-only variable in the core
- An error occurs during startup
The minimal reproduction mocks a library that is using read-only variables.
Note that in a real-world use case, reactive
is not explicitly called. For example, in this codesandbox showcasing the issue with the bpmn-js
library: https://codesandbox.io/s/epic-swartz-zttbr?file=/src/App.vue:1854-1895
What is expected?
- I can use JS libraries out of the box
What is actually happening?
- an Error is thrown
- I have to use
markRaw
Maybe it is possible to check if an Object is writable before proxying it. I sketched a solution below:
var obj = {};
Object.defineProperty(obj, 'foobar', {
value: {}
});
// Proxy Config /////////
var proxy = new Proxy(obj, {
get(target, property) {
var writable = (Object.getOwnPropertyDescriptor(obj, property) || {}).writable;
if (writable) {
return new Proxy(target[property], {});
}
else {
// would throw if we proxy read-only values
return target[property];
}
}
});
console.log(proxy.foobar);
I would say using markRaw()
is expected: https://v3.vuejs.org/api/basic-reactivity.html#markraw
If it is expected, would it be possible to throw a more expressive error message? Currently, users just get a rather cryptic property 'foo' is a read-only and non-configurable
. They then assume it is a problem with the library, as the Error is thrown from there. Example.
I would expect a descriptive error message that makes possible fixes more clearer. This would improve the experience for both the library users and devs.
Checking for potential readonly properties requires calling Object.getOwnPropertyDescriptor
on every Proxy trap call, which I suspect is going to be too expensive even in dev mode.
In general, you should avoid making complex 3rd party objects reactive - i.e. don't return it from data()
- there's no point in doing so. Just set it on this
in created()
.