babel polyfill being included, but forEach still doesn't work in IE11 on NodeLists
Update: As of Babel 7.4.0, Babel has switched to using core-js
directly rather than wrapping it with @babel/polyfill
. core-js
already polyfills forEach
on NodeList
, so no additional polyfill required anymore.
babel-polyfill doesn't polyfill missing web API/prototype methods like NodeList.prototype.forEach
.
Also please note that your question title is misleading as NodeList.prototype.forEach
is not an ES6 feature. forEach
on iterable collections is currently only a candidate recommendation (as of August 2018).
Simply include your own polyfill at the top level of your Javascript:
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
This might change as soon as core-js 3 is stable: https://github.com/zloirock/core-js/issues/329
You can also go without any polyfill if you start to adopt the common pattern being used in ES6 times:
const testList = [...document.querySelectorAll('.test-list li')];
or
const testList = Array.from(document.querySelectorAll('.test-list li'));
The other option you have is to use for...of
instead:
const lis = document.querySelectorAll('.test-list li');
for (const li of lis) {
// li.addEventListener(...) or whatever
}
Finally, you can also adopt the common ES5 pattern:
var testList = document.querySelectorAll('.test-list li');
Array.prototype.forEach.call(testList, function(li) { /*whatever*/ });
Robert_QSS
Updated on June 17, 2022Comments
-
Robert_QSS almost 2 years
I've got Webpack working with Babel and including the @babel/polyfill, yet IE11 is still throwing a SCRIPT438 error when trying to use
.forEach
on aNodeList
.Here's my
package.json
{ ... "scripts": { "build:js": "webpack --config ./_build/webpack.config.js" }, ... "browserslist": [ "IE 11", "last 3 versions", "not IE < 11" ], "babel": { "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage" } ] ] }, "devDependencies": { "@babel/core": "^7.1.6", "@babel/preset-env": "^7.1.6", "babel-loader": "^8.0.4", "webpack": "^4.25.1", "webpack-cli": "^3.1.2" }, "dependencies": { "@babel/polyfill": "^7.0.0" } }
My
webpack.config.js
:const path = require('path'); const webpack = require('webpack'); module.exports = (env, argv) => { const javascript = { test: /\.js$/, use: { loader: 'babel-loader' } }; // config object const config = { entry: { main: './_src/js/main.js', }, devtool: 'source-map', output: { path: path.resolve(__dirname, '../js'), filename: '[name].js', }, module: { rules: [javascript] } } return config; }
And finally
/_src/main.js
that I'm running through webpack and babel:const testList = document.querySelectorAll('.test-list li'); testList.forEach(item => { console.log(item.innerHTML); })
The docs at https://babeljs.io/docs/en/babel-polyfill say that you don't need to
import
orrequire
polyfill
when loading it via Webpack withuseBuiltIns: "usage"
. But even if I remove that option and manually import the whole polyfill at the top ofmain.js
(making my bundle huge), it still errors out in IE11.So...what am I doing wrong?
-
Ramy Rais almost 5 yearsArray.from() is not going to work on IE11 as it is not supported.
-
connexo almost 5 years@RamyRais Which is why I also added the ES5 way. IE 11 does not support any ES6 feature except
const
andlet
keyword.