javascript - 包含了 babel polyfill,但是 forEach 在 IE11 的 NodeLists 上仍然不起作用

标签 javascript webpack babeljs npm-scripts babel-polyfill

我已经让 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;
}

最后是我通过 webpack 和 babel 运行的 /_src/main.js:

const testList = document.querySelectorAll('.test-list li');

testList.forEach(item => {
  console.log(item.innerHTML);
})

文档位于 https://babeljs.io/docs/en/babel-polyfill说你不需要 importrequire polyfill 通过 Webpack 使用 useBuiltIns: "usage"。但即使我删除该选项并在 main.js 顶部手动导入整个 polyfill(使我的包变得很大),它仍然会在 IE11 中出错。

那么...我做错了什么?

最佳答案

更新:从 Babel 7.4.0 开始,Babel 已经切换到直接使用 core-js 而不是用 @babel/polyfill 包装它>。 core-js 已经对 NodeList 上的 forEach 进行了 polyfill,因此不再需要额外的 polyfill。


babel-polyfill 不会填充缺少的 Web API/原型(prototype)方法,例如 NodeList.prototype.forEach

另请注意,您的问题标题具有误导性,因为 NodeList.prototype.forEach 不是 ES6 功能。可迭代集合上的 forEach 目前只是一个候选推荐(截至 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*/ });

关于javascript - 包含了 babel polyfill,但是 forEach 在 IE11 的 NodeLists 上仍然不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53331180/

相关文章:

angular - 如何修复 Angular 'source.lift is not a function' 错误?

javascript - 带有 semantic-ui-react 和 webpack 的图像组件的路径

Javascript 或 jQuery 根据另一个输入值自动填充一个输入文本

javascript - 重定向到包含原始帖子数据的 URL

javascript - javascript 中带有字符串的简单 if 条件的问题

webpack - 如何在 webpack 应用程序中包含 Angular 2 Material 主题。 (JHipster)?

javascript - 无法直接仅导入 S3

javascript - 单击菜单内的链接后如何将汉堡包菜单图标重置为未打开状态?

node.js - Javascript .contains() 在 Babel 中可用于 Node 和 React 吗?

javascript - Webpack 2.3.3 - 类型错误 : $export is not a function