-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Improve Reactivity #230
Improve Reactivity #230
Conversation
@SimoTod - what do you think? I'm pretty sold on this, it took me 2 minutes to pull in and get working, it fixed the bugs I was aware of, including the issue your latest PR solved. I'd love it if you could pull this down and test for yourself. Also, do you think this warrants tagging 3.0? I'd rather make this a minor release, but I am fearful. Thoughts? |
If we can use an existing solid implementation, I'm down with that. |
@calebporzio I don't think this is a breaking change, 1kb is the same amount that other minor feature PRs have added (should be a minor bump) plus the reactivity system isn't exposed to the outside of AlpineJS right? The other question is IE11 support, does this library still work in IE11? |
src/component.js
Outdated
@@ -65,28 +68,25 @@ export default class Component { | |||
} | |||
|
|||
getUnobservedData() { | |||
let rawData = {} | |||
let unwrapedData = this.membrane.unwrapProxy(this.$data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo across this function
let unwrapedData = this.membrane.unwrapProxy(this.$data) | |
let unwrappedData = this.membrane.unwrapProxy(this.$data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thanks!
Playing devil's advocate here: isn't this against the "Alpine" philosophy ? I would actually expect to have an "alpinejs-reactivity-core" module that other frameworks could say "let's just use this small module to solve reactivity reliably for us" the same the dependency you're introducing does (but in an "alpinejs way"). Maybe this is not the popular comment, but I'd love to hear your thoughts about it. |
I'd semi-agree with you. I don't think there's anything wrong with using a 3rd party lib if it covers lots of edge cases and is more solid as @SimoTod mentioned, but I'd like the idea of having a separate Some benefits would involve making changes to the reactive core without needing a new release of Alpine, since the version constraints would always use the latest supported version of the core packages, unless the sub-packages are versioned inline with the parent Alpine repo, such as the |
Fair enough on the mono-repo argument. |
Interesting thoughts. Thanks everyone for pitching in. Good insight on this not being a breaking change. I won't tag it as such. As far as straying from the "Alpine Philosophy", I don't think a more reliable, third-party reactivity core strays from that. If we moved to a v-dom core, I would agree, but this to me is just an implementation detail. To your point though, I could see the argument for challenging the status quo and rolling our own, very small, "as-needed" reactivity core (like we were doing), but honestly, I'd rather spend our time making Alpine awesome than wrapping our heads around obscure Proxy workarounds. |
resolve(), | ||
filesize(), | ||
terser({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason you're dropping this?
The built alpine.js asset is now unminified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it only saves like .1KB
Seems not worth it to me. Unminified means way easier debugging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it's a good idea to leave it there for when the source code grows bigger. But we can add it later anyways. It's fine. Although @calebporzio this will break the code for people who used the CDN links previously. Should be removed starting from the next major release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing terser shouldn't remove code so not really a breaking change
Have you tried it with mangle: true, seems like that would save a bunch more size by renaming variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @HugoDF. Thanks for your comment. For some reason, I thought we already had a minified version of the alpine in the "dist" folder. But we actually didn't.
This was the "dist" content before merging this pull request.
https://github.com/alpinejs/alpine/tree/a6496895b4ddea560244c43e4e83407861814a70/dist
JSDeliver supports auto minifying (by adding ".min" before the file extension) so it's not actually needed at all. Sorry for my misleading statement @calebporzio
Regarding browser compatibility (@HugoDF), in the README.md file of observable-membrane, they specify the need of ECMAScript 6 This means no IE11 compatibility afaik. |
@iksaku I think the Proxy polyfill is included in the IE11 Alpine build |
hi @calebporzio I tried several examples and that library seems solid: All my old pens about proxy issues seem to work fine and another couple of things I tried locally where working as expected. The only thing I noticed (It's not an existing feature, just a branch I was working on), is that object are not reactive if you change their state using functions. This is the example using the new lib: https://codepen.io/SimoTod/pen/eYNGLwK It doesn't fix #144 and #158 but those are related to the extraVars object, really. I'm personally not against dependencies if they allow you to focus on other features. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(one more review comment) it seems deepProxy
is still being imported into component
despite having been deleted 😄
Thanks for all the input. The typo and unused import are fixed. Merging! |
@calebporzio I think you just merged/released with unminified |
@HugoDF see his comment here: #230 (comment) |
@philippbosch thanks for pointing that out, I raised an issue/created a PR for IE11 build being broken |
@HugoDF yeah, I saw that. I'm also relying on the IE11 build so thanks for that!! |
This PR swaps the hand-rolled Proxy-based reactivity core in Alpine for Saleforce's "observable-membrane" library: https://github.com/salesforce/observable-membrane
Reasoning: Solving the current Alpine reactivity issues feels like playing bug whack-a-mole for the project. With every issue, we have to dig deeper into JS Proxies and add extra conditionals to the Proxy core.
By using this off-the-shelf lib, we are accepting the cost of an extra ~1kb min/gzipped added to Alpine very small size, AND adding our first real JS dependancy, but in return, we are getting reliability and peace of mind.
There are other packages out there for this, specifically: https://github.com/nx-js/observer-util
But that package hasn't been touched since May of 2019, and this one is maintained by Salesforce which is a giant company that presumably uses this same lib in their "Lightening Web Components" framework core. I'm much more confident that it'll stick around and get maintained.
This concept of a "Proxy-based Object Membrane" is the exact concept behind the new VueJS 3 reactivity core. It looks like they hand-rolled their core, but in the README, they said it was heavily inspired by these packages.
I think this is a step in the right direction for Alpine.