Current Behavior:
An error is thrown by IE 11 at line 12 in the compiled version of NativeMethodsMixin/index.js in response to Array.from() not being supported.
Expected Behavior:
Compiled code to either include the polyfill for Array.from or not rely on the method.
OS: Windows 10
Browser: IE 11
React Native for Web (version): 0.80
React (version): 15.4.2
I think a better approach would be to warn users that you need this polyfill and provide a link for them to include. This means that people not targeting IE 11 won't need bloat, and users that are have an easy way of fixing it.
I'm pretty sure this is resolvable in a way that doesn't require a polyfill and wouldn't eliminate IE support. I'll take a look at it, if no one else is interested.
It just seems really strange, because it's not actually in use in the source, but babel is utilizing it in the build.
This may be because the transpiled modules expect babel-runtime to be included as the helpers aren't inlined.
@hzoo What do you recommend doing here?
@necolas Yeah the only limitation is instance methods http://babeljs.io/docs/plugins/transform-runtime/#technical-detailscore-js-aliasing
It doesn't look like transform-runtime is in the .babelrc of react-native-web or in the preset? Otherwise I'd recommend asking users to add babel-polyfill or use https://github.com/babel/babel-preset-env. Ref http://babeljs.io/docs/usage/caveats/#polyfills
It doesn't look like transform-runtime is in the .babelrc of react-native-web or in the preset?
Do you need to use the transform-runtime plugin or babel-runtime package to avoid Babel producing code that errors in IE 11? I don't know why Array.from is in being added by Babel here. If I have to add the babel-runtime, do I set it as a peer dependency? I'm a bit confused as to what the problem and solution is.
Sure, it can be very confusing!
Babel automatically adds the Array.from as part of the transform.
It's part of spread (the ...) in const classList = [...node.classList];
http://babeljs.io/docs/usage/caveats/#polyfills
Because for-of, spread, array destructuring all use iterators.. thus the need for Array.from or Symbol.iterator unless you use loose mode (in this case meaning we assume everything is an array). And it's a runtime check since you don't know if it's a regular array or not (unless we take advantage of type inference, which we can do in certain places https://github.com/babel/babel/pull/4747)
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
var classList = [].concat(_toConsumableArray(node.classList));
And node.classList is not an Array (DOMTokenList) so it doesn't hit the ^ for loop and tries to run Array.from.
http://babeljs.io/docs/plugins/transform-es2015-spread/#optionsloose
var classList = [].concat(node.classList);
If you don't use a polyfill for Array.from (recommended for an app), then library needs to include transform-runtime as a devDep (a plugin) and babel-runtime as the runtime dependency. https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-runtime
My recommendation is that the application use preset-env with the useBuiltIns option, https://github.com/babel/babel-preset-env#usebuiltins. In 2.0 (Babel 7), we'll have an option that only adds the used/necessary polyfills for compiled files https://github.com/babel/babel-preset-env/tree/2.0#usebuiltins-usage.
Hope that helps, just what I've learned? So some options:
[...a] (probably not)loose mode: not recommended unless you know every use of it is an array, or you are ok with using not as spec compliant before which may cause more problems down the line when using the native spec compliant version in browsers (maybe)babel-runtime so the user doesn't have to do anythingI think a better approach would be to warn users that you need this polyfill and provide a link for them to include.
Use babel-plugin-transform-runtime to rewrite Array.from to use babel-runtime so the user doesn't have to do anything
@hzoo aint sure if I understand this one correctly, could u elaborate with a short example? I know what transform-runtime does in general, bu aint sure what u have ment by this "to use babel-runtime so the user doesn't have to do anything"
I just mean that if you don't require the user to include a polyfill, you'll need to do it yourself in the library, which can be done with transform-runtime.
ah, misread this somehow then :) i always prefer transform-runtime as its the most efficient one imho, also it doesnt extend built-in from what I remember, which is also a good thing for me
thansk for the answer
Thanks @hzoo! I'll give some thought to this
I decided to use Array.prototype.slice to convert the nodeList, and added a note to the documentation about polyfills.
Most helpful comment
Sure, it can be very confusing!
Babel automatically adds the
Array.fromas part of the transform.It's part of spread (the
...) inconst classList = [...node.classList];http://babeljs.io/docs/usage/caveats/#polyfills
Because for-of, spread, array destructuring all use iterators.. thus the need for
Array.fromorSymbol.iteratorunless you use loose mode (in this case meaning we assume everything is an array). And it's a runtime check since you don't know if it's a regular array or not (unless we take advantage of type inference, which we can do in certain places https://github.com/babel/babel/pull/4747)Regular output (REPL link)
And
node.classListis not an Array (DOMTokenList) so it doesn't hit the ^ for loop and tries to runArray.from.Loose mode (REPL link)
http://babeljs.io/docs/plugins/transform-es2015-spread/#optionsloose
If you don't use a polyfill for Array.from (recommended for an app), then library needs to include transform-runtime as a devDep (a plugin) and babel-runtime as the runtime dependency. https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-runtime
My recommendation is that the application use preset-env with the
useBuiltInsoption, https://github.com/babel/babel-preset-env#usebuiltins. In 2.0 (Babel 7), we'll have an option that only adds the used/necessary polyfills for compiled files https://github.com/babel/babel-preset-env/tree/2.0#usebuiltins-usage.Hope that helps, just what I've learned? So some options:
[...a](probably not)loosemode: not recommended unless you know every use of it is an array, or you are ok with using not as spec compliant before which may cause more problems down the line when using the native spec compliant version in browsers (maybe)babel-runtimeso the user doesn't have to do anything