webpackbabeljsbabel-preset-env

Getting default implementation of @babel/present-env to work with IE11


My @babel/preset-env configuration is working fine except for IE11. When I run it in IE11 I get this error:

SCRIPT438: Object doesn't support property or method 'assign'

After googling the error I see I need to use babel/polyfill, but it is deprecated and the suggestion is that you now use core-js. For such a widely used tool the official documentation is lacking.

I followed other StackOverflow posts and came up with this solution, but still I get the error:

Package.json:

"devDependencies": {
    "@babel/core": "^7.10.2",
    "@babel/preset-env": "^7.10.2",
    "babel-loader": "^8.1.0",
    "core-js": "^3.6.5",
    ...
}

webpack.config:

{
   test: /\.(js)$/,
   exclude: /node_modules/,
   use: {
      loader: 'babel-loader',
      options: {
         // presets: ['@babel/preset-env'],
         presets: [
            [
               "@babel/preset-env", {
                  "targets": {
                     "browsers": ["last 2 versions", "> 0.1%", "not dead", "ie >= 11"]
                  },
                  "useBuiltIns": "usage",
                  "corejs": 3
               }
            ]
         ]
      }
   }
},

I don't have a babelrc or browserlists file as I want to keep it as minimalist as possible.

Why isn't this working and why do I continue to get this error:

function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e)}
SCRIPT438: Object doesn't support property or method 'assign'

Solution

  • Answering my own question for future readers.

    So @babel/polyfill was replaced by the use of corejs and @babel/runtime-corejs3. Do the following to get a polyfill for the Object.assign() error in IE11.

    1. Install packages

    npm i core-js @babel/core @babel/runtime-corejs3 --save-dev

    This installs core-js v3.6.5 at the time of writing.

    2. Update webpack

    Add "useBuiltIns": "usage" and "corejs": 3 to your babel/preset-env rule:

    module: {
       rules: [
          {
             test: /\.(js)$/,
             exclude: /node_modules/,
             use: {
                loader: 'babel-loader',
                options: {
                   presets: [
                      [
                         "@babel/preset-env", {
                            "useBuiltIns": "usage", 
                            "corejs": 3
                         }
                      ]
                   ]
                }
             }
          },
          // Your other rules...
       ]
    },
    

    3. (Optional) Add your browsers

    You can add this to your package.json if you want to specify your own browserslist string:

    "devDependencies": {
       // my dev dependencies
    },
    "dependencies": {
       // my dependencies
    },
    "browserslist": "last 2 versions, > 0.1%, not dead"
    

    4. Add import of corejs

    You need to import core-js to where ever the polyfill is required. I put it in my root ./App.js to give me global coverage.

    import "core-js/stable";
    

    That should fix the Object.assign() error in IE11, however...

    5. Other polyfills..

    So after doing this I had another error regarding my use of .closest() which IE11 does not support. A quick an easy way to get a polyfill for this is to add this script to your

    <script src="https://unpkg.com/element-closest"></script>
    

    You can import it as a package as well, but the above CDN delivered is quick and easy.