IE polyfills BPM way

Some organizations still cannot shrug Internet Explorer (IE) off their IT standards. Combine it with user interface of IBM BPM based on Javascript and your development falls back to coding practices in early 2000’s. Surely there are ways to fill the gaps with polyfills and shims, the question is how do do it neatly in BPM. Let’s see!

I had this issue couple years ago. That time our department had been already involved in long discussions with IT authority on supporting IE or not.  We used to work on daily basis with quite modern JavaScript asking users to install Chrome or Firefox. And in fact most of business users preferred moder browsers either. Nevertheless they were some new business units covered by BPM approach that grown with IE and did not want let it go.

Majority of BPM UI code could be fixed easily for IE e.g by not using missing functions like fancy lookups or filtering in arrays. Some other problems from Javascript world were irrelevant to sometimes simplistic glue-code crafted for BPM e.g. objects low-level manipulation was not needed. There were however one painstaking issue hard to fix with boilerplate code: lack of native promises in IE. Developing some widgets relying heavily on REST API of BPM meant a lot of asynchronous processing, and lack or Promise definition translated into one big clutter.

So my idea was to create single point of injection so that all developers would use all necessary shims/polyfills with lowest possible effort. In that model each widget (called coachview or CV) or screen (called coach) supposed to support IE would have injected such single item. That induced potential issue with multiple attempts to load same set of polyfills by each widget making a lot of unnecessary processing on client, traffic on the net and load to the server. Problem vanished instantly when I decided to do make injection via AMD loader, so that all heavy lifting was delivered by BPM coach engine.

Shims as web files

Bootstrapping shim in CV

 

Toolkit collecting widgets used in almost all applications had to have added compacted versions of polyfill modules that detect and fill gaps in ECMA5, ECMA6 and ECMA7 versions, namely es5-shim.min.js, es6-shim.min.js and es7-shim.min.js. With plumbing code in place I have to create single injection point, the “ie-shims.js”, and upload it also as as web file. Its purpose is to detect IE browser and run all shims, as follows:

/**
 * One script to rule them all. This script loads and executes all 
 * shims/polyfills applied in Internet Explorer environment.
 */
require(['dojo/sniff'], function (sniff) {
    // IE11 introduces itself as "trident" instead of "ie", 
    // see https://bugs.dojotoolkit.org/ticket/17311
    if (sniff("trident") || sniff("ie")) {
        var projectRootUrl = com_ibm_bpm_coach.getManagedAssetUrl('',
            com_ibm_bpm_coach.assetType_WEB, 'ANDY01');
        // remove traling slash otherwise loading JS will 
        // fail on double-slashes
        projectRootUrl = projectRootUrl.slice(0, -1);
        require({
                packages: [{
                    name: 'es5',
                    location: projectRootUrl,
                    main: 'es5-shim.min'
                }, {
                    name: 'es6',
                    location: projectRootUrl,
                    main: 'es6-shim.min'
                }, {
                    name: 'es7',
                    location: projectRootUrl,
                    main: 'es7-shim.min'
                }]
            }, ['es5', 'es6', 'es7'],
            function () {
                // At this point all shims were already loaded, 
                // executed and fixed JS environment. They are 
                // not really used here, so we just log success.
                console.debug("Loaded ES5, ES6 and ES7 shims for IE.");
            });
    }
});

Note: acronym of toolkit where code resides is ANDY01 on my example, you have to replace it with acronym of target toolkit.

Every widget that supports IE just needs to import that single file. In runtime coach engine via AMD guarantees that this file was loaded once, as well as modularized shims (defined as packages in code) loading them also one-time in current frame. Extra indirection with own single injection point also limits requests to server in non-IE browsers, as shown on screenshot.

Runtime loading IE (left) and Chrome (right)

As junior developers do not work with custom widgets frequently as well as there is some legacy code that should run in IE eihter I decided to create alternative way of bootstrapping shims in screen (coach) without touching any custom CV. I made IE shims CV that just imports ie-shims.js. Embedding this CV on screen is enough to load shims and make whole every CV’s Javascript working correctly.

Worth to mention is that there are two major drawback in IE context that shims cannot solve. First, Javascript placed on diagrams, not on screens where CVs live, runs in separate frame. It means that code is isolated from CVs logic and does not benefit from shims. I would blame here IBM clumsy desing as they do not offer any extension points to their proprietary coach engine technology so on diagrams there is no (easy/portable) way to run any custom JS from web files. Second, shims offer JS API alignment, yet they cannot extend interpterer itself, so any modern syntax – like lambdas (arrow functions) or await/async syntactic sugar on top of Promises – is unavailable in IE environment.

Even with is limited scope, shims trick for BPM saved a day of many developers who did not even feel the pain of backporting code to IE.

This entry was posted in Software and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.