3

So I'm going crazy over this. I have a certain module that I use that is not compatible with IE, and because of that the best option to me seemed to not import after I detect the user is using IE.

I don't know anything about polyfills, so I have no clue how to use them, so I have no clue wether they can be the solution, or are the problem. Regardless, I thought not initiating the animations module would do the trick, but that doesn't seem to work like expected. Even commenting out commands.push(animations) still fires the module in IE.

import './polyfill';
import queue from './helpers/queue';
import navigation from './navigation';
import search from './search';
import animations from './animations';

const init = () => {
    document.documentElement.classList.remove('no-js');
    const commands = [       
        navigation,
        search,
    ];

    let isIE = false;
    const ua = window.navigator.userAgent;
    const oldIE = ua.indexOf('MSIE ');
    const newIE = ua.indexOf('Trident/');

    if (oldIE > -1 || newIE > -1) {
        isIE = true;
    }

    console.log(isIE);

    if (!isIE) {
        commands.push(animations);
    }

    queue(commands);
};

window.addEventListener('load', init);

So how can I avoid the animations-module being loaded in IE? I've been trying for hours now, to no avail. Thanks in advance guys!

Yorg Vermeulen
  • 206
  • 3
  • 15
  • What is the problem? Is the `push(animations)` called even if on IE? What is `animations` or `queue` ? – XCS Sep 07 '19 at 11:47
  • So the problem is with the animations module, hence this question should be about the animation code, including any error messages you encounter and preferable a [mcve] instead. Furthermore IE (and Edge) [don't natively support](https://caniuse.com/#feat=imports) the `import` keyword hence there has to be some transpiler that converts them into something IE understands. – Andreas Sep 07 '19 at 11:54
  • I'm sorry my question is not that clear, this is not my strongpoint at all. @Cristy The problem is indeed that push(animations) is called even when I comment it out (edited my answer). animations is importing a bunch of animejs-packages which seem to not work in IE. the queue just iterates over each call to catch errors (I suppose). – Yorg Vermeulen Sep 07 '19 at 12:42
  • @Andreas Yeah I do use polyfills (although I don't know how they work, lol), and the other imported modules don't give issues to me. It's just this one package giving me troubles. It's calling animejs with a bunch of extentions extentions that are not compatible with IE , and the polyfills I used are apperantly not helping, so the only thing I could think about is just disabling it. – Yorg Vermeulen Sep 07 '19 at 12:42

2 Answers2

3

Try to serve an additional file ie-polyfill only to IE11/10/9 browser and other polyfill for all the rest. The solution implemented is simple and effective and it consists of pre-generating a bundle for IE and loading it in a script tag with always present in the index adding nomodule attribute.

(1) Create the file src/ie-polyfills.js with the necessary polyfills for IE.

Example:

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'classlist.js';
import 'web-animations-js';

(2) Leaving only the following inside src/polyfill.ts

import 'zone.js/dist/zone';  // Included with Angular CLI.

(3) To generate the ie-polyfills first we will need to create a webpack configuration in webpack-polyfill-config.js

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  mode: 'production',
  optimization: {
    minimizer: [new UglifyJsPlugin({
      uglifyOptions: {
        warnings: false,
        parse: {},
        compress: {},
        mangle: true, // Note `mangle.properties` is `false` by default.
        output: null,
        toplevel: false,
        nameCache: null,
        ie8: false,
        keep_fnames: false,
      }
    })]
  }
};

(4) Add the following command inside the script section in the package.json:

"build-ie-polyfills": "webpack-cli src/ie-polyfills.js -o src/generated/ie-polyfills.min.js --optimize-minimize -c webpack-polyfill.config.js",
"postbuild": "cp -p src/generated/ie-polyfills.min.js dist/generated"

(5) add the script tag inside the head in src/index.html:

<script nomodule="" src="generated/ie-polyfills.min.js"></script>

The nomodule attribute is a boolean attribute that prevents a script from being executed in user agents that support module scripts.

Only browsers that do not support modules like IE11/10/9, will download the specific bundle while the rest of the browsers will ignore it and just download the normal file.

Reference:

Angular polyfill strategies - IE aside

Deepak-MSFT
  • 10,379
  • 1
  • 12
  • 19
-1

We do have dynamic imports proposal now with ECMA. This is also available as babel-preset.

// Internet Explorer 6-11
var isIE = /*@cc_on!@*/false || !!document.documentMode;

if (!isIE) {
    import('something')
    .then((something) => {
       console.log(something.something);
    });
}

How to detect Safari, Chrome, IE, Firefox and Opera browser?

Tom Marienfeld
  • 716
  • 3
  • 14
  • 1
    That doesn't seem to work, es-lint is also giving me `Parsing error: 'import' and 'export' may only appear at top level. – Yorg Vermeulen Sep 07 '19 at 12:55
  • You need to set es-lint to es6. Check browser compability for [dynamic import](https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/import) and use the provided [babel-preset](https://babeljs.io/docs/en/babel-plugin-syntax-dynamic-import/) for broswers that are not compatible. – Tom Marienfeld Sep 07 '19 at 13:35