Frontend Development 21 min read

How to Adapt a JavaScript SDK for IE9, IE8, and IE7 Compatibility

The guide shows how to modify a Webpack‑4 JavaScript SDK—adding Babel symbol handling, using transform‑runtime, employing Flash for IE9 cross‑domain requests, converting ES5 to ES3 with es3ify‑loader, configuring UglifyJs for IE8, polyfilling missing APIs, building a tiny selector engine, and testing on virtual IE7‑IE9 machines.

Tencent Cloud Developer
Tencent Cloud Developer
Tencent Cloud Developer
How to Adapt a JavaScript SDK for IE9, IE8, and IE7 Compatibility

To improve the development efficiency of marketing activities, a JavaScript SDK compiled with Webpack 4 was created for mobile H5 activities. As business expanded, PC and console activities also needed support, but many users run low‑version Windows or browsers that use the IE engine, causing the SDK to fail. This article describes how to make the SDK work perfectly on IE kernels.

Five major challenges for IE compatibility

IE9 and below: XMLHttpRequest does not support cross‑origin requests and XDomainRequest does not transmit cookies.

IE8 does not follow W3C standards, lacks ES5.1 support and has poor CSS3 support.

IE7 lacks many JS APIs, including postMessage .

Webpack 2+ dropped support for IE8 and below.

The SDK’s selector engine does not support IE7/IE8.

1. Running the code on IE9

Webpack 4 code throws a “symbol is undefined” error on IE9. Adding the transform-es2015-typeof-symbol plugin to .babelrc resolves the issue:

{
  "plugins": ["transform-es2015-typeof-symbol"]
}

Instead of babel-polyfill , transform-runtime is used to keep the bundle size small and avoid global pollution.

2. Supporting cross‑domain requests on IE9

IE9‑IE5 do not support CORS via XMLHttpRequest . IE9/IE8 provide XDomainRequest , which cannot send cookies. The solution is to load a Flash plugin to perform cross‑domain requests.

3. Making the bundle work on IE8

Webpack 4 output contains ES6 syntax (e.g., default , catch ) that IE8 treats as illegal identifiers. Using es3ify-loader converts ES5 to ES3, and configuring UglifyJsPlugin to keep quoted keys and disable mangling prevents the removal of IE8‑specific code:

{
  "compress": {"properties": false},
  "output": {"quote_keys": true},
  "mangle": false
}

Additionally, setting ie8: true in UglifyJsPlugin ensures IE8‑compatible output.

4. Running the code on IE8

IE8 lacks Function.prototype.bind . A polyfill is added via a separate polyfill.js that is concatenated after the Webpack bundle using a Gulp task:

gulp.task('scripts', function() {
  return gulp.src(['polyfill.js', 'dist/bundle.js'])
    .pipe(concat('bundle.ie8.js'))
    .pipe(gulp.dest('dist'));
});

Object.defineProperty is partially supported in IE8 and throws errors for non‑DOM objects. The SDK switches to the object-defineproperty-ie8 shim, which only defines properties on DOM elements.

if (!supportsAccessors) {
  // ignore non‑DOM property definitions
}

To avoid the export … from … pattern that generates accessor descriptors, the transform-es2015-modules-simple-commonjs plugin is used to produce simple CommonJS exports.

5. IE8 & IE7 defects

Various missing APIs are listed, such as:

No global JSON object.

No window.getComputedStyle .

Missing Object.keys , Array.isArray , Function.prototype.bind , etc.

Event handling must fall back to attachEvent and use e.srcElement for the target.

Opacity must be simulated with the filter CSS property.

Examples of polyfills and work‑arounds are provided for each defect, including a querySelectorAll shim for IE7/IE8.

if (!document.querySelectorAll) {
  // simple selector shim implementation
}

6. Developing a lightweight selector engine

The SDK needs a small selector engine (instead of the 20 KB jQuery Sizzle). A minimal engine based on balajs is created, with the following core:

function $(s, context) {
  if (s instanceof init) return s;
  const elements = /* querySelectorAll shim or native */;
  return new $.fn.init(s ? elements : []);
}
$.fn = {};
const init = $.fn.init = function(selector) {
  selector.forEach((ele, i) => { this[i] = ele; });
  this.length = selector.length;
  return this;
};
init.prototype = $.fn;
Object.assign($.fn, {
  click(handle) { /* ... */ },
  append(child) { /* ... */ },
  find(selector) { /* ... */ }
});

Additional utilities handle array‑like objects, DOM detection, and fallback conversions for IE8’s broken apply implementation.

const isDOM = obj => {
  if (typeof HTMLElement === 'object') return obj instanceof HTMLElement;
  return obj && typeof obj === 'object' && obj.nodeType === 1;
};
const isArrayLike = collection => {
  const length = collection.length;
  return typeof length === 'number' && length >= 0 && length <= (Math.pow(2, 53) - 1);
};

7. Summary and debugging tips

The final SDK size increased by only ~10 KB, most of which is the Flash polyfill. Debugging IE is cumbersome; the author uses Parallels Desktop with Windows 7 SP1 and Windows XP virtual machines to test IE9‑IE11 and IE7‑IE8 respectively. Proxy tools (Fiddler, Charles, Whistle) are evaluated, with Charles being the most reliable for HTTPS traffic.

Overall, the article provides a step‑by‑step guide to making a modern Webpack‑based JavaScript SDK compatible with legacy IE browsers.

frontendjavascriptBabelWebpackpolyfillIE Compatibility
Tencent Cloud Developer
Written by

Tencent Cloud Developer

Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.