Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use babel/corejs3/webpack correctly for IE11?

With my current config (see below), I'm getting this error:

   [object Error]{description: "Argument ob...", message: "Argument ob...", name: "TypeError", number: -2147418113, stack: "TypeError: ...", Symbol()_7.bs7gi3oa3wi: undefined}

I tried to dig based on Symbol()_ ... : undefined} but I couldn't find any clear indication.

This is my .babel.config.js:

module.exports = function (api) {
    api.cache(true);
    const presets = [
      [
        '@babel/preset-env',
        {
         // modules: false,
          corejs:"3.6.4",
          useBuiltIns: 'usage',
          targets: {
            browsers: [
              "edge >= 16",
              "safari >= 9",
              "firefox >= 57",
              "ie >= 11",
              "ios >= 9",
              "chrome >= 49"
            ]
          }
        }
      ]
    ];
    const plugins= [
        ["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }],
        ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ];
    return {
      presets,
      plugins
    }
  }

This is my webpackconfig.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
       // exclude: /node_modules/,
       exclude : [
        /\bcore-js\b/,
        /\bwebpack\/buildin\b/
      ],
        use: {
          loader: 'babel-loader',
          options:{
            sourceType: "unambiguous"
          }
        },
      },
    ],
  },
  devtool:"cheap-source-map",
  resolve: {
    extensions: ['*', '.js'],
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'shim.js',
  }
};

I've also tried many alternatives, this is my current one, with entry:"usage" and not excluding node_modules.

This is from my package.json:

 "devDependencies": {
    "@babel/core": "^7.9.0",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-proposal-decorators": "^7.8.3",
    "@babel/preset-env": "^7.9.5",
    "babel-loader": "^8.1.0",
    "eslint": "^6.8.0",
    "eslint-config-google": "^0.14.0",
    "webpack": "^4.42.1",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3",
    "dotenv-webpack": "^1.7.0"
  },
  "dependencies": {
    "core-js": "^3.6.4",
    "ismobilejs": "^1.0.3",
    "localforage": "1.7.3",
    "postmate": "^1.5.2",
    "uuid": "^7.0.3"
  }

Error seems to come from the first invocation of the Postmate library i.e. new Postmate({...}) (I have a console.log just before). Prior to this call, I have one to localforage and the promise complete succesfully.

like image 792
Rhangaun Avatar asked Apr 05 '20 15:04

Rhangaun


People also ask

Does Babel support Internet Explorer?

The @babel/preset-env package is a powerful group of plugins that help developers transpile code down to a format suitable for the browser vendors and browser versions they are targeting. By default, this package transforms your code down to ES5-compatible syntax, which is perfect for supporting IE 11.

Where do I put Babel polyfill?

If @babel/preset-env is not used then add @babel/polyfill to webpack entry array as discussed above. It can still be added at the top of the entry point to application via import or require , but this is not recommended.

How do you use polyfill in Babel?

Babel Polyfill adds support to the web browsers for features, which are not available. Babel compiles the code from recent ecma version to the one, which we want. It changes the syntax as per the preset, but cannot do anything for the objects or methods used.


1 Answers

Using useBuiltIns: "usage"


You'll have to normaly import the modules you want to use (i.g. Postmate) inside your code entry file; no polyfills; every polyfill used will be handled accordingly by @babel/preset-env. Also, the version of corejs in @babel/preset-env has to be a single number (i.e. 3 or 2).

Contents of babel.config.js:

module.exports = function (api) {
  api.cache(true);
  const presets = [
    [
      '@babel/preset-env',
      {
        corejs : {
          version : "3",
          proposals : true
        },
        useBuiltIns: 'usage',
        targets: {
          browsers: [
            "edge >= 16",
            "safari >= 9",
            "firefox >= 57",
            "ie >= 11",
            "ios >= 9",
            "chrome >= 49"
          ]
        }
      }
    ]
  ];
  const plugins= [
      ["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ];
  return {
    presets,
    plugins
  }
}

Contents of webpackconfig.js:

const path = require('path');

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: [
          /\bcore-js\b/,
          /\bwebpack\/buildin\b/
        ],
        use: {
          loader: 'babel-loader',
          options: {
            babelrc: false,
            configFile: path.resolve(__dirname, 'babel.config.js'),
            compact: false,
            cacheDirectory: true,
            sourceMaps: false,
          },
        },
      },
    ],
  },
  devtool: "cheap-source-map",
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'shim.js',
  }
}

Contents of entry JS file src/index.js:

import Postmate from 'postmate';

// Postmate and rest of the code
...

It will generate:

dist/shim.js      177K
dist/shim.js.map  140K

You can test an online distributed example working using useBuiltIns: "usage" in IE 11 here: https://zikro.gr/dbg/so/61044894/usage/. (The child iFrame has a button that changes parent window background color to a random color)

You can find a repository with the whole project and the usage example branch in this Github repository/branch: https://github.com/clytras/ie11-postmate/tree/usage

Using useBuiltIns: "entry"


According to this issue disqussion "using Symbol causes exception in IE11", you have to:

  1. Exclude @babel-runtime and core-js in the rule for .js files.
  2. Have corejs: "3" and useBuiltIns: 'entry' to @babel/preset-env preset inside babel.config.js file.
  3. There have to be core-js/stable and postmate imports inside your entry source JS file.

Contents of bavel.config.js:

module.exports = function (api) {
  api.cache(true);
  const presets = [
    [
      '@babel/preset-env',
      {
        corejs:"3",
        useBuiltIns: 'entry',
        targets: {
          browsers: [
            "edge >= 16",
            "safari >= 9",
            "firefox >= 57",
            "ie >= 11",
            "ios >= 9",
            "chrome >= 49"
          ]
        }
      }
    ]
  ];
  const plugins= [
      ["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ];
  return {
    presets,
    plugins
  }
}

Contents of webpackconfig.js:

const path = require('path');

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /@babel(?:\/|\\{1,2})runtime|core-js/,
        use: {
          loader: 'babel-loader',
          options: {
            babelrc: false,
            configFile: path.resolve(__dirname, 'babel.config.js'),
            compact: false,
            cacheDirectory: true,
            sourceMaps: false,
          },
        },
      },
    ],
  },
  devtool:"cheap-source-map",
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'shim.js',
  }
}

Contents of entry JS file src/index.js:

import 'core-js/stable';
window.Postmate = require('postmate/build/postmate.min.js');

// Postmate and rest of the code
...

It will generate:

dist/shim.js      641K
dist/shim.js.map  459K

You can test in IE 11 here: https://zikro.gr/dbg/so/61044894/.

like image 111
Christos Lytras Avatar answered Oct 18 '22 03:10

Christos Lytras