Fix property mangling and implement ES5 compatibility properly #442
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR re-introduces the changes from d781b16 in a way that I'm pretty certain won't break anything this time. It makes Ziggy's default build ES5-compatible.
TLDR: internal-only property getters like
get _location()
are mangled by Terser in a way that breaks them, so I changed our one internal getter to a regular method,_location()
. It's now mangled correctly, so it's not publicly accessible but everything still works.Closes #441, and closes #440 properly.
I'm not 100% sure what the root issue is here, but I'm pretty close and I'm sick enough of bundlers to stop playing with it now. This is what I've found so far:
JavaScript classes like Ziggy's
Router
are transpiled to a combination of objects with custom prototypes and functions to make them ES5 compatible, which looks kind of like this with microbundle's Babel setup:Notice that the methods become real properties of the Router object (because microbundle uses Babel's
loose
mode), while the_location
getter is represented by an object with its key and a backingget
function. Importantly, the properties and methods of the Router object are not represented by strings—current
and_privateCurrent
are real JavaScript tokens.Terser, which
microbundle
runs our code through after Babel transpiles it, mangles properties and methods starting with_
to shorten their names and make them inaccessible publicly. However this mangling obviously ignores strings, since mangling strings, like'here'
or'there'
, would destroy the functionality of the code.Terser's output looks kind of like this, but more optimized and a lot harder to read:
_privateCurrent
is mangled tocur
everywhere it appears, shortening it's actual name and all calls to it, and thelocation
method's internalthis._location
call is mangled tothis.loc
, but for the same reason that it doesn't mangle'here'
and'there'
, Terser doesn't mangle the"_location"
key for that getter! Because its key is a string,_location
doesn't get renamed properly, which is whythis.loc
doesn't exist when Ziggy later tries to call it from thecurrent()
method orparams
getter.There might be a 'better' fix for this but it almost definitely involves setting up our own custom Rollup build, which I don't feel like doing this weekend 😅 for now, making
_location
a method solves this problem.