-
Notifications
You must be signed in to change notification settings - Fork 113
private fields will break vue/mobx #227
Comments
Duplicate of #106 |
Can't the |
Huh, my prediction was true. In the end of this #158 (comment) I said (in few other places I also mentioned it):
I bet that we'll see more issues of such type.
@nicolo-ribaudo, I don't know internals of BTW, if you want I may create small repo with this pattern showcase and tests, so you won't need to check how Vue/MobX/Aurellia/MetaF works in order to understand our requirements to this proposal. /cc @littledan, @ljharb, @erights |
@nicolo-ribaudo If you were thinking that this is ok because calling against the "receiver" is what should happen anyway since that was the class instance, there are many scenarios where doing so would result in overflowing the stack. Compound this with the reasonable expectation that anything written to the Proxy instance is applied to the internal instance unless interfered with by handler functions, and that Proxy cannot interfere with private-fields, and you've got a recipe for spontaneous failures and confusing misunderstandings. Just my 2¢, but this is the kind of thing you expect to have happen when emotional and rational concerns outweigh logical concerns when designing a language or its features. Failure of a new feature to be compatible with all non-competing, non-conflicting existing features constitutes a design flaw. Allowing such a flaw to further infect post-facto features in perpetuity just because it's already there is just adding insult to injury. |
I've reached out to the Vue maintainers to see if we can address this issue along the lines @nicolo-ribaudo suggested. |
Turns out it's working for us! Thanks to @nicolo-ribaudo for the idea! |
@littledan Is there any particular impact to the proposal should a major framework be found for which no such simple solution is applicable? |
As I understand it, that technique won't work for Aurelia since we're based on vanilla JS component classes. The component class is fully under the control of the developer. We don't (and won't) require a base class, as it's antithetical to our software design philosophy. We can provide some documentation and potential workarounds for our community. However, I still feel that the private fields/proxy integration story is flawed. |
I'm still hopeful we can get a class Foo {
#bar
constructor() {
this.#bar = 12
}
getBar() {
return this.#bar
}
}
const p = new Proxy(new Foo(), {
target(target) {
return target // By default target is the Proxy itself
},
})
p.getBar() // 12, just works From what I recall the way it works is simply that |
I would expect it to work for all internal slots if such a thing existed. |
Was there some reason that we couldn't do this and make this enhancement to Proxy a necessary part of the private fields spec? |
It’s a preexisting problem. It makes more sense to solve it in parallel. |
My concern is browsers implementing private fields without the associated Proxy feature to prevent runtime errors. It seems that if private fields cause the issue with proxies, then the Proxy enhancement should be implemented along with private fields by browser manufacturers. |
@EisenbergEffect user code can cause the same issue right now by using WeakMaps, closures, and/or by extending builtins with internal slots. Private fields are just a new manifestation of a pre-existing issue with certain Proxy usage patterns. |
I hope to find time soon to investigate the Aurelia case further. Sorry for my delay here. |
For:
This has been mentioned and argued several times, and probably most recently is by @jods4 at
|
Please understand that unlike with private fields, the issues in question when using WeakMaps and closures is perfectly resolvable in user-land code. However, there is no possible solution in user-land code when dealing with private fields. Even Babel's implementation of private fields can be made to work where native private fields will break. |
@littledan, in order to simplify your understanding of Aurelia (and other library authors like me) issue, I've created very minimal implementation of If you run tests, you'll see that it works in 2 from 3 cases: If you have any question regarding |
@ljharb, you missed that there are normal workarounds:
Why do you repeat this again and again? We know this very limited number of cases and there are KNOWN WAYS how to handle them. P.S.Don't forget that scale is essential, and amount of breaking |
@Igmat, I know that the Aurelia issue exists. What I don't yet understand is all the context that led to its different design decisions. |
One of the most important things that Aurelia values is unobtrusveness. We hold a strong belief that your code should be at the center of your app, rather than the framework. So, we've worked very hard to not require things like a base class for components or decorators on observable properties. These would couple core application code to the framework, which we see as bad for businesses in the long run. The context for that is many, many years of building many apps for many companies and seeing the negative effects of frameworks and libraries that do not take that approach. |
@littledan Just out of curiosity, why is "the context that led to its different design decisions" at all relevant? Isn't the reality that different design decisions were made at all reason enough to add value to the fact that this proposal allows Proxy to be an unsolvable problem? Aurelia isn't the only code that is going to suffer over this completely impassable issue. Another thing: providing encapsulation is great. However, what good is it when it comes at the cost of functionality that is arguably considered even more useful? Encapsulation vs reliable inheritance (since both base class and derived class accessors could break)? Encapsulation vs monitoring (since non-Membrane like Proxy usage will break)? Encapsulation is not meant to be pitted against other non-competing paradigms. Yet that's precisely what this proposal offers. It isn't that there isn't another approach that doesn't make these kinds of technical trade-offs, but rather that non-technical points of interest were deemed more valuable. Technical problems like this with no reasonable solution are the result of that evaluation. |
I think we're running into core Proxy design decisions, which made it not well-suited to usage patterns like this. If you expect to be able to wrap something in a Proxy from the outside and make that Proxy not unwrap to the target when calling methods, various things will break. This isn't just WeakMaps, but even something as simple as |
This problem is also known, but in most cases it doesn't affect anything, since library authors just enforce that targets interacts in one space and proxies in another one, so
Just check repo I mentioned before - there are no other ways to solve this problem, unless you provide totally new API other then Proxy for this pattern. |
@littledan Sure, there are issues with the core design of Proxy. Fairly large ones in fact. However, in current ES, every one of those issues is either irrelevant in most cases or resolvable using user-land code. This is the point everyone is trying to get through to you. What is currently solvable becomes conclusively unsolvable with no work arounds possible given the introduction of private fields. The only work around is not to use private fields. However, that becomes problematic because libraries like Aurelia, and so much other code, are designed to interact with code outside of the control of those libraries. If an object containing private fields gets wrapped in a non-membrane-like proxy, access to private fields will fail. Full Stop. If there was a work around for this that allowed for Proxy and private fields to be used together, I'm sure you wouldn't be receiving nearly as much push back on this issue. It might be a good idea to be more open to doing at least one of following 3 things:
|
Closing as a duplicate of #106. |
Maybe I'm missing something but:
|
Can you share an example? |
okay, so this was my misunderstanding, and apparantely, it works:
|
https://github.com/vuejs/rfcs/blob/class-api/active-rfcs/0000-class-api.md#usage-with-private-fields
The text was updated successfully, but these errors were encountered: