Development in JavaScript would be incomparably easier without a bunch of issues that are caused by differences between browsers. Especially one of them that is always behind the others - Internet Explorer. Unfortunately, people still use it, even knowing that Microsoft released Edge which should replace IE. It is very likely that your JavaScript application will not work properly on IE11 unless you consciously take care of it. Welcome to IE11 hell.
Table of contents
If you want to jump to other parts of the tutorial, use table of contents.
IE11 does not fully support ES6
If you clone my repository from this commit, run webpack and you open races.html in Chrome and IE11 and click 2017, you will see that IE11 does not display the website correctly. Press F12 on the keyboard to show DevTools in IE11 and refresh the page. You will see SCRIPT1002 error coming from results.bundle.js. It is because of this code fragment from results.js:
[{position: 1, runner: "Thomas Faster", time: "2:08:14"},
{position: 2, runner: "Adam Gorecki", time: "2:09:02"},
{position: 3, runner: "Nick Alwayslast", time: "2:09:33"}
].forEach(r => addRunnerResultToTable(r.position, r.runner, r.time));
It is known as arrow function and it is a part of ES6 (ECMAScript 6). It is not supported by any Internet Explorer version (including 11). That is why this script throws an error on IE11.
Babel can help with IE11
Luckily, there is babel library which was created to solve this issue. Babel is a transpiler that transforms JavaScript code that is not compatible with ECMAScript 5 to one that is covered by ECMAScript 5 which is very basic JS version and it is supported by most browsers including IE11. You can add the transformation to the building pipeline. I am going to add it to webpack configuration so transpiling will be done as part of webpack building process.
Install Babel
I install two babel libraries: core and preset-env. And a loader for webpack: babel-loader.
npm install --save-dev babel-loader @babel/core @babel/preset-env
This command downloads the libraries and adds proper entries to package.json.
Add Babel to webpack config
I need to tell webpack to use babel-loader for JS files. I do that by amending webpack.config.js:
module: {
rules: [
...
{
test: /\.m?js$/, exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
],
},
The above configuration tells webpack to use babel-loader for all JS files except those in node_modules directory. Babel can use different presets but I chose the easiest way - preset-env.
Now I run webpack:
npx webpack --mode=development
When building package is finished, I open my application again - in Chrome and in IE11. Chrome still works but IE11 throws a different error - SCRIPT445. It is a one step further. Now, it did not stop at the arrow function but moved forward to URL object. It is also unsupported by IE11 but it is not handled by Babel either. Yes, there is another solution for that.
URL Polyfill
url-polyfill is a JavaScript library that creates window.URL just in case the browser does not support URL object.
The first step to use it is to install it:
npm install url-polyfill --save
Then I add a proper import to urlparams.js somewhere at the beginning of the file because this script uses the URL object.
import 'url-polyfill';
Now, I let webpack to build the package:
npx webpack --mode=development
and IE11 finally is able to properly display the page.
Summary
This article showed how to cope with JavaScript functionality that is unsupported by older browers like IE11.
Source code created in this part is on tutorial/part12-babel branch on GitHub.