Search code examples
webpackbabeljsbabel-polyfill

Object.entries/Object.values is undefined with Babel-polyfill in IE 11


To optimize page load time our my app, I split the bundle into two bundles: webpack-bundle (this contains my code) and vendor-bundle (this contains everything in node modules). But I am starting to get several errors when my users visit my website from Internet Explorer. They get errors like "includes" is undefined and "Object.entries"/"Object.values" are undefined. Clearly, I need to include babel-polyfill and load that before my other bundles. But I am not sure how to do it when my entry is an object.

This is the old entry. It is an array (before I split the bundle):

const config = {
  "entry": [
    "es5-shim/es5-shim", 
    "es5-shim/es5-sham",
    "url-search-params-polyfill",   
    "@babel/polyfill",  
    "./app/registration"    
  ],

This is my current webpack.config where I changed my entry to an object and used splitChunks. This will out put two bundles.

const config = {
  "entry": {
    "webpack-bundle": "./app/registration"
  },

  "output": {
    filename: "[name].js",
    path: pathLib.resolve(__dirname, "../app/assets/webpack"),
  },

  "module": {
    "rules": [
      {
        "test": /\.(svg)$/,
        "use": [
          {
            "loader": "url-loader",
            "options": {"limit": 8192}
          }
        ]
      },
      {
        "test": /\.css$/,
        "use": [
          "style-loader",
          "css-loader"
        ]
      },
      {
        "test": require.resolve("react"),
        "use": {
          "loader": "imports-loader",
          "options": {
            "sham": "es5-shim/es5-sham",
            "shim": "es5-shim/es5-shim"
          }
        },
      },
      {
        "exclude": /node_modules/,
        "test": /\.jsx?$/,
        "use": {
          "loader": "babel-loader",
          "options": {
            "plugins": [
              "@babel/plugin-proposal-class-properties",
              ["@babel/plugin-proposal-decorators", {"legacy": true}],
              "@babel/plugin-proposal-export-namespace-from",
              "@babel/plugin-proposal-function-sent",
              "@babel/plugin-proposal-json-strings",
              "@babel/plugin-proposal-numeric-separator",
              "@babel/plugin-proposal-object-rest-spread",
              "@babel/plugin-proposal-throw-expressions",
              "@babel/plugin-syntax-dynamic-import",
              "@babel/plugin-syntax-import-meta",
              "@babel/plugin-transform-react-jsx"
            ],
            "presets": [
              "@babel/preset-env",
              "@babel/preset-react"
            ]
          }
        }
      }
    ],
  },

  "plugins": [
    new webpack.ProvidePlugin({
      "$": "jquery",
      "jQuery": "jquery",
      "window.jQuery": "jquery"
    }),
    new UglifyJsPlugin()
  ],

  "optimization": {
    "splitChunks": {
      "cacheGroups": {
        "vendor": {
          "test": /node_modules/,
          "chunks": "all",
          "name": "vendor-bundle"
        }
      }
    }
  },

  "resolve": {
    "alias": {
      "Lib": pathLib.resolve(__dirname, "app/lib/"),
      "Shared": pathLib.resolve(__dirname, "app/shared/")
    },
    "extensions": [".js", ".jsx"]
  }
};

module.exports = config;

babelrc

{
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    ["@babel/plugin-proposal-decorators", {"legacy": true}],
    "@babel/plugin-proposal-export-namespace-from",
    "@babel/plugin-proposal-function-sent",
    "@babel/plugin-proposal-json-strings",
    "@babel/plugin-proposal-numeric-separator",
    "@babel/plugin-proposal-object-rest-spread",
    "@babel/plugin-proposal-throw-expressions",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-syntax-import-meta",
    "@babel/plugin-transform-react-jsx",
   [ "@babel/plugin-transform-runtime", {"regenerator": true}]
  ],
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

I tried to re-write entry this way, but it didn't work:

 "entry": {
    "polyfill-bundle": "@babel/polyfill",
    "es5-shim-bundle": "es5-shim/es5-shim",
    "es5-sham-bundle": "es5-shim/es5-sham",
    "webpack-bundle": "./app/registration"
  },
  1. How can I make sure that babel/polyfill is loaded and is compiling correctly? Should I add it in the entry, or ProvidePlugin?

  2. Shouldn't babel/polyfill be included in vendor-bundle already?


Solution

  • I suggest to replace babel-polyfill with this core-js. Install core-js, create a .babelrc file and place it in it.

    .babelrc

    {
     "presets": [
        [
         "@babel/preset-env",
         {
          "useBuiltIns": "usage",
          "corejs": 3
         }
       ],
       "@babel/preset-react"
      ]
    }
    

    webpack.conf.js

    const config = {
      "entry": {
        "webpack-bundle": "./app/registration"
      },
    
      "output": {
        filename: "[name].js",
        path: pathLib.resolve(__dirname, "../app/assets/webpack"),
      },
    
      "module": {
        "rules": [
          {
            "test": /\.jsx?$/,
            "exclude": /node_modules/,
            "use": {
              "loader": "babel-loader",
              }
            }
          },
          {
            "test": /\.css$/,
            "use": [
              "style-loader",
              "css-loader"
            ]
          },
          {
            "test": /\.(svg)$/,
            "use": [{
              "loader": "url-loader",
              "options": {
                "limit": 8192
              }
            }]
          },
        ],
      },
    
      "plugins": [
        new webpack.ProvidePlugin({
          "$": "jquery",
          "jQuery": "jquery",
          "window.jQuery": "jquery"
        }),
        new UglifyJsPlugin()
      ],
    
      "optimization": {
        "splitChunks": {
          "cacheGroups": {
            "vendor": {
              "test": /node_modules/,
              "chunks": "all",
              "name": "vendor-bundle"
            }
          }
        }
      },
      "resolve": {
        "alias": {
          "Lib": pathLib.resolve(__dirname, "app/lib/"),
          "Shared": pathLib.resolve(__dirname, "app/shared/")
        },
        "extensions": [".js", ".jsx"]
      }
    };
    
    module.exports = config;

    package.jon

    "browserslist": [
      "last 2 version",
      "> 1%",
      "not dead"
    ],
    

    The above entry will add polyfills to browsers including ie10 and ie11. To check this, add debug: true. The console will display exactly what has been added, what files, etc.

    {
      debug: true,
      "useBuiltIns": "usage",
      "corejs": 3
    }
    

    More browserl and github