web-dev-qa-db-ja.com

babel polyfillが含まれていますが、forEachはNodeLists上のIE11ではまだ動作しません

Babelで動作し、@ babel/polyfillを含むWebpackを持っていますが、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 のドキュメントでは、importrequirepolyfilluseBuiltIns: "usage"を使用してWebpack経由でロードする場合。ただし、そのオプションを削除し、main.jsの上部にあるポリフィル全体を手動でインポートしても(バンドルが巨大になります)、IE11でエラーが発生します。

だから...私は間違っているのですか?

10
Robert_QSS

更新:Babel 7.4.0の時点で、Babelはcore-jsでラップするのではなく、@babel/polyfillを直接使用するように切り替えました。 core-jsは既にforEachNodeListをポリフィルしているため、追加のポリフィルはもう必要ありません。


babel-polyfillは、NodeList.prototype.forEachなどの欠落しているWeb API /プロトタイプメソッドをポリフィルしません。

また、NodeList.prototype.forEachはES6の機能ではないため、質問のタイトルが誤解を招く可能性があることに注意してください。反復可能なコレクションのforEachは、現時点では候補の推奨事項のみです(2018年8月現在)。

Javascriptの最上位に独自のポリフィルを含めるだけです。

if (window.NodeList && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = Array.prototype.forEach;
}

これは、core-js 3が安定するとすぐに変更される可能性があります。 https://github.com/zloirock/core-js/issues/329

ES6で使用されている一般的なパターンの採用を開始する場合は、ポリフィルなしでも実行できます。

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*/ });
26
connexo