Awesome
⚠️ This repo is no longer maintained.
As replacement use https://github.com/zloirock/core-js
Autopolyfiller — Precise polyfills
This is like Autoprefixer, but for JavaScript polyfills. It scans your code and applies only required polyfills. Live example.
Assume you code is Object.keys(window)
. Object.keys
polyfill is required to run it in any browser (include IE7). On the other hand this code can be executed on iOS 7 Safari without any polyfills. AutoPolyfiller knows about ES5 and ES6 features and their support in browsers. It can help you to write cutting-edge JavaScript without thinking about ES shims and shivs.
How it works. Step by step:
- Using AST matchers, it scans your code and finds all polyfills
- If target browsers are specified, then it reduces the list of polyfills according to the "feature database"
- It generates polyfills code, using polyfills database, which precisely fixes only required features
Limitations:
- Right now it supports only safe and cross-browser polyfills from ES5, but you can add your own (see examples).
- It can have a false-positives for some cases. For instance, autopolyfiller thinks that
$('div').map()
is call ofArray.prototype.map
. But you can exclude false-positives (see examples).
It will not work if:
- You are
eval
ing code with polyfills. Egeval('Object.keys(this)')
- You are doing something odd. Eg
Object['k' + 'eys']()
Installation
autopolyfiller
can be installed using npm
:
npm install autopolyfiller
CLI Example
$ autopolyfiller lib/**/*.js -b "Explorer 7, Chrome >= 10"
$ cat lib/*.js | autopolyfiller
Grunt, Gulp, Enb tasks, and Webpack loader
- grunt-autopolyfiller - Grunt task for autopolyfiller.
- gulp-autopolyfiller - Gulp task for autopolyfiller.
- enb-autopolyfiller - Enb task for autopolyfiller.
- autopolyfiller-loader - Webpack loader for autopolyfiller.
Example
// Polyfills + Code
require('autopolyfiller')().add(code) + code;
List of polyfills without browsers filtering
var autopolyfiller = require('autopolyfiller');
autopolyfiller()
.add('"".trim();')
.polyfills;
// ['String.prototype.trim']
Filtering using Autoprefixer-style browser matchers
var autopolyfiller = require('autopolyfiller');
autopolyfiller('IE 11', 'Chrome >= 31')
.add('"".trim();Object.create();new Promise()')
.polyfills;
// ['Promise']
Default autoprefixer browsers
var autopolyfiller = require('autopolyfiller'),
autoprefixer = require('autopolyfiller');
autopolyfiller(autoprefixer.default)
.add('new Promise();')
.polyfills;
// ['Promise']
Excluding/including polyfills
var autopolyfiller = require('autopolyfiller');
autopolyfiller()
.exclude(['Promise'])
.include(['String.prototype.trim'])
// All Array polyfills
.include(['Array.*'])
.add('new My.Promise();')
.polyfills;
// ['String.prototype.trim']
Using custom parser
var autopolyfiller = require('autopolyfiller');
autopolyfiller()
.withParser('acorn@0.11.0', {ecmaVersion: 6})
.add('array.map(x => x * x)')
.polyfills;
// ['Array.prototype.map']
Adding your own polyfills
var query = require('grasp-equery').query;
var autopolyfiller = require('autopolyfiller');
autopolyfiller.use({
// AST tree pattern matching
// It may "grep" multiply polyfills
test: function (ast) {
return query('Object.newFeature(_$)', ast).length > 0 ? ['Object.newFeature'] : [];
},
// Your polyfills code
polyfill: {
'Object.newFeature': 'Object.newFeature = function () {};'
},
// This list means "apply this feature to the <list of browsers>"
// For more examples see https://github.com/jonathantneal/polyfill/blob/master/agent.js.json
support: {
// For chrome 29 only apply Object.newFeature polyfill
'Chrome': [{
only: '29',
fill: 'Object.newFeature'
}]
},
// This is optional. By default autopolyfiller will use
// polyfill's name to generate condition's code:
wrapper: {
'Object.newFeature': {
'before': 'if (!("newFeature" in Object)) {',
'after': '}'
}
}
});
autopolyfiller()
.add('Object.create();Object.newFeature();')
.polyfills;
// ['Object.create', 'Object.newFeature']
autopolyfiller()
.add('Object.newFeature();')
.toString();
// if (!("newFeature" in Object)) {
// Object.newFeature = function () {};
// }
autopolyfiller('Chrome >= 20')
.add('Object.create();Object.newFeature();')
.polyfills;
// []
Handling polyfills issues
Right now Autopolyfiller aggreagates existing sources of polyfills. If you have any issues related to a polyfill code itself, please, add an issue or a pull request to the jonathantneal/polyfill.
Here is how to temporary workaround, while your issue being resolved:
var autopolyfiller = require('autopolyfiller');
autopolyfiller.use({
polyfill: {
'Function.prototype.bind': 'fixed code (!Function.prototype.bind)'
}
});