包含了 babel polyfill,但是 forEach 在 IE11 的 NodeLists 上仍然不起作用
babel polyfill being included, but forEach still doesn't work in IE11 on NodeLists
我已经让 Webpack 使用 Babel 并包括 @babel/polyfill,但是当尝试在 NodeList
上使用 .forEach
时,IE11 仍然抛出 SCRIPT438 错误。
这是我的 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"
}
}
我的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;
}
最后 /_src/main.js
我 运行 通过 webpack 和 babel:
const testList = document.querySelectorAll('.test-list li');
testList.forEach(item => {
console.log(item.innerHTML);
})
https://babeljs.io/docs/en/babel-polyfill 的文档说当使用 useBuiltIns: "usage"
通过 Webpack 加载它时,您不需要 import
或 require
polyfill
。但即使我删除该选项并在 main.js
顶部手动导入整个 polyfill(使我的包变得很大),它仍然在 IE11 中出错。
所以...我做错了什么?
更新: 从 Babel 7.4.0 开始,Babel 已经切换到直接使用 core-js
而不是用 @babel/polyfill
包装它。 core-js
已经在 NodeList
上填充 forEach
,因此不再需要额外的填充。
babel-polyfill 不会填充缺少的网络 API/prototype 方法,例如 NodeList.prototype.forEach
.
另请注意,您的问题标题具有误导性,因为 NodeList.prototype.forEach
不是 ES6 功能。 forEach
on iterable collections 目前只是一个候选推荐(截至 2018 年 8 月)。
只需在 Javascript:
的顶层包含您自己的 polyfill
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
一旦 core-js 3 稳定,这可能会改变:https://github.com/zloirock/core-js/issues/329
如果你开始采用 ES6 时代使用的通用模式,你也可以不用任何 polyfill:
const testList = [...document.querySelectorAll('.test-list li')];
或
const testList = Array.from(document.querySelectorAll('.test-list li'));
您的另一个选择是使用 for...of
代替:
const lis = document.querySelectorAll('.test-list li');
for (const li of lis) {
// li.addEventListener(...) or whatever
}
最后也可以采用常见的ES5模式:
var testList = document.querySelectorAll('.test-list li');
Array.prototype.forEach.call(testList, function(li) { /*whatever*/ });
我已经让 Webpack 使用 Babel 并包括 @babel/polyfill,但是当尝试在 NodeList
上使用 .forEach
时,IE11 仍然抛出 SCRIPT438 错误。
这是我的 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"
}
}
我的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;
}
最后 /_src/main.js
我 运行 通过 webpack 和 babel:
const testList = document.querySelectorAll('.test-list li');
testList.forEach(item => {
console.log(item.innerHTML);
})
https://babeljs.io/docs/en/babel-polyfill 的文档说当使用 useBuiltIns: "usage"
通过 Webpack 加载它时,您不需要 import
或 require
polyfill
。但即使我删除该选项并在 main.js
顶部手动导入整个 polyfill(使我的包变得很大),它仍然在 IE11 中出错。
所以...我做错了什么?
更新: 从 Babel 7.4.0 开始,Babel 已经切换到直接使用 core-js
而不是用 @babel/polyfill
包装它。 core-js
已经在 NodeList
上填充 forEach
,因此不再需要额外的填充。
babel-polyfill 不会填充缺少的网络 API/prototype 方法,例如 NodeList.prototype.forEach
.
另请注意,您的问题标题具有误导性,因为 NodeList.prototype.forEach
不是 ES6 功能。 forEach
on iterable collections 目前只是一个候选推荐(截至 2018 年 8 月)。
只需在 Javascript:
的顶层包含您自己的 polyfillif (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
一旦 core-js 3 稳定,这可能会改变:https://github.com/zloirock/core-js/issues/329
如果你开始采用 ES6 时代使用的通用模式,你也可以不用任何 polyfill:
const testList = [...document.querySelectorAll('.test-list li')];
或
const testList = Array.from(document.querySelectorAll('.test-list li'));
您的另一个选择是使用 for...of
代替:
const lis = document.querySelectorAll('.test-list li');
for (const li of lis) {
// li.addEventListener(...) or whatever
}
最后也可以采用常见的ES5模式:
var testList = document.querySelectorAll('.test-list li');
Array.prototype.forEach.call(testList, function(li) { /*whatever*/ });