開発
Introduction Web App ubiquity
Mola BogdanGeorgii
Preamble
Without a doubt, anybody can say that modern web development evolved significantly during the last years. Every week we can hear about new frameworks or at least updates. Developers get more convenience, reliability and performance. JavaScript de-facto is not just language for “making some trivial stuff in browser”, now it is something much more. It conquered other scopes like regular applications, server-side applications (for example Node.js), game development (in some form) and etc. Jimmy Lin and Kareem El Gebaly in their article claimed that the future of Big Data calculations is behind JavaScript.
But what is the price of such fast-growing progress? Unfortunately, not all fields of our civilization are so flexible, especially big companies. In the context of web development that means that for different reasons users continue to use older versions of the browser or even obsolete ones. Alternatively, it can be just a browser that does not support some features. In particular, if you are going to use some older browsers you should forget about such cool things like arrow functions, promises, string templates and many others.
Main issue
“The borders of my language are the borders of my world” (Wittgenstein)
Nobody would like to deliberately narrow his/her developer’s world by decreasing language abilities. At the same time, nobody wants to lose a variety of users that use browsers non-compatible with your code. A developer could solve this problem trying to implement absent feature but in most cases “reinventing bicycle” not best practise. Developers community is a source of fast progress at the same fast-growing manner already took care of such issue.
Basically, there are two techniques that allow solving problem: transpiling and polyfilling. According to Wiki, transpiler (or source-to-source compiler) takes your program as input and generate source code represented in another language. In context of web development it means that developer without any doubts uses something like the following code:
function someFunction(a, b, c) {};
var args = [0, 1, 2];
someFunction(...args);
That is an example of a modern JS. Next, the transpiling process will convert it to the same JS code but more browser-compatible:
function someFunction(a, b, c) {};
var args = [0, 1, 2];
someFunction.apply(void 0, args);
Looks like nothing special, but this is a very simple example that just shows how a developer can preserve the ability to use such syntax sugar as Spread operator. One of the most popular tools is Babel that can provide traspillation. It is possible to check out online how your code will be transformed.
At first glance, it could be enough but it works when dealing with syntax specifics. If the developer will use something like this:
[1, 2, 3].includes(2);
It still will not be executed on some old browsers. The most simple solution is to include the implementation of the new brand feature in your code. But it is important to keep in mind that if you are going to actively use modern syntax your code base will grow dramatically fast. For example, mentioned above code required to add:
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(valueToFind, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return false;
}
var n = fromIndex | 0;
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
while (k < len) {
if (sameValueZero(o[k], valueToFind)) {
return true;
}
k++;
}
return false;
}
});
}
Quite huge, isn’t it?
Piece of code has been taken from mozzila.org where you can find such an example for any method. What happened is called pollyfiling. An attentive reader may already notice that manual pollyfilling is not something that usually corresponds to modern development (except in some cases). Of course, solutions exist. One of the most popular is Babel (Actually it has other features as well). So, a developer can keep to use all these cool things like Promise`s, Fetch and etc.
For historical reference: author of term polyfill came from Remy Sharp as a metaphor to spackling paste that closes feature “holes” of old browsers in the context of modern web experience and, what is more important, provide mechanisms for back compatibility in the future web experience.
In a real project, parameters defined by developer stored in .babelrc file. In other cases, parameters can be stored in babel.config.js (we used it our Vue.js based project). Speaking about specific frameworks, Vue.js has built-in mechanisms with huge opportunities for tuning. Also, it has preset with more Vue oriented default configurations. In general case, crossbrowserabiltiy reached quite smooth. You should be careful with some specific dependencies installed in your project that can be not covered with default presets. For those cases, you can explicitly describe what you need to transform something by adding
transpileDependencies: ['yourLib1']
in vue.config.js. There are should be similar options if you use AngularJS or ReactJS that are actively evolving frameworks.
Another project that will help if you are going to use some cutting edge features that are only about to be added to JS standard. Its called Traceur.
If your project requirements allow a 3d party, polyfill.io your case. This service allows to load/construct polyfills on-demand, depending on the features you need.
Pollyfiling and transpilling seem to be powerful tools but unfortunately, it has limits. The most notable things are Service Workers, Push API, Bluetooth API, Proxy. Basically, such tricks supported by browsers its impossible to overcome it. More detailed information you can find here.
It worth to note security consideration about avoiding of JS based cryptography describe here.
Conclusion.
As a piece of final advice, I would like to add that as a result, you will pay with the growing size of your code. So, you should pay attention and adopt appropriate options for your project to avoid a significant increase in traffic. Please don’t give up trying to provide ubiquity for your web app and give an opportunity for people with different browsers to keep their preferences.
Conclusion.
In this short attempt to describe a really huge topic that is only part of chaotically evolving world of web development that produces a mess where there are many ways to solve a task. Most likely your project will face some specific problems there is no Silver bullet. However, I would like to provide a few links for resources that will help to advance understanding.
- Big article with a detailed description
- For Vue.js users example of a project with Babel configuration
- Typical troubleshooting examples:
- Work of Vue with IE11
- Babel configuration for Vue
- Vue app blank page in IE 11
- ES6 and VUE JS not working in IE 11
- Internet Explorer 11 detection
- Saving files locally using Blob and msSaveBlob
- IE 9+ Download Attribute workaround
- Not working A tag with download attribute