Hello,
It seems that after the transition to rollup and newer features, alpinejs is not working in IE11 with the current polyfills.
I am getting the error:
Expected ')'
at this line in utils.js
export function walkSkippingNestedComponents(el, callback, isRoot = true) {
I then tested on a branch after the transition to rollup (1.1.3) and got it to work by changing babel.config.js to the following
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
browsers: "> 0.5%, ie >= 11"
},
modules: false,
spec: true,
useBuiltIns: "usage",
forceAllTransforms: true,
corejs: {
version: 3,
proposals: false
}
}
]
]
};
this increases the build size, but gets it to work for testing purposes.
I then tested the same configuration on the current build (1.7) and I now get the following error
Uncaught (in promise) TypeError: Cannot create property for a non-extensible object
Seems like an error with the proxy polyfill when researching that error.
<script src="https://cdn.jsdelivr.net/npm/[email protected]/proxy.min.js"></script>
I also tested by adding Laravel Mix back and the same object error still occurs.
Wondering if anyone else has gotten a recent build to work with IE11?
Thanks.
it seems that the proxy polyfill issue happened with commit https://github.com/alpinejs/alpine/commit/1ddb8941b6790c8e5639884cbf674497cba6cd71
Uncaught (in promise) TypeError: Cannot create property for a non-extensible object
Perhaps with the expansion of the $refs functionality
Up until version 1.5, the adjustment below to the rollup.config.js file can create 2 different versions of Alpine (alpine.js and alpine-ie11.js), one that can be used with regular browsers and one for IE11. This seems to solve the error
expected ')' .
It doesn't solve the first error
Uncaught (in promise) TypeError: Cannot create property for a non-extensible object
rollup.config.js
import babel from 'rollup-plugin-babel';
import filesize from 'rollup-plugin-filesize';
import {
terser
} from "rollup-plugin-terser";
import resolve from "rollup-plugin-node-resolve"
export default [{
input: 'src/index.js',
output: {
name: 'Alpine',
file: 'dist/alpine.js',
format: 'umd',
sourcemap: true,
},
plugins: [
resolve(),
filesize(),
terser({
compress: {
drop_debugger: false,
},
}),
babel({
exclude: 'node_modules/**',
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
})
]
},
{
input: 'src/index.js',
output: {
name: 'Alpine',
file: 'dist/alpine-ie11.js',
format: 'umd',
sourcemap: true,
},
plugins: [
resolve(),
filesize(),
terser({
compress: {
drop_debugger: false,
},
}),
babel({
babelrc: false,
exclude: 'node_modules/**',
presets: [
[
"@babel/preset-env",
{
targets: {
browsers: "> 0.5%, ie >= 11"
},
modules: false,
spec: true,
useBuiltIns: "usage",
forceAllTransforms: true,
corejs: {
version: 3,
proposals: false
}
}
]
]
})
]
}
]
I'm also struggling with this issue. I hope a solution get's worked out as I support IE11.
@keyurshah Not sure if it helps (I can't try myself because I'm a Mac user) but I believe it's because the polyfill doesn't allow the definition of new properties for the Proxy once created.
In their github page, they say: The polyfill supports just a limited number of proxy 'traps'. It also works by calling seal on the object passed to Proxy. This means that the properties you want to proxy must be known at creation time.
From that commit, we create a proxy for the data object then we try to add additional properties at line 17-31.
Can you try to comment those lines out and see if it removes the error?
Obviously there will be other parts that will not work since I assume those variables are used later on, but it would be good to see if that is the reason why it stopped working.
@SimoTod thanks! that seemed to work when commenting out lines 17-31
A test branch is here with those changes.
https://github.com/keyurshah/alpine/tree/test-1.6-merge
As you said, other functionality will break once doing that.
The following tests do not pass after the changes
el.spec.js
ref.spec.js
lifecycle.spec.js
next-tick.spec.js
appreciate your help!
Yeah, we need to assess if those variables are required in the proxy object or they can be stored somewhere else (i.e. this) and retrieved from there. I've a gut feeling saying that it won't be easy, though.
@keyurshah you can try moving those lines before line 15 (but after line 13).
It looks like it should work and pass the tests.
Basically, without that code you won't be able to use $refs, $el and $nextTick in your alpine callbacks (see https://github.com/alpinejs/alpine/#magic-properties).
Let me know how it goes.
got it working similar to past versions with your suggestions! With these changes it seems usable again, but there are some preexisting bugs it seems.
Also, Given these known limitations from master, what’s the best way to manage the file differences? Maintain a separate branch or repo?
I started with the current version and commented out lines 20-26 in component.js
// After making user-supplied data methods reactive, we can now add
// our magic properties to the original data for access.
// unobservedData.$el = this.$el
// unobservedData.$refs = this.getRefsProxy()
// this.nextTickStack = []
// unobservedData.$nextTick = (callback) => {
// this.nextTickStack.push(callback)
// }
I tested the component below on prior versions of alpine, such as 0.4.0 and the same error occurred in that version as well. So it's not an error particular to the newest modified version only.
For example, If both checkboxes are checked, it should show ["foo","bar"] but it shows only ["foo"]
<div x-data="{ checkbox: ['foo'] }">
Checkbox:
<span x-text="JSON.stringify(checkbox)"></span>
<input type="checkbox" x-model="checkbox" value="foo">
<input type="checkbox" x-model="checkbox" value="bar">
</div>
Syntax Error
utils.js (80,88)
utils.js line where error occurred
export function saferEvalNoReturn(expression, dataContext, additionalHelperVariables = {}) {
this component works correctly
<div x-data="{ text: 'foo'}">
Text:
<span x-text="JSON.stringify(text)"></span>
<input type="text" x-model="text">
</div
@keyurshah I sent you a patch that should allow you to recover some of those bugs.
Probably there's still something broken, I can't test it much by myself so I need you to check on IE11.
If you get to the point were there are no regression in chrome/firefox and IE is 90% working (maybe documenting what is missing) you can probably try to send a PR. The biggest impediment is the file size but I think that configuring the compiler to create 2 versions (standard and IE11 for those who need it) is not a bad idea and it won't bother other users that much.
You should probably check with Caleb if he's happy with this strategy, though.
Also, the readme needs updating if ever your patch will make to master.
Good luck
Thank you so much for your hard work @SimoTod !
The tests are passing and a majority of the functionality seems to work well on this branch with your PR
This other branch is updated with the current master (had to change walkSkippingNestedComponents to walkAndSkipNestedComponents)
The items that don't seem to work:
$refs object inside x-on or in a function gives an error. The example below gives an undefined error<div x-data="{}">
<div x-ref="foo">bar</div>
<button x-on:click="console.log($refs.foo.innerText)">Click Here</button>
</div>
Argument not optional) - utils.js - line 157x-ifMost of these things seem that they can be worked around and is probably not worth anymore time.
If anyone wants to test out, just load the index_ie11.html from the branch and try it out.
Will wait to hear back from @calebporzio and see how he wants to handle these differing changes.
Thanks so much!
Since it's not working on IE11 now, might be worth updating the readme – is there any point in documenting that polyfills are needed when they won't make it work?
Thanks for all the help on this everyone. 1) I think we should definitely offer a path for IE11 support 2) It would be great if that was just a different output file (like suggested alpine-ie11) 3) I would LOVE a PR to add support but with as few changes to the existing codebase as possible, AND with as much isolated code as possible. I would love for this support to not be littered all over the codebase. Thanks everyone for the help, sorry I haven't given this more attention.
Just to update on the current status, we have been using on IE11, but in a limited fashion on the branch here
The items that do not work are
Error: (Argument not optional) - utils.js - line 157x-if templatesx-ref and $refs are working now
There are also some pending issues if someone can help out before trying a PR.
The following error occurs when:
$event and $dispatch to workSCRIPT5007: Unable to get property '$isAlpineProxy' of undefined or null reference
component.js (84,23)
The current set of polyfills I am using are these
https://polyfill.io/v3/polyfill.min.js?features=MutationObserver%2CArray.from%2CArray.prototype.forEach%2CMap%2CSet%2CArray.prototype.includes%2CString.prototype.includes%2CPromise%2CNodeList.prototype.forEach%2CObject.values%2CReflect%2CReflect.set%2CString.prototype.startsWith%2CArray.prototype.find%2CArray.prototype.findIndex%2CElement.prototype.closest%2CElement.prototype.remove";
I can get a windows VM setup with IE11 for anyone if that can help.
@keyurshah if you change const setWasSuccessful = value['$isAlpineProxy'] to something like const setWasSuccessful = value && value['$isAlpineProxy'], the error "should" disappear.
@SimoTod when I make that change you suggested to that line, bindings begin to fail
for example, when editing an input field with x-model, it will show undefined
_initial_:

_when editing:_

Steps
Files
_binding example_
<div x-data="{ text: 'foo', checkbox: ['foo'], radio:
'foo', select: 'foo', 'multiselect': ['foo'] }">
Text:
<span x-text="JSON.stringify(text)"></span>
<input type="text" x-model="text">
Checkbox:
<span x-text="JSON.stringify(checkbox)"></span>
<input type="checkbox" x-model="checkbox" value="foo">
<input type="checkbox" x-model="checkbox" value="bar">
Radio:
<span x-text="JSON.stringify(radio)"></span>
<input type="radio" x-model="radio" value="foo">
<input type="radio" x-model="radio" value="bar">
Select:
<span x-text="JSON.stringify(select)"></span>
<select x-model="select">
<option>foo</option>
<option>bar</option>
</select>
Multiple Select:
<span x-text="JSON.stringify(multiselect)"></span>
<select x-model="multiselect" multiple>
<option>foo</option>
<option>bar</option>
</select>
</div>
this event component does work however
<div x-data="{ foo: 'bar' }" x-on:custom-event="foo = $event.detail.newValue">
<span x-text="foo"></span>
<button x-on:click="$dispatch('custom-event', {newValue: 'baz'})">Turn 'bar' to 'baz'</button>
</div>
mmmh, try to console log value before const setWasSuccessful.
It's probably undefined which suggests to me that $event.detail.newValue doesn't have the value you expect for some reason. Either the CustomEvent polyfill is not compatible or $event doesn't work in IE11.
when adding the CustomEvent polyfill, at a particular point, the event becomes an instanceof CustomEvent instead of staying as undefined
the event instanceof is undefined until https://github.com/alpinejs/alpine/blob/95c628acc0ad65a4ae95d130d4da02f1f29d3c97/src/directives/model.js#L14-L17
which calls
it should stay undefined but after generateModelAssignmentFunction is called, the event becomes an instanceof CustomType (in IE11) instead of undefined (Chrome)
It then incorrectly matches the if clause at line (where 1event.detail1 is undefined causing the binding error) https://github.com/alpinejs/alpine/blob/95c628acc0ad65a4ae95d130d4da02f1f29d3c97/src/directives/model.js#L30-L31 instead of hitting the else at line https://github.com/alpinejs/alpine/blob/95c628acc0ad65a4ae95d130d4da02f1f29d3c97/src/directives/model.js#L43-L47
need to understand why event is not passed as a parameter to generateModelAssignmentFunction. I tried passing the event through, but it still changes to a CustomEvent here
This is the component for this example
<div x-data="{ foo: 'bar'}">
Text:
<span x-text="JSON.stringify(foo)"></span>
<input type="text" x-model="foo">
</div
It seems to work if I change the following
to
if (event instanceof CustomEvent && event.detail) {
return event.detail
and tests seem to pass. i'll add it to my custom branch and see how it goes for now.
if anyone has any thoughts, that would be great.
It seems sensible to me. Well done.
Thanks!
Got another issue to work now as well. before multiple select fields were not working correctly. But it works now by adding the following
<script src="https://unpkg.com/shim-selected-options" async></script>
remaining open issues
x-if / x-template are not workingalso seeing how to access rollup config variables inside alpinejs so we can add conditions for ie11 into the main file based on the build.
The code looks close to the original.
The if condition we added in the ref function is already running only on IE11.
About the transitions, it seems that IE11 doesn't support classList.add() with multiple params (the spread operator converts an array to a list of variables). -> https://caniuse.com/#feat=classlist
You can probably try to achieve the same with .className = "your classes, original + what you need to apply, space separated".
Or loop on the class array and add them one by one (although it might stress the browser a bit more).
@SimoTod thanks that advice helped! I added a classlist polyfill and transitions work great now.
thanks for the tip for the IE11 condition check that you added earlier.
Branch is updated with additional checks for window.document.documentMode on the changes we made.
known issues
x-if / x-template not workingx-for not working@keyurshah I've set up a win VM and I think we got the last piece of the puzzle as well.
Template is not natively supported, but polyfill.io has a polyfill for it: HTMLTemplateElement.
Just tried and it seems to work. This was my polyfill configuration:
<script src="https://polyfill.io/v3/polyfill.js?features=MutationObserver%2CArray.from%2CArray.prototype.forEach%2CMap%2CSet%2CArray.prototype.includes%2CString.prototype.includes%2CPromise%2CNodeList.prototype.forEach%2CObject.values%2CReflect%2CReflect.set%2CString.prototype.startsWith%2CArray.prototype.find%2CArray.prototype.findIndex%2CElement.prototype.closest%2CElement.prototype.remove%2CCustomEvent%2CElement.prototype.classList%2CHTMLTemplateElement"></script>
I think the IE branch is close enough to the original, so you can PR it.
I've added a rollup plugin which removes the IE11 code from the standard version when you run rollup so it shouldn't affect the size of the final build for those who don't want to support IE11.
It would be good to update the readme to list all the required Polyfills and tell the user which file to include before submitting the PR.
that works for me! nice spotting that polyfill, i was trying some others without any luck. that seems to have solved x-for as well.
I can work on the PR and will run it by you. The rollup plugin looks nice.
I'll change back the CustomEvent check as well. Thanks for the tip.
Thanks @SimoTod!
Just submitted a PR here #164
Hopefully it works well
Just a thought, since the ie11 alpine version is a completely separate build, would it make sense to bundle the polyfills with it?
@timrspratt My opinion is quite the opposite and I don't believe any framework should contain polyfills. If every packaged we used contained polyfills we would have repeat code. I think it's much better when it's seperate then the polyfills can work across multiple packages.
I like the idea of having 2 builds:
That way the dev only has to think about which one they want, and they're good to go!
@timrspratt can you help with including the polyfills directly? Not sure if all the libraries used from polyfill.io can be included with an easy import statement
@keyurshah sorry, unfortunately this isn't something I'll have time to look in to
I agree with @TomS- the polyfills should not be included. Maybe make two bundles in stead then, one with the polyfills and one without.
useBuiltIns: "usage" already includes most of the polyfills though and my understanding is that, without that settings, the bundle won't work.
The polyfills.io script would include some of the polyfills that are already available so I'm not sure why we should make it harder and exclude some of them.
If we really want to not include polyfills, then we should make an effort to compile the bundle without the builtIn option.
Good point @SimoTod, I guess it would be even harder to use without the builtin.
I tried to compile without the useBuiltIns and it did not work.
I had created it with 2 different versions for IE (with and without polyfills) but the size was almost the same so I just removed the one without polyfills for now in PR #164
Thanks to @SimoTod for the bulk of the work in that PR.
not sure if it's just me, but when I try to use the new alpine-ie11.js version (with polyfills included) alongside other libraries (flickity & jquery), I am getting some errors. It might be that the polyfills that are now included directly through rollup might function differently than the ones through polyfill.io.
When using the new alpine-ie11.js by itself without other libraries, it works fine in IE11. So my setup might be an edge case.
I'll just keep maintaining a separate branch for anyone that needs a version without the included polyfills.
Should be all good now. Re-open if not.
Most helpful comment
@SimoTod thanks that advice helped! I added a classlist polyfill and transitions work great now.
thanks for the tip for the IE11 condition check that you added earlier.
Branch is updated with additional checks for
window.document.documentModeon the changes we made.known issues
x-if/x-templatenot workingx-fornot working