├── .babelrc ├── .devolutionrc.js ├── .gitignore ├── .npmignore ├── README.md ├── __tests__ ├── __fixtures__ │ └── babel │ │ ├── generator │ │ ├── actual.js │ │ └── expected.json │ │ ├── node │ │ ├── actual.js │ │ └── expected.json │ │ └── static-fields │ │ ├── actual.js │ │ └── expected.json ├── detector.spec.js └── utils.spec.js ├── assets └── devo-logo.jpg ├── bin └── devolution ├── jest.config.js ├── package.json ├── src ├── cli.js ├── data │ ├── README.md │ ├── corejs2 │ │ ├── built-in-definitions.js │ │ ├── built-ins.js │ │ └── index.js │ ├── corejs3 │ │ ├── built-in-definitions.js │ │ ├── built-ins.js │ │ └── index.js │ └── esmBaseline.js ├── index.js ├── plugins │ └── detectPolyfills.js ├── rc.js ├── smoke-tester.js ├── utils.js └── workers │ ├── composePolyfill.js │ ├── detect.js │ └── transpile.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env", { 4 | "targets": { 5 | "node": "10" 6 | } 7 | }] 8 | ], 9 | "plugins": [ 10 | "@babel/plugin-proposal-class-properties", 11 | "@babel/plugin-syntax-dynamic-import" 12 | ] 13 | } -------------------------------------------------------------------------------- /.devolutionrc.js: -------------------------------------------------------------------------------- 1 | // devolution 🦎 -> 🦖 2 | 3 | /** 4 | what about shipping the BEST for the bleeding edge browsers? 5 | (requires SSR or feature detection for proper shipping) 6 | */ 7 | const USE_MODERN = false; 8 | 9 | module.exports = Promise.resolve({ // could be async 10 | /** 11 | * core-js version. Version 3 is more modern, while version 2 is more common 12 | * this __must__ be synchoronized with corejs version visible to babel, and installed by you 13 | * (if not installed, then it's v2) 14 | */ 15 | corejs: "3", 16 | /** 17 | * include proposals polyfills, core-js 3 only 18 | */ 19 | proposals: false, 20 | 21 | /** 22 | * if set to `false` it would SYMLINK files, effective keeping only one version for files 23 | * not managed by devolution (read - non-js). 24 | * If set to `true` - all files would be copied. 25 | */ 26 | copyFiles: false, 27 | 28 | /** 29 | * files to add could be RegExp or array 30 | */ 31 | match: /\.js$/, 32 | 33 | /** 34 | * these chunks expected to always be loaded, for example this could be your entry point(s) 35 | */ 36 | rootBundles: null, 37 | 38 | /** 39 | * are polyfills included in the baseline bundle? If yes no polyfills which "might be" required for esmodules target would be added 40 | * IT'S BETTER TO INCLUDE THEM 41 | * to prevent duplication among chunks 42 | * (keep in mind - polyfills landed in the main bundle will not be duplicated) 43 | */ 44 | includesPolyfills: false, 45 | 46 | /** 47 | https://github.com/swc-project/swc 48 | roughly TWICE faster than babel, used only for es5 target. 49 | however, it produces a bit different code. PLEASE CHECK THE RESULT! 50 | When to use: when babel is to slow, or failing our of memory 51 | **/ 52 | useSWC: false, 53 | /** 54 | * the result bundle might be "prettied", so some light minification might be needed 55 | */ 56 | useTerser: true, 57 | /** 58 | * apply minification for the baseline bundle 59 | */ 60 | useTerserForBaseline: false, 61 | 62 | /** 63 | controls syntax and polyfill level 64 | `esm` and `es5` are reserved keywords - `esm` means "no transformation required", and `es5` means - target is `es5` 65 | the values inside are used to determine required polyfills 66 | **/ 67 | targets: { 68 | /** 69 | * ESM controls ONLY polyfills. No code transformation to be made! 70 | */ 71 | esm: USE_MODERN 72 | ? { 73 | "chrome": "70", // if baseline bundle used preset-modern use some "big" target, but ship only for this "big" target! 74 | } 75 | : { 76 | // this controls polyfills for ESM bundle 77 | // you might be surprised how many of them might be bundled 78 | // core-js 3 : see https://github.com/zloirock/core-js/blob/master/packages/core-js-compat/src/data.js 79 | // core-js 2 : see https://github.com/theKashey/devolution/blob/master/src/data/corejs2/built-ins.js 80 | 81 | // if baseline bundle used preset-env+esmodules - https://github.com/babel/babel/blob/master/packages/babel-preset-env/data/built-in-modules.json 82 | "edge": "16", 83 | "firefox": "60", 84 | "chrome": "61", 85 | "safari": "10.1", 86 | }, 87 | 88 | // es6: { something between IE5 and bleeding edge? } 89 | 90 | /** 91 | * the legacy target (you might need only it) 92 | * it is roughly "just ES5". Target (ie11) controls polyfills 93 | */ 94 | es5: { 95 | // list the lowest browser here, it would not affect the "language", only polyfills 96 | "ie": "11", // do not support IE9, and IE10 97 | }, 98 | }, 99 | 100 | /** 101 | * plugins for the scan(detect polyfills) pass 102 | */ 103 | babelScan: [ 104 | '@babel/plugin-syntax-object-rest-spread', 105 | '@babel/plugin-syntax-class-properties', 106 | '@babel/plugin-syntax-dynamic-import', 107 | ], 108 | 109 | /** 110 | * plugins for transformation pass 111 | */ 112 | babelTransform: [ 113 | '@babel/plugin-proposal-object-rest-spread', 114 | '@babel/plugin-proposal-class-properties', 115 | '@babel/plugin-syntax-dynamic-import', 116 | ], 117 | 118 | // some files might be excluded from polyfilling 119 | dontPolyfill: [ 120 | /manifest/, // dont polyfill webpack manifest 121 | ], 122 | 123 | // injects some target specific polyfills to the "main bundle" 124 | addPolyfills: { 125 | esm: [ 126 | // probably none? 127 | ], 128 | es5: [ 129 | // which? what about a few "ignored" ones? 130 | // or, like, regenerator runtime? (ignore it beforehand) 131 | // 'regenerator-runtime', 132 | ] 133 | }, 134 | /** 135 | * Some polyfills might be "manually" bundled, or you just might dont need them - automatic detection is not perfect. 136 | * Let's us know which... 137 | */ 138 | ignorePolyfills: [ 139 | // put a list of polyfills to ignore, they would be considered as already added 140 | 141 | // WeakMap is defacto supported my IE11, but not listed compact table and would be included in any case 142 | "es6.weak-map", 143 | 144 | // almost any library has a failback for Symbol support 145 | 'es6.symbol', 146 | 'es7.symbol.async-iterator', 147 | 148 | // and almost no library uses extra RegExp features 149 | 'es6.regexp.flags', 150 | ] 151 | }); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /lib/ 3 | /dist/ 4 | coverage 5 | .DS_Store 6 | .nyc_output 7 | yarn-error.log 8 | _tests/dist -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | _tests 2 | assets 3 | yarn.lock -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

🦎 -> DEvolution -> 🦖

3 |
4 | devolution 5 |
6 |
7 | de-evolution gun, as seen in Mario Bros, to help you ship modern, and de-modernized bundles. 8 |
9 |
10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | ## Why? 18 | - ship more modern, more compact and more fast code to 85+% of your customers 19 | - do not worry about transpiling node_modules - use as modern code as you can everywhere 20 | - don't be bound to the bundler 21 | - well, it's just faster than a `multi-compiler mode` and __100% customizable__. 22 | 23 | - 🚀 fast - uses [swc](https://github.com/swc-project/swc) to be a blazing 🔥 fast! 24 | - 📱 multi threaded - uses [jest-worker](https://github.com/facebook/jest/tree/master/packages/jest-worker) to consume all your CPU cores 25 | - 🗜 compact - uses [terser](https://github.com/terser-js/terser) without mangling to re-compress the result 26 | - 🦎 optimized - uses [rollup](https://rollupjs.org/guide/en/) to handle polyfills 27 | - 🦖 supports `core-js` 2 and 3 28 | 29 | ### TWO bundles to rule the world 30 | 31 | - One for "esm"(modern) browsers, which you may load using `type=module` 32 | - Another for an "old"(legacy) browser, which you may load using `nomodule` 33 | 34 | ## Usage 35 | ### 1. Compile your code to the `modern` target and call it a "baseline". 36 | 1. Prefer [preset-modules](https://github.com/babel/preset-modules) 37 | ```json 38 | { 39 | "presets": [ 40 | "@babel/preset-modules" 41 | ] 42 | } 43 | ``` 44 | 2. However, feel free to use [preset-env with esmodules](https://babeljs.io/docs/en/babel-preset-env#targetsesmodules) 45 | ```json 46 | { 47 | "presets": [ 48 | ["@babel/preset-env", { 49 | "targets": { 50 | "esmodules": true 51 | }, 52 | "useBuiltIns": "usage" 53 | }] 54 | ] 55 | } 56 | ``` 57 | > `useBuiltIns` are optional, and plays well with `includesPolyfills` option in `.devolutionrc` 58 | 59 | 3. [sucrase](https://github.com/alangpierce/sucrase) is an option 60 | `sucrase` is much faster than babel(and swc), however is able to produce only "modern" code. 61 | However, this is what we need. 62 | If your code is not using babel plugins, and non-yet-supported by the browsers code - feel free to use it. 63 | 64 | ### 2. Fire devolution to produce de-modernized bundles 65 | > the first run would create `.devolutionrc.js`, which could be used to tune some details 66 | ```bash 67 | yarn devolution from to 68 | // like 69 | yarn devolution dist dist 70 | ``` 71 | It will convert all files in `dist` into `esm` and `es5` targets in the same `dist` 72 | 73 | > By default it will handle only files in the directory, __not__ including subdirs. 74 | You might return array of files via `.devolutionrc` to handle all your files 75 | 76 | ### 3 (Only webpack) setup `public-path`, somewhere close to the script start 77 | ```js 78 | __webpack_public_path__ = devolutionBundle + '/'; // devolutionBundle is a predefined variable 79 | ``` 80 | > `Parcel` will configure public path automatically. 81 | 82 | 83 | #### Symlink 84 | Then `devolution` will symlink resources to "sub-bundles" 85 | 86 | ### 4. Ship the right script to the browser 87 | Please __dont use__ code like this 88 | ```html 89 | 90 | 91 | ``` 92 | 93 | It does not work well for the really "old" browsers - __IE11 will download both bundles__, but execute only the right one. 94 | This syntax would made things even worse for the legacy browsers. 95 | 96 | Use feature detection to pick the right bundle: 97 | ```js 98 | var script = document.createElement('script'); 99 | var prefix = (!('noModule' in script)) ? "/ie11" : "/esm"; 100 | script.src = prefix + "/index.js"; // or main? you better know 101 | document.head.appendChild(script); 102 | ``` 103 | This "prefix" is all you need. 104 | 105 | ### 4, again. SSR this time 106 | However, it's much better to use Server Side logic to pick the right bundle - you might control 107 | which bundle should be shipped in which case. 108 | 109 | But default - use the same `browsers` as they are listed in `.devolutionrc.js` `targets` for `esm`, 110 | however - you might "raise the bar", shipping modern code only to `Chrome 80+`, 111 | or introduce __more than two__ bundles - the "language" in the top ones could be the same, but polyfills set would be different. 112 | 113 | ```js 114 | import UA from 'browserslist-useragent' 115 | 116 | export const isModernBrowser = (userAgent) => { 117 | return UA.matchesUA(userAgent, { 118 | _allowHigherVersions: true, 119 | browsers: [ 120 | "Chrome >= 61", 121 | "Safari >= 10.1", 122 | "iOS >= 11.3", 123 | "Firefox >= 60", 124 | "Edge >= 16" 125 | ] 126 | }) 127 | } 128 | 129 | function renderApp(req, res) { 130 | const userAgent = req.headers['user-agent']; 131 | 132 | const bundleMode = isModernBrowser(userAgent) ? 'esm' : 'es5'; 133 | // send the right scripts 134 | } 135 | ``` 136 | 137 | See [Optimising JS Delivery](https://dev.to/thekashey/optimising-js-delivery-4h6l) for details 138 | 139 | ### 5. Done! 140 | 141 | A few minutes to setup, a few seconds to build 142 | 143 | 144 | ## Tuning 145 | See `.devolutionrc.js`, it contains all information you might look for 146 | 147 | ## FAQ 148 | 149 | ##### Why two separate folders? 150 | In the most articles, you might find online, ES5 and ES6 bundles are generated independently, 151 | and ES5 uses `.js` extension, while ES6 uses `.mjs`. 152 | 153 | That requires two real bundling steps as long as "hashes" of files and "chunk names", bundles inside `runtime-chunk` would be different. 154 | That's why we generate two folders - to be able just to use prefix, to enable switching between bundles just using 155 | `__webpack_public_path__` or parcel script location autodetection. 156 | 157 | ##### Drawbacks 158 | 159 | - __!!__ doesn't play well with script _prefetching_ - you have to manually specify to prefetch `esm` version, 160 | not the "original" one. 161 | - may duplicate polyfills across the chunks. Don't worry much 162 | 163 | ##### (default) Targets for "esm" 164 | - edge: "16+", 165 | - firefox: "60+", 166 | - chrome: "61+", 167 | - safari: "10.1+", 168 | (2017+) 169 | 170 | ##### (default) Targets for "ie5" 171 | - ie: "11-" 172 | 173 | That's is the oldest living browser, and can be used as a base line. 174 | 175 | #### SWC 176 | SWC is much faster than babel, however not as stable and might produce broken code. 177 | Controlled by `useSWC`, disabled by default 178 | 179 | #### Terser 180 | There are two options, which control minification - `useTerser` and `useTerserForBaseline`. 181 | You __have__ to enable `useTerser` if you enable `useSWC` as long as it produces non minified code. 182 | 183 | ### API 184 | You may file devolution manually 185 | ```js 186 | import {devolute} from 'devolution'; 187 | 188 | devolute(sourceDist, destDist, options) 189 | 190 | // for example 191 | 192 | devolute( 193 | 'dist', // the default webpack output 194 | 'dist', // the same directory could be used as well 195 | require('.devolutionrc') 196 | ) 197 | ``` 198 | 199 | # License 200 | MIT 201 | -------------------------------------------------------------------------------- /__tests__/__fixtures__/babel/generator/actual.js: -------------------------------------------------------------------------------- 1 | async function* func1 () { 2 | yield await 1; 3 | } 4 | 5 | function* func2 () { 6 | yield 1; 7 | } -------------------------------------------------------------------------------- /__tests__/__fixtures__/babel/generator/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "2": { 3 | "polyfills": [ 4 | "es6.object.to-string", 5 | "es6.promise" 6 | ], 7 | "flags": { 8 | "usesRegenerator": true 9 | } 10 | }, 11 | "3": { 12 | "polyfills": [ 13 | "es.promise", 14 | "es.object.to-string" 15 | ], 16 | "flags": { 17 | "usesRegenerator": true 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /__tests__/__fixtures__/babel/node/actual.js: -------------------------------------------------------------------------------- 1 | new Promise(() => { 2 | const map = new Map(); 3 | }); -------------------------------------------------------------------------------- /__tests__/__fixtures__/babel/node/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "2": { 3 | "polyfills": [ 4 | "es6.object.to-string", 5 | "es6.promise", 6 | "es6.map", 7 | "es6.string.iterator", 8 | "es6.array.iterator", 9 | "web.dom.iterable" 10 | ], 11 | "flags": { 12 | "usesRegenerator": false 13 | } 14 | }, 15 | "3": { 16 | "polyfills": [ 17 | "es.promise", 18 | "es.object.to-string", 19 | "es.map", 20 | "esnext.map.delete-all", 21 | "esnext.map.every", 22 | "esnext.map.filter", 23 | "esnext.map.find", 24 | "esnext.map.find-key", 25 | "esnext.map.includes", 26 | "esnext.map.key-of", 27 | "esnext.map.map-keys", 28 | "esnext.map.map-values", 29 | "esnext.map.merge", 30 | "esnext.map.reduce", 31 | "esnext.map.some", 32 | "esnext.map.update", 33 | "es.string.iterator", 34 | "es.array.iterator", 35 | "web.dom-collections.iterator" 36 | ], 37 | "flags": { 38 | "usesRegenerator": false 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /__tests__/__fixtures__/babel/static-fields/actual.js: -------------------------------------------------------------------------------- 1 | Number.isInteger(20); -------------------------------------------------------------------------------- /__tests__/__fixtures__/babel/static-fields/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "2": { 3 | "polyfills": [ 4 | "es6.number.is-integer", 5 | "es6.number.constructor" 6 | ], 7 | "flags": { 8 | "usesRegenerator": false 9 | } 10 | }, 11 | "3": { 12 | "polyfills": [ 13 | "es.number.is-integer", 14 | "es.number.constructor" 15 | ], 16 | "flags": { 17 | "usesRegenerator": false 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /__tests__/detector.spec.js: -------------------------------------------------------------------------------- 1 | import {transform} from '@babel/core' 2 | import {join} from 'path' 3 | import {readdirSync, statSync, readFileSync} from 'fs' 4 | 5 | import corejs2 from '../src/data/corejs2'; 6 | import corejs3 from '../src/data/corejs3'; 7 | 8 | const FIXTURE_PATH = join(__dirname, '__fixtures__/babel'); 9 | 10 | const testFolders = readdirSync(FIXTURE_PATH).filter(file => 11 | statSync(join(FIXTURE_PATH, file)).isDirectory(), 12 | ); 13 | 14 | const testPlugin = (code, definitions) => { 15 | const polyfills = []; 16 | const flags = { 17 | usesRegenerator: false 18 | }; 19 | transform(code, { 20 | plugins: [ 21 | require('../src/plugins/detectPolyfills').default(polyfills, flags, definitions) 22 | ], 23 | }); 24 | 25 | return { 26 | polyfills, 27 | flags, 28 | }; 29 | }; 30 | 31 | 32 | describe('babel', () => { 33 | 34 | testFolders.forEach(folderName => { 35 | const actual = readFileSync( 36 | join(FIXTURE_PATH, folderName, 'actual.js'), 37 | 'utf8', 38 | ); 39 | const expected = readFileSync( 40 | join(FIXTURE_PATH, folderName, 'expected.json'), 41 | 'utf8', 42 | ); 43 | 44 | it(`works with ${folderName}`, () => { 45 | const result = JSON.stringify({ 46 | 2: testPlugin(actual, corejs2.definitions), 47 | 3: testPlugin(actual, corejs3.definitions), 48 | }, null, 2); 49 | expect(result).toEqual(expected); 50 | }) 51 | }) 52 | }); -------------------------------------------------------------------------------- /__tests__/utils.spec.js: -------------------------------------------------------------------------------- 1 | import {isBelow} from "../src/utils"; 2 | import {esmBaseline} from "../src/data/esmBaseline"; 3 | 4 | describe("utils", () => { 5 | describe("isBelow", () => { 6 | it("X below Y", () => { 7 | expect(isBelow('any', {ie: 11}, {chrome: 70})).toBe(true); 8 | }); 9 | 10 | it("ie11 above ie9", () => { 11 | expect(isBelow('any', {ie: 9}, {ie: 11})).toBe(false); 12 | }); 13 | 14 | it("chrome 70 above chrome 60", () => { 15 | expect(isBelow('any', {chrome: 60, ie: 9}, {chrome: 70})).toBe(false); 16 | }); 17 | 18 | it("however, two conditions changes it", () => { 19 | expect(isBelow('any', {chrome: 60, ie: 10}, {chrome: 70, ie: 9})).toBe(true); 20 | }); 21 | 22 | it('esm baseline is above ie11', () => { 23 | expect(isBelow('any', esmBaseline, {ie: 11})).toBe(true); 24 | }); 25 | }); 26 | }); -------------------------------------------------------------------------------- /assets/devo-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theKashey/devolution/201b9f26ee3e23b14eddeffc0d26dfa187471878/assets/devo-logo.jpg -------------------------------------------------------------------------------- /bin/devolution: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('../dist/cli'); -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testMatch: ['**/__tests__/*.spec.js'], 3 | }; 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "devolution", 3 | "version": "2.3.1", 4 | "description": "A devolution gun for your bundle", 5 | "main": "./dist/index.js", 6 | "scripts": { 7 | "test": "jest", 8 | "build": "babel src -d dist" 9 | }, 10 | "bin": { 11 | "devolution": "./bin/devolution" 12 | }, 13 | "files": [ 14 | "dist", 15 | "bin", 16 | ".devolutionrc.js" 17 | ], 18 | "repository": "https://github.com/theKashey/devolution/", 19 | "author": "theKashey ", 20 | "license": "MIT", 21 | "homepage": "https://github.com/theKashey/devolution#readme", 22 | "peerDependencies": { 23 | "@swc/core": "^1.0.48" 24 | }, 25 | "dependencies": { 26 | "@babel/plugin-proposal-class-properties": "^7.7.0", 27 | "@babel/plugin-proposal-object-rest-spread": "^7.6.2", 28 | "@babel/plugin-syntax-class-properties": "^7.2.0", 29 | "@babel/plugin-syntax-dynamic-import": "^7.2.0", 30 | "@babel/plugin-syntax-object-rest-spread": "^7.2.0", 31 | "@babel/preset-env": "^7.7.1", 32 | "chalk": "^3.0.0", 33 | "core-js-compat": "^3.4.2", 34 | "jest": "^24.9.0", 35 | "jest-worker": "^24.0.0", 36 | "regenerator-runtime": "^0.13.3", 37 | "rollup": "^1.27.5", 38 | "rollup-plugin-commonjs": "^10.1.0", 39 | "rollup-plugin-node-resolve": "^5.2.0", 40 | "rollup-plugin-replace": "^2.2.0", 41 | "table": "^5.4.6", 42 | "terser": "^4.4.0" 43 | }, 44 | "devDependencies": { 45 | "@babel/cli": "^7.2.3", 46 | "@babel/core": "^7.3.3", 47 | "@babel/register": "^7.0.0", 48 | "@swc/core": "^1.0.54", 49 | "chai": "^4.2.0" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/cli.js: -------------------------------------------------------------------------------- 1 | import {resolve} from 'path' 2 | import {scan} from './index'; 3 | import {ensureRCExists} from "./rc"; 4 | 5 | if (!process.argv || !process.argv[3]) { 6 | console.log('usage: devolution source target '); 7 | console.log('example: devolution dist dist'); 8 | ensureRCExists(); 9 | } else { 10 | Promise.resolve( 11 | scan(resolve(process.argv[2]), resolve(process.argv[3])) 12 | ) 13 | .then(code => { 14 | if (!code) { 15 | process.exit(-1); 16 | } 17 | }) 18 | .catch(err => { 19 | console.error(err); 20 | process.exit(-1) 21 | }) 22 | } -------------------------------------------------------------------------------- /src/data/README.md: -------------------------------------------------------------------------------- 1 | These files are left here to tackle dependency on babel internals 2 | 3 | - @babel/preset-env/data/built-ins.json.js 4 | - @babel/preset-env/lib/polyfills/corejs3/built-in-definitions.js -------------------------------------------------------------------------------- /src/data/corejs2/built-in-definitions.js: -------------------------------------------------------------------------------- 1 | const ArrayNatureIterators = [ 2 | "es6.object.to-string", 3 | "es6.array.iterator", 4 | "web.dom.iterable", 5 | ]; 6 | 7 | export const CommonIterators = ["es6.string.iterator", ...ArrayNatureIterators]; 8 | 9 | export const PromiseDependencies = ["es6.object.to-string", "es6.promise"]; 10 | 11 | export const BuiltIns = { 12 | DataView: "es6.typed.data-view", 13 | Float32Array: "es6.typed.float32-array", 14 | Float64Array: "es6.typed.float64-array", 15 | Int8Array: "es6.typed.int8-array", 16 | Int16Array: "es6.typed.int16-array", 17 | Int32Array: "es6.typed.int32-array", 18 | Map: ["es6.map", ...CommonIterators], 19 | Number: "es6.number.constructor", 20 | Promise: PromiseDependencies, 21 | RegExp: ["es6.regexp.constructor"], 22 | Set: ["es6.set", ...CommonIterators], 23 | Symbol: ["es6.symbol", "es7.symbol.async-iterator"], 24 | Uint8Array: "es6.typed.uint8-array", 25 | Uint8ClampedArray: "es6.typed.uint8-clamped-array", 26 | Uint16Array: "es6.typed.uint16-array", 27 | Uint32Array: "es6.typed.uint32-array", 28 | WeakMap: ["es6.weak-map", ...CommonIterators], 29 | WeakSet: ["es6.weak-set", ...CommonIterators], 30 | }; 31 | 32 | export const InstanceProperties = { 33 | __defineGetter__: ["es7.object.define-getter"], 34 | __defineSetter__: ["es7.object.define-setter"], 35 | __lookupGetter__: ["es7.object.lookup-getter"], 36 | __lookupSetter__: ["es7.object.lookup-setter"], 37 | anchor: ["es6.string.anchor"], 38 | big: ["es6.string.big"], 39 | bind: ["es6.function.bind"], 40 | blink: ["es6.string.blink"], 41 | bold: ["es6.string.bold"], 42 | codePointAt: ["es6.string.code-point-at"], 43 | copyWithin: ["es6.array.copy-within"], 44 | endsWith: ["es6.string.ends-with"], 45 | entries: ArrayNatureIterators, 46 | every: ["es6.array.is-array"], 47 | fill: ["es6.array.fill"], 48 | filter: ["es6.array.filter"], 49 | finally: ["es7.promise.finally", ...PromiseDependencies], 50 | find: ["es6.array.find"], 51 | findIndex: ["es6.array.find-index"], 52 | fixed: ["es6.string.fixed"], 53 | flags: ["es6.regexp.flags"], 54 | flatMap: ["es7.array.flat-map"], 55 | fontcolor: ["es6.string.fontcolor"], 56 | fontsize: ["es6.string.fontsize"], 57 | forEach: ["es6.array.for-each"], 58 | includes: ["es6.string.includes", "es7.array.includes"], 59 | indexOf: ["es6.array.index-of"], 60 | italics: ["es6.string.italics"], 61 | keys: ArrayNatureIterators, 62 | lastIndexOf: ["es6.array.last-index-of"], 63 | link: ["es6.string.link"], 64 | map: ["es6.array.map"], 65 | match: ["es6.regexp.match"], 66 | name: ["es6.function.name"], 67 | padStart: ["es7.string.pad-start"], 68 | padEnd: ["es7.string.pad-end"], 69 | reduce: ["es6.array.reduce"], 70 | reduceRight: ["es6.array.reduce-right"], 71 | repeat: ["es6.string.repeat"], 72 | replace: ["es6.regexp.replace"], 73 | search: ["es6.regexp.search"], 74 | slice: ["es6.array.slice"], 75 | small: ["es6.string.small"], 76 | some: ["es6.array.some"], 77 | sort: ["es6.array.sort"], 78 | split: ["es6.regexp.split"], 79 | startsWith: ["es6.string.starts-with"], 80 | strike: ["es6.string.strike"], 81 | sub: ["es6.string.sub"], 82 | sup: ["es6.string.sup"], 83 | toISOString: ["es6.date.to-iso-string"], 84 | toJSON: ["es6.date.to-json"], 85 | toString: [ 86 | "es6.object.to-string", 87 | "es6.date.to-string", 88 | "es6.regexp.to-string", 89 | ], 90 | trim: ["es6.string.trim"], 91 | trimEnd: ["es7.string.trim-right"], 92 | trimLeft: ["es7.string.trim-left"], 93 | trimRight: ["es7.string.trim-right"], 94 | trimStart: ["es7.string.trim-left"], 95 | values: ArrayNatureIterators, 96 | }; 97 | 98 | export const StaticProperties = { 99 | Array: { 100 | from: ["es6.array.from", "es6.string.iterator"], 101 | isArray: "es6.array.is-array", 102 | of: "es6.array.of", 103 | }, 104 | 105 | Date: { 106 | now: "es6.date.now", 107 | }, 108 | 109 | Object: { 110 | assign: "es6.object.assign", 111 | create: "es6.object.create", 112 | defineProperty: "es6.object.define-property", 113 | defineProperties: "es6.object.define-properties", 114 | entries: "es7.object.entries", 115 | freeze: "es6.object.freeze", 116 | getOwnPropertyDescriptors: "es7.object.get-own-property-descriptors", 117 | getOwnPropertySymbols: "es6.symbol", 118 | is: "es6.object.is", 119 | isExtensible: "es6.object.is-extensible", 120 | isFrozen: "es6.object.is-frozen", 121 | isSealed: "es6.object.is-sealed", 122 | keys: "es6.object.keys", 123 | preventExtensions: "es6.object.prevent-extensions", 124 | seal: "es6.object.seal", 125 | setPrototypeOf: "es6.object.set-prototype-of", 126 | values: "es7.object.values", 127 | }, 128 | 129 | Math: { 130 | acosh: "es6.math.acosh", 131 | asinh: "es6.math.asinh", 132 | atanh: "es6.math.atanh", 133 | cbrt: "es6.math.cbrt", 134 | clz32: "es6.math.clz32", 135 | cosh: "es6.math.cosh", 136 | expm1: "es6.math.expm1", 137 | fround: "es6.math.fround", 138 | hypot: "es6.math.hypot", 139 | imul: "es6.math.imul", 140 | log1p: "es6.math.log1p", 141 | log10: "es6.math.log10", 142 | log2: "es6.math.log2", 143 | sign: "es6.math.sign", 144 | sinh: "es6.math.sinh", 145 | tanh: "es6.math.tanh", 146 | trunc: "es6.math.trunc", 147 | }, 148 | 149 | String: { 150 | fromCodePoint: "es6.string.from-code-point", 151 | raw: "es6.string.raw", 152 | }, 153 | 154 | Number: { 155 | EPSILON: "es6.number.epsilon", 156 | MIN_SAFE_INTEGER: "es6.number.min-safe-integer", 157 | MAX_SAFE_INTEGER: "es6.number.max-safe-integer", 158 | isFinite: "es6.number.is-finite", 159 | isInteger: "es6.number.is-integer", 160 | isSafeInteger: "es6.number.is-safe-integer", 161 | isNaN: "es6.number.is-nan", 162 | parseFloat: "es6.number.parse-float", 163 | parseInt: "es6.number.parse-int", 164 | }, 165 | 166 | Promise: { 167 | all: CommonIterators, 168 | race: CommonIterators, 169 | }, 170 | 171 | Reflect: { 172 | apply: "es6.reflect.apply", 173 | construct: "es6.reflect.construct", 174 | defineProperty: "es6.reflect.define-property", 175 | deleteProperty: "es6.reflect.delete-property", 176 | get: "es6.reflect.get", 177 | getOwnPropertyDescriptor: "es6.reflect.get-own-property-descriptor", 178 | getPrototypeOf: "es6.reflect.get-prototype-of", 179 | has: "es6.reflect.has", 180 | isExtensible: "es6.reflect.is-extensible", 181 | ownKeys: "es6.reflect.own-keys", 182 | preventExtensions: "es6.reflect.prevent-extensions", 183 | set: "es6.reflect.set", 184 | setPrototypeOf: "es6.reflect.set-prototype-of", 185 | }, 186 | }; 187 | 188 | export const CommonInstanceDependencies = [ 189 | "es6.object.to-string", 190 | "es7.object.define-getter", 191 | "es7.object.define-setter", 192 | "es7.object.lookup-getter", 193 | "es7.object.lookup-setter", 194 | ]; 195 | 196 | 197 | export const PossibleGlobalObjects = [ 198 | "global", 199 | "globalThis", 200 | "self", 201 | "window", 202 | ]; -------------------------------------------------------------------------------- /src/data/corejs2/built-ins.js: -------------------------------------------------------------------------------- 1 | export default { 2 | "es6.array.copy-within": { 3 | "chrome": "45", 4 | "edge": "12", 5 | "firefox": "32", 6 | "safari": "9", 7 | "node": "4", 8 | "ios": "9", 9 | "samsung": "5", 10 | "opera": "32", 11 | "electron": "0.35" 12 | }, 13 | "es6.array.every": { 14 | "chrome": "5", 15 | "opera": "10.10", 16 | "edge": "12", 17 | "firefox": "2", 18 | "safari": "3.1", 19 | "node": "0.10", 20 | "ie": "9", 21 | "android": "4", 22 | "ios": "6", 23 | "phantom": "2", 24 | "samsung": "2.1", 25 | "electron": "1.1" 26 | }, 27 | "es6.array.fill": { 28 | "chrome": "45", 29 | "edge": "12", 30 | "firefox": "31", 31 | "safari": "7.1", 32 | "node": "4", 33 | "ios": "8", 34 | "samsung": "5", 35 | "opera": "32", 36 | "electron": "0.35" 37 | }, 38 | "es6.array.filter": { 39 | "chrome": "5", 40 | "opera": "10.10", 41 | "edge": "12", 42 | "firefox": "2", 43 | "safari": "3.1", 44 | "node": "0.10", 45 | "ie": "9", 46 | "android": "4", 47 | "ios": "6", 48 | "phantom": "2", 49 | "samsung": "2.1", 50 | "electron": "1.1" 51 | }, 52 | "es6.array.find": { 53 | "chrome": "45", 54 | "edge": "12", 55 | "firefox": "25", 56 | "safari": "7.1", 57 | "node": "4", 58 | "ios": "8", 59 | "samsung": "5", 60 | "opera": "32", 61 | "electron": "0.35" 62 | }, 63 | "es6.array.find-index": { 64 | "chrome": "45", 65 | "edge": "12", 66 | "firefox": "25", 67 | "safari": "7.1", 68 | "node": "4", 69 | "ios": "8", 70 | "samsung": "5", 71 | "opera": "32", 72 | "electron": "0.35" 73 | }, 74 | "es7.array.flat-map": { 75 | "chrome": "69", 76 | "firefox": "62", 77 | "safari": "12", 78 | "node": "11", 79 | "ios": "12", 80 | "opera": "56", 81 | "electron": "4" 82 | }, 83 | "es6.array.for-each": { 84 | "chrome": "5", 85 | "opera": "10.10", 86 | "edge": "12", 87 | "firefox": "2", 88 | "safari": "3.1", 89 | "node": "0.10", 90 | "ie": "9", 91 | "android": "4", 92 | "ios": "6", 93 | "phantom": "2", 94 | "samsung": "2.1", 95 | "electron": "1.1" 96 | }, 97 | "es6.array.from": { 98 | "chrome": "51", 99 | "edge": "15", 100 | "firefox": "36", 101 | "safari": "10", 102 | "node": "6.5", 103 | "ios": "10", 104 | "samsung": "5", 105 | "opera": "38", 106 | "electron": "1.2" 107 | }, 108 | "es7.array.includes": { 109 | "chrome": "47", 110 | "edge": "14", 111 | "firefox": "43", 112 | "safari": "10", 113 | "node": "6", 114 | "ios": "10", 115 | "samsung": "5", 116 | "opera": "34", 117 | "electron": "0.36" 118 | }, 119 | "es6.array.index-of": { 120 | "chrome": "5", 121 | "opera": "10.10", 122 | "edge": "12", 123 | "firefox": "2", 124 | "safari": "3.1", 125 | "node": "0.10", 126 | "ie": "9", 127 | "android": "4", 128 | "ios": "6", 129 | "phantom": "2", 130 | "samsung": "2.1", 131 | "electron": "1.1" 132 | }, 133 | "es6.array.is-array": { 134 | "chrome": "5", 135 | "opera": "10.50", 136 | "edge": "12", 137 | "firefox": "4", 138 | "safari": "4", 139 | "node": "0.10", 140 | "ie": "9", 141 | "android": "4", 142 | "ios": "6", 143 | "phantom": "2", 144 | "samsung": "2.1", 145 | "electron": "1.1" 146 | }, 147 | "es6.array.iterator": { 148 | "chrome": "38", 149 | "edge": "12", 150 | "firefox": "28", 151 | "safari": "7.1", 152 | "node": "0.12", 153 | "ios": "8", 154 | "samsung": "3", 155 | "opera": "25", 156 | "electron": "0.2" 157 | }, 158 | "es6.array.last-index-of": { 159 | "chrome": "5", 160 | "opera": "10.10", 161 | "edge": "12", 162 | "firefox": "2", 163 | "safari": "3.1", 164 | "node": "0.10", 165 | "ie": "9", 166 | "android": "4", 167 | "ios": "6", 168 | "phantom": "2", 169 | "samsung": "2.1", 170 | "electron": "1.1" 171 | }, 172 | "es6.array.map": { 173 | "chrome": "5", 174 | "opera": "10.10", 175 | "edge": "12", 176 | "firefox": "2", 177 | "safari": "3.1", 178 | "node": "0.10", 179 | "ie": "9", 180 | "android": "4", 181 | "ios": "6", 182 | "phantom": "2", 183 | "samsung": "2.1", 184 | "electron": "1.1" 185 | }, 186 | "es6.array.of": { 187 | "chrome": "45", 188 | "edge": "12", 189 | "firefox": "25", 190 | "safari": "9", 191 | "node": "4", 192 | "ios": "9", 193 | "samsung": "5", 194 | "opera": "32", 195 | "electron": "0.35" 196 | }, 197 | "es6.array.reduce": { 198 | "chrome": "5", 199 | "opera": "10.50", 200 | "edge": "12", 201 | "firefox": "3", 202 | "safari": "4", 203 | "node": "0.10", 204 | "ie": "9", 205 | "android": "4", 206 | "ios": "6", 207 | "phantom": "2", 208 | "samsung": "2.1", 209 | "electron": "1.1" 210 | }, 211 | "es6.array.reduce-right": { 212 | "chrome": "5", 213 | "opera": "10.50", 214 | "edge": "12", 215 | "firefox": "3", 216 | "safari": "4", 217 | "node": "0.10", 218 | "ie": "9", 219 | "android": "4", 220 | "ios": "6", 221 | "phantom": "2", 222 | "samsung": "2.1", 223 | "electron": "1.1" 224 | }, 225 | "es6.array.some": { 226 | "chrome": "5", 227 | "opera": "10.10", 228 | "edge": "12", 229 | "firefox": "2", 230 | "safari": "3.1", 231 | "node": "0.10", 232 | "ie": "9", 233 | "android": "4", 234 | "ios": "6", 235 | "phantom": "2", 236 | "samsung": "2.1", 237 | "electron": "1.1" 238 | }, 239 | "es6.array.sort": { 240 | "chrome": "63", 241 | "opera": "50", 242 | "edge": "12", 243 | "firefox": "5", 244 | "safari": "12", 245 | "node": "10", 246 | "ie": "9", 247 | "ios": "12", 248 | "samsung": "8.2", 249 | "electron": "3.1" 250 | }, 251 | "es6.array.species": { 252 | "chrome": "51", 253 | "edge": "13", 254 | "firefox": "48", 255 | "safari": "10", 256 | "node": "6.5", 257 | "ios": "10", 258 | "samsung": "5", 259 | "opera": "38", 260 | "electron": "1.2" 261 | }, 262 | "es6.date.now": { 263 | "chrome": "5", 264 | "opera": "10.50", 265 | "edge": "12", 266 | "firefox": "2", 267 | "safari": "4", 268 | "node": "0.10", 269 | "ie": "9", 270 | "android": "4", 271 | "ios": "6", 272 | "phantom": "2", 273 | "samsung": "2.1", 274 | "electron": "1.1" 275 | }, 276 | "es6.date.to-iso-string": { 277 | "chrome": "5", 278 | "opera": "10.50", 279 | "edge": "12", 280 | "firefox": "3.5", 281 | "safari": "4", 282 | "node": "0.10", 283 | "ie": "9", 284 | "android": "4", 285 | "ios": "6", 286 | "phantom": "2", 287 | "samsung": "2.1", 288 | "electron": "1.1" 289 | }, 290 | "es6.date.to-json": { 291 | "chrome": "5", 292 | "opera": "12.10", 293 | "edge": "12", 294 | "firefox": "4", 295 | "safari": "10", 296 | "node": "0.10", 297 | "ie": "9", 298 | "android": "4", 299 | "ios": "10", 300 | "samsung": "2.1", 301 | "electron": "1.1" 302 | }, 303 | "es6.date.to-primitive": { 304 | "chrome": "47", 305 | "edge": "15", 306 | "firefox": "44", 307 | "safari": "10", 308 | "node": "6", 309 | "ios": "10", 310 | "samsung": "5", 311 | "opera": "34", 312 | "electron": "0.36" 313 | }, 314 | "es6.date.to-string": { 315 | "chrome": "5", 316 | "opera": "10.50", 317 | "edge": "12", 318 | "firefox": "2", 319 | "safari": "3.1", 320 | "node": "0.10", 321 | "ie": "10", 322 | "android": "4", 323 | "ios": "6", 324 | "phantom": "2", 325 | "samsung": "2.1", 326 | "electron": "1.1" 327 | }, 328 | "es6.xtion.bind": { 329 | "chrome": "7", 330 | "opera": "12", 331 | "edge": "12", 332 | "firefox": "4", 333 | "safari": "5.1", 334 | "node": "0.10", 335 | "ie": "9", 336 | "android": "4", 337 | "ios": "6", 338 | "phantom": "2", 339 | "samsung": "2.1", 340 | "electron": "5" 341 | }, 342 | "es6.function.has-instance": { 343 | "chrome": "51", 344 | "edge": "15", 345 | "firefox": "50", 346 | "safari": "10", 347 | "node": "6.5", 348 | "ios": "10", 349 | "samsung": "5", 350 | "opera": "38", 351 | "electron": "1.2" 352 | }, 353 | "es6.function.name": { 354 | "chrome": "5", 355 | "opera": "10.50", 356 | "edge": "14", 357 | "firefox": "2", 358 | "safari": "4", 359 | "node": "0.10", 360 | "android": "4", 361 | "ios": "6", 362 | "phantom": "2", 363 | "samsung": "2.1", 364 | "electron": "1.1" 365 | }, 366 | "es6.map": { 367 | "chrome": "51", 368 | "edge": "15", 369 | "firefox": "53", 370 | "safari": "10", 371 | "node": "6.5", 372 | "ios": "10", 373 | "samsung": "5", 374 | "opera": "38", 375 | "electron": "1.2" 376 | }, 377 | "es6.math.acosh": { 378 | "chrome": "38", 379 | "edge": "12", 380 | "firefox": "25", 381 | "safari": "7.1", 382 | "node": "0.12", 383 | "ios": "8", 384 | "samsung": "3", 385 | "opera": "25", 386 | "electron": "0.2" 387 | }, 388 | "es6.math.asinh": { 389 | "chrome": "38", 390 | "edge": "12", 391 | "firefox": "25", 392 | "safari": "7.1", 393 | "node": "0.12", 394 | "ios": "8", 395 | "samsung": "3", 396 | "opera": "25", 397 | "electron": "0.2" 398 | }, 399 | "es6.math.atanh": { 400 | "chrome": "38", 401 | "edge": "12", 402 | "firefox": "25", 403 | "safari": "7.1", 404 | "node": "0.12", 405 | "ios": "8", 406 | "samsung": "3", 407 | "opera": "25", 408 | "electron": "0.2" 409 | }, 410 | "es6.math.cbrt": { 411 | "chrome": "38", 412 | "edge": "12", 413 | "firefox": "25", 414 | "safari": "7.1", 415 | "node": "0.12", 416 | "ios": "8", 417 | "samsung": "3", 418 | "opera": "25", 419 | "electron": "0.2" 420 | }, 421 | "es6.math.clz32": { 422 | "chrome": "38", 423 | "edge": "12", 424 | "firefox": "31", 425 | "safari": "9", 426 | "node": "0.12", 427 | "ios": "9", 428 | "samsung": "3", 429 | "opera": "25", 430 | "electron": "0.2" 431 | }, 432 | "es6.math.cosh": { 433 | "chrome": "38", 434 | "edge": "12", 435 | "firefox": "25", 436 | "safari": "7.1", 437 | "node": "0.12", 438 | "ios": "8", 439 | "samsung": "3", 440 | "opera": "25", 441 | "electron": "0.2" 442 | }, 443 | "es6.math.expm1": { 444 | "chrome": "38", 445 | "edge": "12", 446 | "firefox": "25", 447 | "safari": "7.1", 448 | "node": "0.12", 449 | "ios": "8", 450 | "samsung": "3", 451 | "opera": "25", 452 | "electron": "0.2" 453 | }, 454 | "es6.math.fround": { 455 | "chrome": "38", 456 | "edge": "12", 457 | "firefox": "26", 458 | "safari": "7.1", 459 | "node": "0.12", 460 | "ios": "8", 461 | "samsung": "3", 462 | "opera": "25", 463 | "electron": "0.2" 464 | }, 465 | "es6.math.hypot": { 466 | "chrome": "38", 467 | "edge": "12", 468 | "firefox": "27", 469 | "safari": "7.1", 470 | "node": "0.12", 471 | "ios": "8", 472 | "samsung": "3", 473 | "opera": "25", 474 | "electron": "0.2" 475 | }, 476 | "es6.math.imul": { 477 | "chrome": "30", 478 | "edge": "12", 479 | "firefox": "23", 480 | "safari": "7", 481 | "node": "0.12", 482 | "android": "4.4", 483 | "ios": "7", 484 | "samsung": "2.1", 485 | "opera": "17", 486 | "electron": "0.2" 487 | }, 488 | "es6.math.log1p": { 489 | "chrome": "38", 490 | "edge": "12", 491 | "firefox": "25", 492 | "safari": "7.1", 493 | "node": "0.12", 494 | "ios": "8", 495 | "samsung": "3", 496 | "opera": "25", 497 | "electron": "0.2" 498 | }, 499 | "es6.math.log10": { 500 | "chrome": "38", 501 | "edge": "12", 502 | "firefox": "25", 503 | "safari": "7.1", 504 | "node": "0.12", 505 | "ios": "8", 506 | "samsung": "3", 507 | "opera": "25", 508 | "electron": "0.2" 509 | }, 510 | "es6.math.log2": { 511 | "chrome": "38", 512 | "edge": "12", 513 | "firefox": "25", 514 | "safari": "7.1", 515 | "node": "0.12", 516 | "ios": "8", 517 | "samsung": "3", 518 | "opera": "25", 519 | "electron": "0.2" 520 | }, 521 | "es6.math.sign": { 522 | "chrome": "38", 523 | "edge": "12", 524 | "firefox": "25", 525 | "safari": "9", 526 | "node": "0.12", 527 | "ios": "9", 528 | "samsung": "3", 529 | "opera": "25", 530 | "electron": "0.2" 531 | }, 532 | "es6.math.sinh": { 533 | "chrome": "38", 534 | "edge": "12", 535 | "firefox": "25", 536 | "safari": "7.1", 537 | "node": "0.12", 538 | "ios": "8", 539 | "samsung": "3", 540 | "opera": "25", 541 | "electron": "0.2" 542 | }, 543 | "es6.math.tanh": { 544 | "chrome": "38", 545 | "edge": "12", 546 | "firefox": "25", 547 | "safari": "7.1", 548 | "node": "0.12", 549 | "ios": "8", 550 | "samsung": "3", 551 | "opera": "25", 552 | "electron": "0.2" 553 | }, 554 | "es6.math.trunc": { 555 | "chrome": "38", 556 | "edge": "12", 557 | "firefox": "25", 558 | "safari": "7.1", 559 | "node": "0.12", 560 | "ios": "8", 561 | "samsung": "3", 562 | "opera": "25", 563 | "electron": "0.2" 564 | }, 565 | "es6.number.constructor": { 566 | "chrome": "41", 567 | "edge": "12", 568 | "firefox": "36", 569 | "safari": "9", 570 | "node": "4", 571 | "ios": "9", 572 | "samsung": "3.4", 573 | "opera": "28", 574 | "electron": "0.24" 575 | }, 576 | "es6.number.epsilon": { 577 | "chrome": "34", 578 | "edge": "12", 579 | "firefox": "25", 580 | "safari": "9", 581 | "node": "0.12", 582 | "ios": "9", 583 | "samsung": "2.1", 584 | "opera": "21", 585 | "electron": "0.2" 586 | }, 587 | "es6.number.is-finite": { 588 | "chrome": "19", 589 | "edge": "12", 590 | "firefox": "16", 591 | "safari": "9", 592 | "node": "0.12", 593 | "android": "4.1", 594 | "ios": "9", 595 | "samsung": "2.1", 596 | "electron": "0.2" 597 | }, 598 | "es6.number.is-integer": { 599 | "chrome": "34", 600 | "edge": "12", 601 | "firefox": "16", 602 | "safari": "9", 603 | "node": "0.12", 604 | "ios": "9", 605 | "samsung": "2.1", 606 | "opera": "21", 607 | "electron": "0.2" 608 | }, 609 | "es6.number.is-nan": { 610 | "chrome": "19", 611 | "edge": "12", 612 | "firefox": "15", 613 | "safari": "9", 614 | "node": "0.12", 615 | "android": "4.1", 616 | "ios": "9", 617 | "samsung": "2.1", 618 | "electron": "0.2" 619 | }, 620 | "es6.number.is-safe-integer": { 621 | "chrome": "34", 622 | "edge": "12", 623 | "firefox": "32", 624 | "safari": "9", 625 | "node": "0.12", 626 | "ios": "9", 627 | "samsung": "2.1", 628 | "opera": "21", 629 | "electron": "0.2" 630 | }, 631 | "es6.number.max-safe-integer": { 632 | "chrome": "34", 633 | "edge": "12", 634 | "firefox": "31", 635 | "safari": "9", 636 | "node": "0.12", 637 | "ios": "9", 638 | "samsung": "2.1", 639 | "opera": "21", 640 | "electron": "0.2" 641 | }, 642 | "es6.number.min-safe-integer": { 643 | "chrome": "34", 644 | "edge": "12", 645 | "firefox": "31", 646 | "safari": "9", 647 | "node": "0.12", 648 | "ios": "9", 649 | "samsung": "2.1", 650 | "opera": "21", 651 | "electron": "0.2" 652 | }, 653 | "es6.number.parse-float": { 654 | "chrome": "34", 655 | "edge": "12", 656 | "firefox": "25", 657 | "safari": "9", 658 | "node": "0.12", 659 | "ios": "9", 660 | "samsung": "2.1", 661 | "opera": "21", 662 | "electron": "0.2" 663 | }, 664 | "es6.number.parse-int": { 665 | "chrome": "34", 666 | "edge": "12", 667 | "firefox": "25", 668 | "safari": "9", 669 | "node": "0.12", 670 | "ios": "9", 671 | "samsung": "2.1", 672 | "opera": "21", 673 | "electron": "0.2" 674 | }, 675 | "es6.object.assign": { 676 | "chrome": "49", 677 | "edge": "13", 678 | "firefox": "36", 679 | "safari": "10", 680 | "node": "6", 681 | "ios": "10", 682 | "samsung": "5", 683 | "opera": "36", 684 | "electron": "1" 685 | }, 686 | "es6.object.create": { 687 | "chrome": "5", 688 | "opera": "12", 689 | "edge": "12", 690 | "firefox": "4", 691 | "safari": "4", 692 | "node": "0.10", 693 | "ie": "9", 694 | "android": "4", 695 | "ios": "6", 696 | "phantom": "2", 697 | "samsung": "2.1", 698 | "electron": "1.1" 699 | }, 700 | "es7.object.define-getter": { 701 | "chrome": "62", 702 | "edge": "16", 703 | "firefox": "48", 704 | "safari": "9", 705 | "node": "8.10", 706 | "ios": "9", 707 | "samsung": "8.2", 708 | "opera": "49", 709 | "electron": "3.1" 710 | }, 711 | "es7.object.define-setter": { 712 | "chrome": "62", 713 | "edge": "16", 714 | "firefox": "48", 715 | "safari": "9", 716 | "node": "8.10", 717 | "ios": "9", 718 | "samsung": "8.2", 719 | "opera": "49", 720 | "electron": "3.1" 721 | }, 722 | "es6.object.define-property": { 723 | "chrome": "5", 724 | "opera": "12", 725 | "edge": "12", 726 | "firefox": "4", 727 | "safari": "5.1", 728 | "node": "0.10", 729 | "ie": "9", 730 | "android": "4", 731 | "ios": "6", 732 | "phantom": "2", 733 | "samsung": "2.1", 734 | "electron": "1.1" 735 | }, 736 | "es6.object.define-properties": { 737 | "chrome": "5", 738 | "opera": "12", 739 | "edge": "12", 740 | "firefox": "4", 741 | "safari": "4", 742 | "node": "0.10", 743 | "ie": "9", 744 | "android": "4", 745 | "ios": "6", 746 | "phantom": "2", 747 | "samsung": "2.1", 748 | "electron": "1.1" 749 | }, 750 | "es7.object.entries": { 751 | "chrome": "54", 752 | "edge": "14", 753 | "firefox": "47", 754 | "safari": "10.1", 755 | "node": "7", 756 | "ios": "10.3", 757 | "samsung": "6.2", 758 | "opera": "41", 759 | "electron": "1.5" 760 | }, 761 | "es6.object.freeze": { 762 | "chrome": "44", 763 | "edge": "12", 764 | "firefox": "35", 765 | "safari": "9", 766 | "node": "4", 767 | "ios": "9", 768 | "samsung": "4", 769 | "opera": "31", 770 | "electron": "0.31" 771 | }, 772 | "es6.object.get-own-property-descriptor": { 773 | "chrome": "44", 774 | "edge": "12", 775 | "firefox": "35", 776 | "safari": "9", 777 | "node": "4", 778 | "ios": "9", 779 | "samsung": "4", 780 | "opera": "31", 781 | "electron": "0.31" 782 | }, 783 | "es7.object.get-own-property-descriptors": { 784 | "chrome": "54", 785 | "edge": "15", 786 | "firefox": "50", 787 | "safari": "10.1", 788 | "node": "7", 789 | "ios": "10.3", 790 | "samsung": "6.2", 791 | "opera": "41", 792 | "electron": "1.5" 793 | }, 794 | "es6.object.get-own-property-names": { 795 | "chrome": "40", 796 | "edge": "12", 797 | "firefox": "33", 798 | "safari": "9", 799 | "node": "4", 800 | "ios": "9", 801 | "samsung": "3.4", 802 | "opera": "27", 803 | "electron": "0.21" 804 | }, 805 | "es6.object.get-prototype-of": { 806 | "chrome": "44", 807 | "edge": "12", 808 | "firefox": "35", 809 | "safari": "9", 810 | "node": "4", 811 | "ios": "9", 812 | "samsung": "4", 813 | "opera": "31", 814 | "electron": "0.31" 815 | }, 816 | "es7.object.lookup-getter": { 817 | "chrome": "62", 818 | "firefox": "36", 819 | "safari": "9", 820 | "node": "8.10", 821 | "ios": "9", 822 | "samsung": "8.2", 823 | "opera": "49", 824 | "electron": "3.1" 825 | }, 826 | "es7.object.lookup-setter": { 827 | "chrome": "62", 828 | "firefox": "36", 829 | "safari": "9", 830 | "node": "8.10", 831 | "ios": "9", 832 | "samsung": "8.2", 833 | "opera": "49", 834 | "electron": "3.1" 835 | }, 836 | "es6.object.prevent-extensions": { 837 | "chrome": "44", 838 | "edge": "12", 839 | "firefox": "35", 840 | "safari": "9", 841 | "node": "4", 842 | "ios": "9", 843 | "samsung": "4", 844 | "opera": "31", 845 | "electron": "0.31" 846 | }, 847 | "es6.object.to-string": { 848 | "chrome": "57", 849 | "edge": "15", 850 | "firefox": "51", 851 | "safari": "10", 852 | "node": "8", 853 | "ios": "10", 854 | "samsung": "7.2", 855 | "opera": "44", 856 | "electron": "1.7" 857 | }, 858 | "es6.object.is": { 859 | "chrome": "19", 860 | "edge": "12", 861 | "firefox": "22", 862 | "safari": "9", 863 | "node": "0.12", 864 | "android": "4.1", 865 | "ios": "9", 866 | "samsung": "2.1", 867 | "electron": "0.2" 868 | }, 869 | "es6.object.is-frozen": { 870 | "chrome": "44", 871 | "edge": "12", 872 | "firefox": "35", 873 | "safari": "9", 874 | "node": "4", 875 | "ios": "9", 876 | "samsung": "4", 877 | "opera": "31", 878 | "electron": "0.31" 879 | }, 880 | "es6.object.is-sealed": { 881 | "chrome": "44", 882 | "edge": "12", 883 | "firefox": "35", 884 | "safari": "9", 885 | "node": "4", 886 | "ios": "9", 887 | "samsung": "4", 888 | "opera": "31", 889 | "electron": "0.31" 890 | }, 891 | "es6.object.is-extensible": { 892 | "chrome": "44", 893 | "edge": "12", 894 | "firefox": "35", 895 | "safari": "9", 896 | "node": "4", 897 | "ios": "9", 898 | "samsung": "4", 899 | "opera": "31", 900 | "electron": "0.31" 901 | }, 902 | "es6.object.keys": { 903 | "chrome": "40", 904 | "edge": "12", 905 | "firefox": "35", 906 | "safari": "9", 907 | "node": "4", 908 | "ios": "9", 909 | "samsung": "3.4", 910 | "opera": "27", 911 | "electron": "0.21" 912 | }, 913 | "es6.object.seal": { 914 | "chrome": "44", 915 | "edge": "12", 916 | "firefox": "35", 917 | "safari": "9", 918 | "node": "4", 919 | "ios": "9", 920 | "samsung": "4", 921 | "opera": "31", 922 | "electron": "0.31" 923 | }, 924 | "es6.object.set-prototype-of": { 925 | "chrome": "34", 926 | "edge": "12", 927 | "firefox": "31", 928 | "safari": "9", 929 | "node": "0.12", 930 | "ie": "11", 931 | "ios": "9", 932 | "samsung": "2.1", 933 | "opera": "21", 934 | "electron": "0.2" 935 | }, 936 | "es7.object.values": { 937 | "chrome": "54", 938 | "edge": "14", 939 | "firefox": "47", 940 | "safari": "10.1", 941 | "node": "7", 942 | "ios": "10.3", 943 | "samsung": "6.2", 944 | "opera": "41", 945 | "electron": "1.5" 946 | }, 947 | "es6.promise": { 948 | "chrome": "51", 949 | "edge": "14", 950 | "firefox": "45", 951 | "safari": "10", 952 | "node": "6.5", 953 | "ios": "10", 954 | "samsung": "5", 955 | "opera": "38", 956 | "electron": "1.2" 957 | }, 958 | "es7.promise.finally": { 959 | "chrome": "63", 960 | "edge": "18", 961 | "firefox": "58", 962 | "safari": "11.1", 963 | "node": "10", 964 | "ios": "11.3", 965 | "samsung": "8.2", 966 | "opera": "50", 967 | "electron": "3.1" 968 | }, 969 | "es6.reflect.apply": { 970 | "chrome": "49", 971 | "edge": "12", 972 | "firefox": "42", 973 | "safari": "10", 974 | "node": "6", 975 | "ios": "10", 976 | "samsung": "5", 977 | "opera": "36", 978 | "electron": "1" 979 | }, 980 | "es6.reflect.construct": { 981 | "chrome": "49", 982 | "edge": "13", 983 | "firefox": "49", 984 | "safari": "10", 985 | "node": "6", 986 | "ios": "10", 987 | "samsung": "5", 988 | "opera": "36", 989 | "electron": "1" 990 | }, 991 | "es6.reflect.define-property": { 992 | "chrome": "49", 993 | "edge": "13", 994 | "firefox": "42", 995 | "safari": "10", 996 | "node": "6", 997 | "ios": "10", 998 | "samsung": "5", 999 | "opera": "36", 1000 | "electron": "1" 1001 | }, 1002 | "es6.reflect.delete-property": { 1003 | "chrome": "49", 1004 | "edge": "12", 1005 | "firefox": "42", 1006 | "safari": "10", 1007 | "node": "6", 1008 | "ios": "10", 1009 | "samsung": "5", 1010 | "opera": "36", 1011 | "electron": "1" 1012 | }, 1013 | "es6.reflect.get": { 1014 | "chrome": "49", 1015 | "edge": "12", 1016 | "firefox": "42", 1017 | "safari": "10", 1018 | "node": "6", 1019 | "ios": "10", 1020 | "samsung": "5", 1021 | "opera": "36", 1022 | "electron": "1" 1023 | }, 1024 | "es6.reflect.get-own-property-descriptor": { 1025 | "chrome": "49", 1026 | "edge": "12", 1027 | "firefox": "42", 1028 | "safari": "10", 1029 | "node": "6", 1030 | "ios": "10", 1031 | "samsung": "5", 1032 | "opera": "36", 1033 | "electron": "1" 1034 | }, 1035 | "es6.reflect.get-prototype-of": { 1036 | "chrome": "49", 1037 | "edge": "12", 1038 | "firefox": "42", 1039 | "safari": "10", 1040 | "node": "6", 1041 | "ios": "10", 1042 | "samsung": "5", 1043 | "opera": "36", 1044 | "electron": "1" 1045 | }, 1046 | "es6.reflect.has": { 1047 | "chrome": "49", 1048 | "edge": "12", 1049 | "firefox": "42", 1050 | "safari": "10", 1051 | "node": "6", 1052 | "ios": "10", 1053 | "samsung": "5", 1054 | "opera": "36", 1055 | "electron": "1" 1056 | }, 1057 | "es6.reflect.is-extensible": { 1058 | "chrome": "49", 1059 | "edge": "12", 1060 | "firefox": "42", 1061 | "safari": "10", 1062 | "node": "6", 1063 | "ios": "10", 1064 | "samsung": "5", 1065 | "opera": "36", 1066 | "electron": "1" 1067 | }, 1068 | "es6.reflect.own-keys": { 1069 | "chrome": "49", 1070 | "edge": "12", 1071 | "firefox": "42", 1072 | "safari": "10", 1073 | "node": "6", 1074 | "ios": "10", 1075 | "samsung": "5", 1076 | "opera": "36", 1077 | "electron": "1" 1078 | }, 1079 | "es6.reflect.prevent-extensions": { 1080 | "chrome": "49", 1081 | "edge": "12", 1082 | "firefox": "42", 1083 | "safari": "10", 1084 | "node": "6", 1085 | "ios": "10", 1086 | "samsung": "5", 1087 | "opera": "36", 1088 | "electron": "1" 1089 | }, 1090 | "es6.reflect.set": { 1091 | "chrome": "49", 1092 | "edge": "12", 1093 | "firefox": "42", 1094 | "safari": "10", 1095 | "node": "6", 1096 | "ios": "10", 1097 | "samsung": "5", 1098 | "opera": "36", 1099 | "electron": "1" 1100 | }, 1101 | "es6.reflect.set-prototype-of": { 1102 | "chrome": "49", 1103 | "edge": "12", 1104 | "firefox": "42", 1105 | "safari": "10", 1106 | "node": "6", 1107 | "ios": "10", 1108 | "samsung": "5", 1109 | "opera": "36", 1110 | "electron": "1" 1111 | }, 1112 | "es6.regexp.constructor": { 1113 | "chrome": "50", 1114 | "firefox": "40", 1115 | "safari": "10", 1116 | "node": "6", 1117 | "ios": "10", 1118 | "samsung": "5", 1119 | "opera": "37", 1120 | "electron": "1.1" 1121 | }, 1122 | "es6.regexp.flags": { 1123 | "chrome": "49", 1124 | "firefox": "37", 1125 | "safari": "9", 1126 | "node": "6", 1127 | "ios": "9", 1128 | "samsung": "5", 1129 | "opera": "36", 1130 | "electron": "1" 1131 | }, 1132 | "es6.regexp.match": { 1133 | "chrome": "50", 1134 | "firefox": "49", 1135 | "safari": "10", 1136 | "node": "6", 1137 | "ios": "10", 1138 | "samsung": "5", 1139 | "opera": "37", 1140 | "electron": "1.1" 1141 | }, 1142 | "es6.regexp.replace": { 1143 | "chrome": "50", 1144 | "firefox": "49", 1145 | "safari": "10", 1146 | "node": "6", 1147 | "ios": "10", 1148 | "samsung": "5", 1149 | "opera": "37", 1150 | "electron": "1.1" 1151 | }, 1152 | "es6.regexp.split": { 1153 | "chrome": "50", 1154 | "firefox": "49", 1155 | "safari": "10", 1156 | "node": "6", 1157 | "ios": "10", 1158 | "samsung": "5", 1159 | "opera": "37", 1160 | "electron": "1.1" 1161 | }, 1162 | "es6.regexp.search": { 1163 | "chrome": "50", 1164 | "firefox": "49", 1165 | "safari": "10", 1166 | "node": "6", 1167 | "ios": "10", 1168 | "samsung": "5", 1169 | "opera": "37", 1170 | "electron": "1.1" 1171 | }, 1172 | "es6.regexp.to-string": { 1173 | "chrome": "50", 1174 | "firefox": "39", 1175 | "safari": "10", 1176 | "node": "6", 1177 | "ios": "10", 1178 | "samsung": "5", 1179 | "opera": "37", 1180 | "electron": "1.1" 1181 | }, 1182 | "es6.set": { 1183 | "chrome": "51", 1184 | "edge": "15", 1185 | "firefox": "53", 1186 | "safari": "10", 1187 | "node": "6.5", 1188 | "ios": "10", 1189 | "samsung": "5", 1190 | "opera": "38", 1191 | "electron": "1.2" 1192 | }, 1193 | "es6.symbol": { 1194 | "chrome": "51", 1195 | "firefox": "51", 1196 | "safari": "10", 1197 | "node": "6.5", 1198 | "ios": "10", 1199 | "samsung": "5", 1200 | "opera": "38", 1201 | "electron": "1.2" 1202 | }, 1203 | "es7.symbol.async-iterator": { 1204 | "chrome": "63", 1205 | "firefox": "57", 1206 | "safari": "12", 1207 | "node": "10", 1208 | "ios": "12", 1209 | "samsung": "8.2", 1210 | "opera": "50", 1211 | "electron": "3.1" 1212 | }, 1213 | "es6.string.anchor": { 1214 | "chrome": "5", 1215 | "edge": "12", 1216 | "firefox": "17", 1217 | "safari": "6", 1218 | "node": "0.10", 1219 | "android": "4", 1220 | "ios": "7", 1221 | "phantom": "2", 1222 | "samsung": "2.1", 1223 | "electron": "1.1" 1224 | }, 1225 | "es6.string.big": { 1226 | "chrome": "5", 1227 | "edge": "12", 1228 | "firefox": "17", 1229 | "safari": "6", 1230 | "node": "0.10", 1231 | "android": "4", 1232 | "ios": "7", 1233 | "phantom": "2", 1234 | "samsung": "2.1", 1235 | "electron": "1.1" 1236 | }, 1237 | "es6.string.blink": { 1238 | "chrome": "5", 1239 | "edge": "12", 1240 | "firefox": "17", 1241 | "safari": "6", 1242 | "node": "0.10", 1243 | "android": "4", 1244 | "ios": "7", 1245 | "phantom": "2", 1246 | "samsung": "2.1", 1247 | "electron": "1.1" 1248 | }, 1249 | "es6.string.bold": { 1250 | "chrome": "5", 1251 | "edge": "12", 1252 | "firefox": "17", 1253 | "safari": "6", 1254 | "node": "0.10", 1255 | "android": "4", 1256 | "ios": "7", 1257 | "phantom": "2", 1258 | "samsung": "2.1", 1259 | "electron": "1.1" 1260 | }, 1261 | "es6.string.code-point-at": { 1262 | "chrome": "41", 1263 | "edge": "12", 1264 | "firefox": "29", 1265 | "safari": "9", 1266 | "node": "4", 1267 | "ios": "9", 1268 | "samsung": "3.4", 1269 | "opera": "28", 1270 | "electron": "0.24" 1271 | }, 1272 | "es6.string.ends-with": { 1273 | "chrome": "41", 1274 | "edge": "12", 1275 | "firefox": "29", 1276 | "safari": "9", 1277 | "node": "4", 1278 | "ios": "9", 1279 | "samsung": "3.4", 1280 | "opera": "28", 1281 | "electron": "0.24" 1282 | }, 1283 | "es6.string.fixed": { 1284 | "chrome": "5", 1285 | "edge": "12", 1286 | "firefox": "17", 1287 | "safari": "6", 1288 | "node": "0.10", 1289 | "android": "4", 1290 | "ios": "7", 1291 | "phantom": "2", 1292 | "samsung": "2.1", 1293 | "electron": "1.1" 1294 | }, 1295 | "es6.string.fontcolor": { 1296 | "chrome": "5", 1297 | "edge": "12", 1298 | "firefox": "17", 1299 | "safari": "6", 1300 | "node": "0.10", 1301 | "android": "4", 1302 | "ios": "7", 1303 | "phantom": "2", 1304 | "samsung": "2.1", 1305 | "electron": "1.1" 1306 | }, 1307 | "es6.string.fontsize": { 1308 | "chrome": "5", 1309 | "edge": "12", 1310 | "firefox": "17", 1311 | "safari": "6", 1312 | "node": "0.10", 1313 | "android": "4", 1314 | "ios": "7", 1315 | "phantom": "2", 1316 | "samsung": "2.1", 1317 | "electron": "1.1" 1318 | }, 1319 | "es6.string.from-code-point": { 1320 | "chrome": "41", 1321 | "edge": "12", 1322 | "firefox": "29", 1323 | "safari": "9", 1324 | "node": "4", 1325 | "ios": "9", 1326 | "samsung": "3.4", 1327 | "opera": "28", 1328 | "electron": "0.24" 1329 | }, 1330 | "es6.string.includes": { 1331 | "chrome": "41", 1332 | "edge": "12", 1333 | "firefox": "40", 1334 | "safari": "9", 1335 | "node": "4", 1336 | "ios": "9", 1337 | "samsung": "3.4", 1338 | "opera": "28", 1339 | "electron": "0.24" 1340 | }, 1341 | "es6.string.italics": { 1342 | "chrome": "5", 1343 | "edge": "12", 1344 | "firefox": "17", 1345 | "safari": "6", 1346 | "node": "0.10", 1347 | "android": "4", 1348 | "ios": "7", 1349 | "phantom": "2", 1350 | "samsung": "2.1", 1351 | "electron": "1.1" 1352 | }, 1353 | "es6.string.iterator": { 1354 | "chrome": "38", 1355 | "edge": "12", 1356 | "firefox": "36", 1357 | "safari": "9", 1358 | "node": "0.12", 1359 | "ios": "9", 1360 | "samsung": "3", 1361 | "opera": "25", 1362 | "electron": "0.2" 1363 | }, 1364 | "es6.string.link": { 1365 | "chrome": "5", 1366 | "edge": "12", 1367 | "firefox": "17", 1368 | "safari": "6", 1369 | "node": "0.10", 1370 | "android": "4", 1371 | "ios": "7", 1372 | "phantom": "2", 1373 | "samsung": "2.1", 1374 | "electron": "1.1" 1375 | }, 1376 | "es7.string.pad-start": { 1377 | "chrome": "57", 1378 | "edge": "15", 1379 | "firefox": "48", 1380 | "safari": "10", 1381 | "node": "8", 1382 | "ios": "10", 1383 | "samsung": "7.2", 1384 | "opera": "44", 1385 | "electron": "1.7" 1386 | }, 1387 | "es7.string.pad-end": { 1388 | "chrome": "57", 1389 | "edge": "15", 1390 | "firefox": "48", 1391 | "safari": "10", 1392 | "node": "8", 1393 | "ios": "10", 1394 | "samsung": "7.2", 1395 | "opera": "44", 1396 | "electron": "1.7" 1397 | }, 1398 | "es6.string.raw": { 1399 | "chrome": "41", 1400 | "edge": "12", 1401 | "firefox": "34", 1402 | "safari": "9", 1403 | "node": "4", 1404 | "ios": "9", 1405 | "samsung": "3.4", 1406 | "opera": "28", 1407 | "electron": "0.24" 1408 | }, 1409 | "es6.string.repeat": { 1410 | "chrome": "41", 1411 | "edge": "12", 1412 | "firefox": "24", 1413 | "safari": "9", 1414 | "node": "4", 1415 | "ios": "9", 1416 | "samsung": "3.4", 1417 | "opera": "28", 1418 | "electron": "0.24" 1419 | }, 1420 | "es6.string.small": { 1421 | "chrome": "5", 1422 | "edge": "12", 1423 | "firefox": "17", 1424 | "safari": "6", 1425 | "node": "0.10", 1426 | "android": "4", 1427 | "ios": "7", 1428 | "phantom": "2", 1429 | "samsung": "2.1", 1430 | "electron": "1.1" 1431 | }, 1432 | "es6.string.starts-with": { 1433 | "chrome": "41", 1434 | "edge": "12", 1435 | "firefox": "29", 1436 | "safari": "9", 1437 | "node": "4", 1438 | "ios": "9", 1439 | "samsung": "3.4", 1440 | "opera": "28", 1441 | "electron": "0.24" 1442 | }, 1443 | "es6.string.strike": { 1444 | "chrome": "5", 1445 | "edge": "12", 1446 | "firefox": "17", 1447 | "safari": "6", 1448 | "node": "0.10", 1449 | "android": "4", 1450 | "ios": "7", 1451 | "phantom": "2", 1452 | "samsung": "2.1", 1453 | "electron": "1.1" 1454 | }, 1455 | "es6.string.sub": { 1456 | "chrome": "5", 1457 | "edge": "12", 1458 | "firefox": "17", 1459 | "safari": "6", 1460 | "node": "0.10", 1461 | "android": "4", 1462 | "ios": "7", 1463 | "phantom": "2", 1464 | "samsung": "2.1", 1465 | "electron": "1.1" 1466 | }, 1467 | "es6.string.sup": { 1468 | "chrome": "5", 1469 | "edge": "12", 1470 | "firefox": "17", 1471 | "safari": "6", 1472 | "node": "0.10", 1473 | "android": "4", 1474 | "ios": "7", 1475 | "phantom": "2", 1476 | "samsung": "2.1", 1477 | "electron": "1.1" 1478 | }, 1479 | "es6.string.trim": { 1480 | "chrome": "5", 1481 | "opera": "10.50", 1482 | "edge": "12", 1483 | "firefox": "3.5", 1484 | "safari": "4", 1485 | "node": "0.10", 1486 | "ie": "9", 1487 | "android": "4", 1488 | "ios": "6", 1489 | "phantom": "2", 1490 | "samsung": "2.1", 1491 | "electron": "1.1" 1492 | }, 1493 | "es7.string.trim-left": { 1494 | "chrome": "66", 1495 | "firefox": "61", 1496 | "safari": "12", 1497 | "node": "10", 1498 | "ios": "12", 1499 | "opera": "53", 1500 | "electron": "3.1" 1501 | }, 1502 | "es7.string.trim-right": { 1503 | "chrome": "66", 1504 | "firefox": "61", 1505 | "safari": "12", 1506 | "node": "10", 1507 | "ios": "12", 1508 | "opera": "53", 1509 | "electron": "3.1" 1510 | }, 1511 | "es6.typed.array-buffer": { 1512 | "chrome": "51", 1513 | "edge": "13", 1514 | "firefox": "48", 1515 | "safari": "10", 1516 | "node": "6.5", 1517 | "ios": "10", 1518 | "samsung": "5", 1519 | "opera": "38", 1520 | "electron": "1.2" 1521 | }, 1522 | "es6.typed.data-view": { 1523 | "chrome": "5", 1524 | "opera": "12", 1525 | "edge": "12", 1526 | "firefox": "15", 1527 | "safari": "5.1", 1528 | "node": "0.10", 1529 | "ie": "10", 1530 | "android": "4", 1531 | "ios": "6", 1532 | "phantom": "2", 1533 | "samsung": "2.1", 1534 | "electron": "1.1" 1535 | }, 1536 | "es6.typed.int8-array": { 1537 | "chrome": "51", 1538 | "edge": "13", 1539 | "firefox": "48", 1540 | "safari": "10", 1541 | "node": "6.5", 1542 | "ios": "10", 1543 | "samsung": "5", 1544 | "opera": "38", 1545 | "electron": "1.2" 1546 | }, 1547 | "es6.typed.uint8-array": { 1548 | "chrome": "51", 1549 | "edge": "13", 1550 | "firefox": "48", 1551 | "safari": "10", 1552 | "node": "6.5", 1553 | "ios": "10", 1554 | "samsung": "5", 1555 | "opera": "38", 1556 | "electron": "1.2" 1557 | }, 1558 | "es6.typed.uint8-clamped-array": { 1559 | "chrome": "51", 1560 | "edge": "13", 1561 | "firefox": "48", 1562 | "safari": "10", 1563 | "node": "6.5", 1564 | "ios": "10", 1565 | "samsung": "5", 1566 | "opera": "38", 1567 | "electron": "1.2" 1568 | }, 1569 | "es6.typed.int16-array": { 1570 | "chrome": "51", 1571 | "edge": "13", 1572 | "firefox": "48", 1573 | "safari": "10", 1574 | "node": "6.5", 1575 | "ios": "10", 1576 | "samsung": "5", 1577 | "opera": "38", 1578 | "electron": "1.2" 1579 | }, 1580 | "es6.typed.uint16-array": { 1581 | "chrome": "51", 1582 | "edge": "13", 1583 | "firefox": "48", 1584 | "safari": "10", 1585 | "node": "6.5", 1586 | "ios": "10", 1587 | "samsung": "5", 1588 | "opera": "38", 1589 | "electron": "1.2" 1590 | }, 1591 | "es6.typed.int32-array": { 1592 | "chrome": "51", 1593 | "edge": "13", 1594 | "firefox": "48", 1595 | "safari": "10", 1596 | "node": "6.5", 1597 | "ios": "10", 1598 | "samsung": "5", 1599 | "opera": "38", 1600 | "electron": "1.2" 1601 | }, 1602 | "es6.typed.uint32-array": { 1603 | "chrome": "51", 1604 | "edge": "13", 1605 | "firefox": "48", 1606 | "safari": "10", 1607 | "node": "6.5", 1608 | "ios": "10", 1609 | "samsung": "5", 1610 | "opera": "38", 1611 | "electron": "1.2" 1612 | }, 1613 | "es6.typed.float32-array": { 1614 | "chrome": "51", 1615 | "edge": "13", 1616 | "firefox": "48", 1617 | "safari": "10", 1618 | "node": "6.5", 1619 | "ios": "10", 1620 | "samsung": "5", 1621 | "opera": "38", 1622 | "electron": "1.2" 1623 | }, 1624 | "es6.typed.float64-array": { 1625 | "chrome": "51", 1626 | "edge": "13", 1627 | "firefox": "48", 1628 | "safari": "10", 1629 | "node": "6.5", 1630 | "ios": "10", 1631 | "samsung": "5", 1632 | "opera": "38", 1633 | "electron": "1.2" 1634 | }, 1635 | "es6.weak-map": { 1636 | "chrome": "51", 1637 | "edge": "15", 1638 | "firefox": "53", 1639 | "safari": "9", 1640 | "node": "6.5", 1641 | "ios": "9", 1642 | "samsung": "5", 1643 | "opera": "38", 1644 | "electron": "1.2" 1645 | }, 1646 | "es6.weak-set": { 1647 | "chrome": "51", 1648 | "edge": "15", 1649 | "firefox": "53", 1650 | "safari": "9", 1651 | "node": "6.5", 1652 | "ios": "9", 1653 | "samsung": "5", 1654 | "opera": "38", 1655 | "electron": "1.2" 1656 | } 1657 | } 1658 | -------------------------------------------------------------------------------- /src/data/corejs2/index.js: -------------------------------------------------------------------------------- 1 | import * as definitions from './built-in-definitions'; 2 | import builtIns from './built-ins'; 3 | 4 | export default { 5 | definitions, 6 | builtIns 7 | } -------------------------------------------------------------------------------- /src/data/corejs3/built-in-definitions.js: -------------------------------------------------------------------------------- 1 | const ArrayNatureIterators = [ 2 | "es.array.iterator", 3 | "web.dom-collections.iterator", 4 | ]; 5 | 6 | export const CommonIterators = ["es.string.iterator", ...ArrayNatureIterators]; 7 | 8 | const ArrayNatureIteratorsWithTag = [ 9 | "es.object.to-string", 10 | ...ArrayNatureIterators, 11 | ]; 12 | 13 | const CommonIteratorsWithTag = ["es.object.to-string", ...CommonIterators]; 14 | 15 | const TypedArrayDependencies = [ 16 | "es.typed-array.copy-within", 17 | "es.typed-array.every", 18 | "es.typed-array.fill", 19 | "es.typed-array.filter", 20 | "es.typed-array.find", 21 | "es.typed-array.find-index", 22 | "es.typed-array.for-each", 23 | "es.typed-array.includes", 24 | "es.typed-array.index-of", 25 | "es.typed-array.iterator", 26 | "es.typed-array.join", 27 | "es.typed-array.last-index-of", 28 | "es.typed-array.map", 29 | "es.typed-array.reduce", 30 | "es.typed-array.reduce-right", 31 | "es.typed-array.reverse", 32 | "es.typed-array.set", 33 | "es.typed-array.slice", 34 | "es.typed-array.some", 35 | "es.typed-array.sort", 36 | "es.typed-array.subarray", 37 | "es.typed-array.to-locale-string", 38 | "es.typed-array.to-string", 39 | "es.object.to-string", 40 | "es.array.iterator", 41 | "es.array-buffer.slice", 42 | ]; 43 | 44 | const TypedArrayStaticMethods = { 45 | from: "es.typed-array.from", 46 | of: "es.typed-array.of", 47 | }; 48 | 49 | export const PromiseDependencies = ["es.promise", "es.object.to-string"]; 50 | 51 | const PromiseDependenciesWithIterators = [ 52 | ...PromiseDependencies, 53 | ...CommonIterators, 54 | ]; 55 | 56 | const SymbolDependencies = [ 57 | "es.symbol", 58 | "es.symbol.description", 59 | "es.object.to-string", 60 | ]; 61 | 62 | const MapDependencies = [ 63 | "es.map", 64 | "esnext.map.delete-all", 65 | "esnext.map.every", 66 | "esnext.map.filter", 67 | "esnext.map.find", 68 | "esnext.map.find-key", 69 | "esnext.map.includes", 70 | "esnext.map.key-of", 71 | "esnext.map.map-keys", 72 | "esnext.map.map-values", 73 | "esnext.map.merge", 74 | "esnext.map.reduce", 75 | "esnext.map.some", 76 | "esnext.map.update", 77 | ...CommonIteratorsWithTag, 78 | ]; 79 | 80 | const SetDependencies = [ 81 | "es.set", 82 | "esnext.set.add-all", 83 | "esnext.set.delete-all", 84 | "esnext.set.difference", 85 | "esnext.set.every", 86 | "esnext.set.filter", 87 | "esnext.set.find", 88 | "esnext.set.intersection", 89 | "esnext.set.is-disjoint-from", 90 | "esnext.set.is-subset-of", 91 | "esnext.set.is-superset-of", 92 | "esnext.set.join", 93 | "esnext.set.map", 94 | "esnext.set.reduce", 95 | "esnext.set.some", 96 | "esnext.set.symmetric-difference", 97 | "esnext.set.union", 98 | ...CommonIteratorsWithTag, 99 | ]; 100 | 101 | const WeakMapDependencies = [ 102 | "es.weak-map", 103 | "esnext.weak-map.delete-all", 104 | ...CommonIteratorsWithTag, 105 | ]; 106 | 107 | const WeakSetDependencies = [ 108 | "es.weak-set", 109 | "esnext.weak-set.add-all", 110 | "esnext.weak-set.delete-all", 111 | ...CommonIteratorsWithTag, 112 | ]; 113 | 114 | const URLSearchParamsDependencies = ["web.url", ...CommonIteratorsWithTag]; 115 | 116 | export const BuiltIns= { 117 | AggregateError: ["esnext.aggregate-error", ...CommonIterators], 118 | ArrayBuffer: [ 119 | "es.array-buffer.constructor", 120 | "es.array-buffer.slice", 121 | "es.object.to-string", 122 | ], 123 | DataView: ["es.data-view", "es.array-buffer.slice", "es.object.to-string"], 124 | Date: ["es.date.to-string"], 125 | Float32Array: ["es.typed-array.float32-array", ...TypedArrayDependencies], 126 | Float64Array: ["es.typed-array.float64-array", ...TypedArrayDependencies], 127 | Int8Array: ["es.typed-array.int8-array", ...TypedArrayDependencies], 128 | Int16Array: ["es.typed-array.int16-array", ...TypedArrayDependencies], 129 | Int32Array: ["es.typed-array.int32-array", ...TypedArrayDependencies], 130 | Uint8Array: ["es.typed-array.uint8-array", ...TypedArrayDependencies], 131 | Uint8ClampedArray: [ 132 | "es.typed-array.uint8-clamped-array", 133 | ...TypedArrayDependencies, 134 | ], 135 | Uint16Array: ["es.typed-array.uint16-array", ...TypedArrayDependencies], 136 | Uint32Array: ["es.typed-array.uint32-array", ...TypedArrayDependencies], 137 | Map: MapDependencies, 138 | Number: ["es.number.constructor"], 139 | Observable: [ 140 | "esnext.observable", 141 | "esnext.symbol.observable", 142 | "es.object.to-string", 143 | ...CommonIteratorsWithTag, 144 | ], 145 | Promise: PromiseDependencies, 146 | RegExp: ["es.regexp.constructor", "es.regexp.exec", "es.regexp.to-string"], 147 | Set: SetDependencies, 148 | Symbol: SymbolDependencies, 149 | URL: ["web.url", ...URLSearchParamsDependencies], 150 | URLSearchParams: URLSearchParamsDependencies, 151 | WeakMap: WeakMapDependencies, 152 | WeakSet: WeakSetDependencies, 153 | clearImmediate: ["web.immediate"], 154 | compositeKey: ["esnext.composite-key"], 155 | compositeSymbol: ["esnext.composite-symbol", ...SymbolDependencies], 156 | fetch: PromiseDependencies, 157 | globalThis: ["esnext.global-this"], 158 | parseFloat: ["es.parse-float"], 159 | parseInt: ["es.parse-int"], 160 | queueMicrotask: ["web.queue-microtask"], 161 | setTimeout: ["web.timers"], 162 | setInterval: ["web.timers"], 163 | setImmediate: ["web.immediate"], 164 | }; 165 | 166 | export const InstanceProperties = { 167 | at: ["esnext.string.at"], 168 | anchor: ["es.string.anchor"], 169 | big: ["es.string.big"], 170 | bind: ["es.function.bind"], 171 | blink: ["es.string.blink"], 172 | bold: ["es.string.bold"], 173 | codePointAt: ["es.string.code-point-at"], 174 | codePoints: ["esnext.string.code-points"], 175 | concat: ["es.array.concat"], 176 | copyWithin: ["es.array.copy-within"], 177 | description: ["es.symbol", "es.symbol.description"], 178 | endsWith: ["es.string.ends-with"], 179 | entries: ArrayNatureIteratorsWithTag, 180 | every: ["es.array.every"], 181 | exec: ["es.regexp.exec"], 182 | fill: ["es.array.fill"], 183 | filter: ["es.array.filter"], 184 | finally: ["es.promise.finally", ...PromiseDependencies], 185 | find: ["es.array.find"], 186 | findIndex: ["es.array.find-index"], 187 | fixed: ["es.string.fixed"], 188 | flags: ["es.regexp.flags"], 189 | flat: ["es.array.flat", "es.array.unscopables.flat"], 190 | flatMap: ["es.array.flat-map", "es.array.unscopables.flat-map"], 191 | fontcolor: ["es.string.fontcolor"], 192 | fontsize: ["es.string.fontsize"], 193 | forEach: ["es.array.for-each", "web.dom-collections.for-each"], 194 | includes: ["es.array.includes", "es.string.includes"], 195 | indexOf: ["es.array.index-of"], 196 | italics: ["es.string.italics"], 197 | join: ["es.array.join"], 198 | keys: ArrayNatureIteratorsWithTag, 199 | lastIndex: ["esnext.array.last-index"], 200 | lastIndexOf: ["es.array.last-index-of"], 201 | lastItem: ["esnext.array.last-item"], 202 | link: ["es.string.link"], 203 | match: ["es.string.match", "es.regexp.exec"], 204 | matchAll: ["esnext.string.match-all"], 205 | map: ["es.array.map"], 206 | name: ["es.function.name"], 207 | padEnd: ["es.string.pad-end"], 208 | padStart: ["es.string.pad-start"], 209 | reduce: ["es.array.reduce"], 210 | reduceRight: ["es.array.reduce-right"], 211 | repeat: ["es.string.repeat"], 212 | replace: ["es.string.replace", "es.regexp.exec"], 213 | replaceAll: ["esnext.string.replace-all"], 214 | reverse: ["es.array.reverse"], 215 | search: ["es.string.search", "es.regexp.exec"], 216 | slice: ["es.array.slice"], 217 | small: ["es.string.small"], 218 | some: ["es.array.some"], 219 | sort: ["es.array.sort"], 220 | splice: ["es.array.splice"], 221 | split: ["es.string.split", "es.regexp.exec"], 222 | startsWith: ["es.string.starts-with"], 223 | strike: ["es.string.strike"], 224 | sub: ["es.string.sub"], 225 | sup: ["es.string.sup"], 226 | toFixed: ["es.number.to-fixed"], 227 | toISOString: ["es.date.to-iso-string"], 228 | toJSON: ["es.date.to-json", "web.url.to-json"], 229 | toPrecision: ["es.number.to-precision"], 230 | toString: ["es.object.to-string", "es.regexp.to-string", "es.date.to-string"], 231 | trim: ["es.string.trim"], 232 | trimEnd: ["es.string.trim-end"], 233 | trimLeft: ["es.string.trim-start"], 234 | trimRight: ["es.string.trim-end"], 235 | trimStart: ["es.string.trim-start"], 236 | values: ArrayNatureIteratorsWithTag, 237 | __defineGetter__: ["es.object.define-getter"], 238 | __defineSetter__: ["es.object.define-setter"], 239 | __lookupGetter__: ["es.object.lookup-getter"], 240 | __lookupSetter__: ["es.object.lookup-setter"], 241 | }; 242 | 243 | export const StaticProperties = { 244 | Array: { 245 | from: ["es.array.from", "es.string.iterator"], 246 | isArray: ["es.array.is-array"], 247 | of: ["es.array.of"], 248 | }, 249 | 250 | Date: { 251 | now: "es.date.now", 252 | }, 253 | 254 | Object: { 255 | assign: "es.object.assign", 256 | create: "es.object.create", 257 | defineProperty: "es.object.define-property", 258 | defineProperties: "es.object.define-properties", 259 | entries: "es.object.entries", 260 | freeze: "es.object.freeze", 261 | fromEntries: ["es.object.from-entries", "es.array.iterator"], 262 | getOwnPropertyDescriptor: "es.object.get-own-property-descriptor", 263 | getOwnPropertyDescriptors: "es.object.get-own-property-descriptors", 264 | getOwnPropertyNames: "es.object.get-own-property-names", 265 | getOwnPropertySymbols: "es.symbol", 266 | getPrototypeOf: "es.object.get-prototype-of", 267 | is: "es.object.is", 268 | isExtensible: "es.object.is-extensible", 269 | isFrozen: "es.object.is-frozen", 270 | isSealed: "es.object.is-sealed", 271 | keys: "es.object.keys", 272 | preventExtensions: "es.object.prevent-extensions", 273 | seal: "es.object.seal", 274 | setPrototypeOf: "es.object.set-prototype-of", 275 | values: "es.object.values", 276 | }, 277 | 278 | Math: { 279 | DEG_PER_RAD: "esnext.math.deg-per-rad", 280 | RAD_PER_DEG: "esnext.math.rad-per-deg", 281 | acosh: "es.math.acosh", 282 | asinh: "es.math.asinh", 283 | atanh: "es.math.atanh", 284 | cbrt: "es.math.cbrt", 285 | clamp: "esnext.math.clamp", 286 | clz32: "es.math.clz32", 287 | cosh: "es.math.cosh", 288 | degrees: "esnext.math.degrees", 289 | expm1: "es.math.expm1", 290 | fround: "es.math.fround", 291 | fscale: "esnext.math.fscale", 292 | hypot: "es.math.hypot", 293 | iaddh: "esnext.math.iaddh", 294 | imul: "es.math.imul", 295 | imulh: "esnext.math.imulh", 296 | isubh: "esnext.math.isubh", 297 | log1p: "es.math.log1p", 298 | log10: "es.math.log10", 299 | log2: "es.math.log2", 300 | radians: "esnext.math.radians", 301 | scale: "esnext.math.scale", 302 | seededPRNG: "esnext.math.seeded-prng", 303 | sign: "es.math.sign", 304 | signbit: "esnext.math.signbit", 305 | sinh: "es.math.sinh", 306 | tanh: "es.math.tanh", 307 | trunc: "es.math.trunc", 308 | umulh: "esnext.math.umulh", 309 | }, 310 | 311 | String: { 312 | fromCodePoint: "es.string.from-code-point", 313 | raw: "es.string.raw", 314 | }, 315 | 316 | Number: { 317 | EPSILON: "es.number.epsilon", 318 | MIN_SAFE_INTEGER: "es.number.min-safe-integer", 319 | MAX_SAFE_INTEGER: "es.number.max-safe-integer", 320 | fromString: "esnext.number.from-string", 321 | isFinite: "es.number.is-finite", 322 | isInteger: "es.number.is-integer", 323 | isSafeInteger: "es.number.is-safe-integer", 324 | isNaN: "es.number.is-nan", 325 | parseFloat: "es.number.parse-float", 326 | parseInt: "es.number.parse-int", 327 | }, 328 | 329 | Map: { 330 | from: ["esnext.map.from", ...MapDependencies], 331 | groupBy: ["esnext.map.group-by", ...MapDependencies], 332 | keyBy: ["esnext.map.key-by", ...MapDependencies], 333 | of: ["esnext.map.of", ...MapDependencies], 334 | }, 335 | 336 | Set: { 337 | from: ["esnext.set.from", ...SetDependencies], 338 | of: ["esnext.set.of", ...SetDependencies], 339 | }, 340 | 341 | WeakMap: { 342 | from: ["esnext.weak-map.from", ...WeakMapDependencies], 343 | of: ["esnext.weak-map.of", ...WeakMapDependencies], 344 | }, 345 | 346 | WeakSet: { 347 | from: ["esnext.weak-set.from", ...WeakSetDependencies], 348 | of: ["esnext.weak-set.of", ...WeakSetDependencies], 349 | }, 350 | 351 | Promise: { 352 | all: PromiseDependenciesWithIterators, 353 | allSettled: [ 354 | "esnext.promise.all-settled", 355 | ...PromiseDependenciesWithIterators, 356 | ], 357 | any: ["esnext.promise.any", ...PromiseDependenciesWithIterators], 358 | race: PromiseDependenciesWithIterators, 359 | try: ["esnext.promise.try", ...PromiseDependenciesWithIterators], 360 | }, 361 | 362 | Reflect: { 363 | apply: "es.reflect.apply", 364 | construct: "es.reflect.construct", 365 | defineMetadata: "esnext.reflect.define-metadata", 366 | defineProperty: "es.reflect.define-property", 367 | deleteMetadata: "esnext.reflect.delete-metadata", 368 | deleteProperty: "es.reflect.delete-property", 369 | get: "es.reflect.get", 370 | getMetadata: "esnext.reflect.get-metadata", 371 | getMetadataKeys: "esnext.reflect.get-metadata-keys", 372 | getOwnMetadata: "esnext.reflect.get-own-metadata", 373 | getOwnMetadataKeys: "esnext.reflect.get-own-metadata-keys", 374 | getOwnPropertyDescriptor: "es.reflect.get-own-property-descriptor", 375 | getPrototypeOf: "es.reflect.get-prototype-of", 376 | has: "es.reflect.has", 377 | hasMetadata: "esnext.reflect.has-metadata", 378 | hasOwnMetadata: "esnext.reflect.has-own-metadata", 379 | isExtensible: "es.reflect.is-extensible", 380 | metadata: "esnext.reflect.metadata", 381 | ownKeys: "es.reflect.own-keys", 382 | preventExtensions: "es.reflect.prevent-extensions", 383 | set: "es.reflect.set", 384 | setPrototypeOf: "es.reflect.set-prototype-of", 385 | }, 386 | 387 | Symbol: { 388 | asyncIterator: ["es.symbol.async-iterator"], 389 | dispose: ["esnext.symbol.dispose"], 390 | hasInstance: ["es.symbol.has-instance", "es.function.has-instance"], 391 | isConcatSpreadable: ["es.symbol.is-concat-spreadable", "es.array.concat"], 392 | iterator: ["es.symbol.iterator", ...CommonIteratorsWithTag], 393 | match: ["es.symbol.match", "es.string.match"], 394 | observable: ["esnext.symbol.observable"], 395 | patternMatch: ["esnext.symbol.pattern-match"], 396 | replace: ["es.symbol.replace", "es.string.replace"], 397 | search: ["es.symbol.search", "es.string.search"], 398 | species: ["es.symbol.species", "es.array.species"], 399 | split: ["es.symbol.split", "es.string.split"], 400 | toPrimitive: ["es.symbol.to-primitive", "es.date.to-primitive"], 401 | toStringTag: [ 402 | "es.symbol.to-string-tag", 403 | "es.object.to-string", 404 | "es.math.to-string-tag", 405 | "es.json.to-string-tag", 406 | ], 407 | unscopables: ["es.symbol.unscopables"], 408 | }, 409 | 410 | ArrayBuffer: { 411 | isView: ["es.array-buffer.is-view"], 412 | }, 413 | 414 | Int8Array: TypedArrayStaticMethods, 415 | Uint8Array: TypedArrayStaticMethods, 416 | Uint8ClampedArray: TypedArrayStaticMethods, 417 | Int16Array: TypedArrayStaticMethods, 418 | Uint16Array: TypedArrayStaticMethods, 419 | Int32Array: TypedArrayStaticMethods, 420 | Uint32Array: TypedArrayStaticMethods, 421 | Float32Array: TypedArrayStaticMethods, 422 | Float64Array: TypedArrayStaticMethods, 423 | }; 424 | 425 | export const CommonInstanceDependencies = [ 426 | "es.object.to-string", 427 | "es.object.define-getter", 428 | "es.object.define-setter", 429 | "es.object.lookup-getter", 430 | "es.object.lookup-setter", 431 | "es.regexp.exec", 432 | ]; 433 | 434 | export const PossibleGlobalObjects = [ 435 | "global", 436 | "globalThis", 437 | "self", 438 | "window", 439 | ] -------------------------------------------------------------------------------- /src/data/corejs3/built-ins.js: -------------------------------------------------------------------------------- 1 | import data from 'core-js-compat/data'; 2 | 3 | export default data; -------------------------------------------------------------------------------- /src/data/corejs3/index.js: -------------------------------------------------------------------------------- 1 | import * as definitions from './built-in-definitions'; 2 | import builtIns from './built-ins'; 3 | 4 | export default { 5 | definitions, 6 | builtIns 7 | } -------------------------------------------------------------------------------- /src/data/esmBaseline.js: -------------------------------------------------------------------------------- 1 | export const esmBaseline = { 2 | "edge": "16", 3 | "firefox": "60", 4 | "chrome": "61", 5 | "safari": "10.1", 6 | }; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import util from 'util'; 3 | import path from 'path'; 4 | import child_process from 'child_process'; 5 | import Worker from 'jest-worker'; 6 | import chalk from 'chalk'; 7 | import {table, createStream} from 'table'; 8 | 9 | import corejs2 from './data/corejs2'; 10 | import corejs3 from './data/corejs3'; 11 | 12 | const corejsVersions = { 13 | 2: corejs2, 14 | 3: corejs3, 15 | }; 16 | 17 | import {getRC} from "./rc"; 18 | import {esmBaseline} from "./data/esmBaseline"; 19 | import {inTime, fileSize, isBelow, getSize} from "./utils"; 20 | 21 | export const scan = async (dist, out, _options = getRC()) => { 22 | console.log(chalk.bold.underline.green("devolution"), "🦎 -> 🦖"); 23 | 24 | const options = await _options; 25 | 26 | const corejsVersion = +(options.corejs || 2); 27 | const corejs = corejsVersions[corejsVersion]; 28 | 29 | if (!corejs) { 30 | throw new Error('invalid core-js version:' + corejsVersion); 31 | } 32 | 33 | if (options.useSWC) { 34 | try { 35 | require("@swc/core"); 36 | } catch (e) { 37 | throw new Error('to use SWC please install `@swc/core`'); 38 | } 39 | } 40 | 41 | const {builtIns, definitions} = corejs; 42 | 43 | const {targets, proposals, addPolyfills} = options; 44 | 45 | const mainBundleReg = new RegExp(options.rootBundles); 46 | const dontPolyfill = (options.dontPolyfill || []).map(x => new RegExp(x)); 47 | 48 | const firstTarget = targets[Object.keys(targets)[0]]; 49 | 50 | // find all required files 51 | 52 | const allFiles = Array.isArray(options.files) ? options.files : await util.promisify(fs.readdir)(dist); 53 | const jsFiles = allFiles.filter(file => file.match(options.match)); 54 | 55 | if (!jsFiles.length) { 56 | console.log(chalk.bold.underline.ref("no files to process")); 57 | return false; 58 | } 59 | 60 | const otherFiles = allFiles.filter(file => ( 61 | !jsFiles.includes(file) && 62 | !fs.lstatSync(path.join(dist, file)).isDirectory() 63 | )); 64 | 65 | const mainBundle = jsFiles.find(name => name === mainBundleReg || name.match(mainBundleReg)); 66 | 67 | // prepare polyfill target 68 | 69 | const polyfills = {}; 70 | let basePolyfills = []; 71 | const polyCache = {}; 72 | 73 | const devolutionRoot = path.resolve(path.join(out, '.devolution')); 74 | const polyfillDir = path.resolve(path.join(devolutionRoot, '.polyfills')); 75 | const outDir = path.resolve(out); 76 | 77 | if (!fs.existsSync(out)) { 78 | fs.mkdirSync(out); 79 | } 80 | 81 | if (!fs.existsSync(devolutionRoot)) { 82 | fs.mkdirSync(devolutionRoot); 83 | } 84 | 85 | if (!fs.existsSync(polyfillDir)) { 86 | fs.mkdirSync(polyfillDir); 87 | } 88 | 89 | console.log({ 90 | dist, 91 | out, 92 | mainBundle, 93 | bundledPolyfills: options.includesPolyfills, 94 | 'core-js': corejsVersion, 95 | proposals 96 | }); 97 | 98 | const processPolyfills = (fills) => ( 99 | proposals 100 | ? fills 101 | : fills.filter(name => !name.startsWith('esnext.')) 102 | ); 103 | 104 | console.log(" -> 🦎 -> ", chalk.bold.underline.green("scanning files")); 105 | console.group(); 106 | await inTime(async () => { 107 | 108 | const tableStream = createStream({ 109 | columnDefault: { 110 | width: 50 111 | }, 112 | columns: { 113 | 0: { 114 | width: 70, 115 | }, 116 | 1: { 117 | alignment: 'right' 118 | } 119 | }, 120 | columnCount: 2 121 | }); 122 | tableStream.write(['file', 'polyfills required']); 123 | 124 | const worker = new Worker(require.resolve('./workers/detect')); 125 | const polyfillsLeft = x => basePolyfills.indexOf(x) < 0; 126 | 127 | if (mainBundle && mainBundle !== '.') { 128 | basePolyfills = polyfills[mainBundle] = processPolyfills( 129 | await worker.extractPolyfills(dist, mainBundle, options.babelScan, definitions) 130 | ); 131 | tableStream.write([mainBundle, basePolyfills.length]); 132 | } 133 | 134 | if (addPolyfills && !mainBundle) { 135 | throw new Error("devolution: in order to use `addPolyfills` define `rootBundles` condition.") 136 | } 137 | 138 | await Promise.all( 139 | jsFiles.map(async file => { 140 | if (file !== mainBundle) { 141 | polyfills[file] = processPolyfills( 142 | await worker.extractPolyfills(dist, file, options.babelScan, definitions) 143 | ).filter(polyfillsLeft); 144 | tableStream.write([file, polyfills[file].length]); 145 | } 146 | }) 147 | ); 148 | worker.end(); 149 | }); 150 | console.groupEnd(); 151 | 152 | const targetPolyfills = {}; 153 | console.log(" -> 🦎 -> 🥚", chalk.bold.underline.green("composing polyfills")); 154 | console.group(); 155 | 156 | await inTime(async () => { 157 | const worker = new Worker(require.resolve('./workers/composePolyfill')); 158 | 159 | const tableStream = createStream({ 160 | columnDefault: { 161 | width: 50 162 | }, 163 | columns: { 164 | 0: { 165 | width: 6 166 | }, 167 | 1: { 168 | width: 40 169 | }, 170 | 2: { 171 | width: 15, 172 | wrapWord: true, 173 | alignment: 'right' 174 | }, 175 | 3: { 176 | width: 6, 177 | alignment: 'right' 178 | }, 179 | 4: { 180 | width: 50, 181 | wrapWord: true, 182 | } 183 | }, 184 | columnCount: 6 185 | }); 186 | tableStream.write(['target', 'file', 'missing polyfills', 'size', 'names', 'extra']); 187 | 188 | const usedInMain = new Set(); 189 | 190 | const writePromises = []; 191 | Object 192 | .keys(targets) 193 | .forEach(target => { 194 | targetPolyfills[target] = []; 195 | Object 196 | .keys(polyfills) 197 | .forEach(key => { 198 | let extraCode = ''; 199 | 200 | const localPolyfills = polyfills[key] 201 | .filter( 202 | rule => ( 203 | // would not be included in a base image 204 | (rule==='@regenerator' || !(options.includesPolyfills && isBelow(rule, builtIns[rule], firstTarget))) && 205 | // and not used in the main bundle 206 | (!usedInMain.has(rule) || key===mainBundle) && 207 | // not ignored in config 208 | !options.ignorePolyfills.includes(rule) 209 | ) 210 | ); 211 | 212 | if (key === mainBundle) { 213 | if(addPolyfills) { 214 | localPolyfills.push(...(addPolyfills[target] || [])); 215 | } 216 | localPolyfills.forEach(name => usedInMain.add(name)); 217 | } 218 | 219 | // uses regenerator 220 | if (localPolyfills.includes('@regenerator')) { 221 | if (isBelow('regenerator', esmBaseline, targets[target])) { 222 | extraCode += "import 'regenerator-runtime';" 223 | } 224 | } 225 | 226 | const list = localPolyfills 227 | .filter(rule => ( 228 | // and required for the target 229 | isBelow(rule, builtIns[rule], targets[target]) 230 | ) 231 | ); 232 | 233 | list.forEach(p => { 234 | if (!targetPolyfills[target].includes(p)) { 235 | targetPolyfills[target].push(p) 236 | } 237 | }); 238 | 239 | const chunkPolyfills = list.map(x => `import 'core-js/modules/${x}'`); 240 | 241 | const fileIn = path.join(polyfillDir, `${target}-${key}.mjs`); 242 | fs.writeFileSync(fileIn, extraCode + chunkPolyfills.join('\n')); 243 | 244 | writePromises.push((async () => { 245 | let composedResult = polyCache[`${target}-${key}`] = ''; 246 | if (!dontPolyfill.some(mask => key.match(mask))) { 247 | if (fileSize(fileIn) > 0) { 248 | composedResult = await worker.composePolyfill(fileIn); 249 | const {error} = composedResult; 250 | if (error) { 251 | console.log(''); 252 | console.error(`failed to compose polyfill from ${fileIn}. Error: ${error}`); 253 | throw new Error(error); 254 | } 255 | polyCache[`${target}-${key}`] = composedResult; 256 | } 257 | } 258 | 259 | tableStream.write([target, key, list.length ? list.length : '-', composedResult.length,list, extraCode]); 260 | })()); 261 | }); 262 | }); 263 | 264 | await Promise.all(writePromises); 265 | worker.end(); 266 | }); 267 | console.groupEnd(); 268 | 269 | console.log(" -> 🦎 -> 🦖", chalk.bold.underline.green("devoluting targets...")); 270 | console.group(); 271 | await inTime(async () => { 272 | const worker = new Worker(require.resolve('./workers/transpile')); 273 | 274 | const writePromises = []; 275 | const tableStream = createStream({ 276 | columnDefault: { 277 | width: 50 278 | }, 279 | columns: { 280 | 0: { 281 | width: 6, 282 | }, 283 | 1: { 284 | width: 70, 285 | }, 286 | 2: { 287 | width: 10, 288 | alignment: 'right' 289 | }, 290 | 4: { 291 | width: 10 292 | } 293 | }, 294 | columnCount: 4 295 | }); 296 | tableStream.write(['target', 'file', 'time, ms', 'delta']); 297 | 298 | Object 299 | .keys(targets) 300 | .forEach(target => { 301 | const bundleDir = path.join(outDir, target); 302 | if (!fs.existsSync(bundleDir)) { 303 | fs.mkdirSync(bundleDir); 304 | } 305 | writePromises.push(...Object 306 | .keys(polyfills) 307 | .map(async file => { 308 | const fileOut = path.join(bundleDir, file); 309 | const now = Date.now(); 310 | const useTerser = target === 'esm' ? options.useTerserForBaseline : options.useTerser; 311 | const code = await worker.compileAndWrite( 312 | dist, file, target, 313 | fileOut, polyCache[`${target}-${file}`], 314 | { 315 | targets: targets[target], 316 | plugins: options.babelTransform, 317 | useSWC: options.useSWC, 318 | useTerser: useTerser, 319 | } 320 | ); 321 | const delta = fileSize(fileOut) - fileSize(path.join(dist, file)); 322 | tableStream.write([target, file, Date.now() - now, (delta > 0 ? '+' : '-') + Math.abs(delta)]); 323 | })) 324 | }); 325 | 326 | await Promise.all(writePromises); 327 | worker.end(); 328 | }); 329 | console.groupEnd(); 330 | 331 | console.group(); 332 | await inTime(async () => { 333 | console.log(" -> 🥚 -> 🥚", chalk.bold.underline.green("linking...."), otherFiles.length, 'files'); 334 | 335 | const copyCommand = options.copyFiles ? 'cp' : 'ln -s'; 336 | 337 | if (otherFiles.length) { 338 | Object 339 | .keys(targets) 340 | .forEach(target => { 341 | try { 342 | child_process.execSync( 343 | otherFiles 344 | .map(file => `${copyCommand} ${path.join(dist, file)} ${path.join(outDir, target, file)}`) 345 | .join(' && ') 346 | ) 347 | } catch (e) { 348 | // nope 349 | } 350 | }) 351 | } 352 | }); 353 | console.groupEnd(); 354 | 355 | { 356 | console.log(" -> 🦖", chalk.bold.underline.green("you have been de-evoluted")); 357 | console.group(); 358 | const base = getSize(dist, jsFiles); 359 | 360 | const report = [ 361 | ['target', 'size', 'delta', 'polyfills', 'added'] 362 | ]; 363 | report.push(['base', base, 0, '(base)' + basePolyfills.length, '']); 364 | Object 365 | .keys(targets) 366 | .forEach(target => { 367 | const size = getSize(path.join(outDir, target), jsFiles); 368 | const delta = size - base; 369 | report.push([ 370 | target, 371 | size, 372 | (delta > 0 ? '+' : '-') + Math.abs(delta), 373 | targetPolyfills[target].length, 374 | targetPolyfills[target].join(',') 375 | ]); 376 | }); 377 | console.log(table(report, { 378 | columns: { 379 | 1: { 380 | alignment: 'right' 381 | }, 382 | 2: { 383 | alignment: 'right' 384 | }, 385 | 3: { 386 | alignment: 'right' 387 | }, 388 | 4: { 389 | width: 60, 390 | wrapWord: true, 391 | } 392 | } 393 | })); 394 | 395 | console.groupEnd(); 396 | } 397 | 398 | return true; 399 | }; -------------------------------------------------------------------------------- /src/plugins/detectPolyfills.js: -------------------------------------------------------------------------------- 1 | function has(obj, key) { 2 | return Object.prototype.hasOwnProperty.call(obj, key); 3 | } 4 | 5 | function getType(target) { 6 | return Object.prototype.toString.call(target).slice(8, -1).toLowerCase(); 7 | } 8 | 9 | function isNamespaced(path) { 10 | if (!path.node) return false; 11 | const binding = path.scope.getBinding(path.node.name); 12 | if (!binding) return false; 13 | return binding.path.isImportNamespaceSpecifier(); 14 | } 15 | 16 | function resolveKey(path, computed) { 17 | const {node, parent, scope} = path; 18 | if (path.isStringLiteral()) return node.value; 19 | const {name} = node; 20 | const isIdentifier = path.isIdentifier(); 21 | if (isIdentifier && !(computed || parent.computed)) return name; 22 | if (!isIdentifier || scope.getBindingIdentifier(name)) { 23 | const {value} = path.evaluate(); 24 | if (typeof value === "string") return value; 25 | } 26 | } 27 | 28 | function resolveSource(path) { 29 | const {node, scope} = path; 30 | let builtIn, instanceType; 31 | if (node) { 32 | builtIn = node.name; 33 | if (!path.isIdentifier() || scope.getBindingIdentifier(builtIn)) { 34 | const {deopt, value} = path.evaluate(); 35 | if (value !== undefined) { 36 | instanceType = getType(value); 37 | } else if (deopt && deopt.isIdentifier()) { 38 | builtIn = deopt.node.name; 39 | } 40 | } 41 | } 42 | return {builtIn, instanceType, isNamespaced: isNamespaced(path)}; 43 | } 44 | 45 | // https://raw.githubusercontent.com/babel/babel/master/packages/babel-preset-env/src/polyfills/corejs3/usage-plugin.js 46 | 47 | export default (polyfills, flags, definitions) => function ({types: t}) { 48 | const { 49 | BuiltIns, 50 | StaticProperties, 51 | InstanceProperties, 52 | PromiseDependencies, 53 | CommonIterators, 54 | PossibleGlobalObjects, 55 | CommonInstanceDependencies, 56 | } = definitions; 57 | 58 | const addAndRemovePolyfillImports = { 59 | // require('core-js') 60 | // Program: { 61 | // exit(path) { 62 | // const filtered = intersection(polyfills, this.polyfillsSet, available); 63 | // const reversed = Array.from(filtered).reverse(); 64 | // 65 | // for (const module of reversed) { 66 | // // Program:exit could be called multiple times. 67 | // // Avoid injecting the polyfills twice. 68 | // if (!this.injectedPolyfills.has(module)) { 69 | // createImport(path, module); 70 | // } 71 | // } 72 | // 73 | // filtered.forEach(module => this.injectedPolyfills.add(module)); 74 | // }, 75 | // }, 76 | 77 | // import('something').then(...) 78 | Import() { 79 | this.addUnsupported(PromiseDependencies); 80 | }, 81 | 82 | Function({node}) { 83 | // (async function () { }).finally(...) 84 | if (node.async) { 85 | this.addUnsupported(PromiseDependencies); 86 | flags.usesRegenerator = true; 87 | } 88 | // (function* () { }) 89 | if (node.generator) { 90 | flags.usesRegenerator = true; 91 | } 92 | }, 93 | 94 | // for-of, [a, b] = c 95 | "ForOfStatement|ArrayPattern"() { 96 | this.addUnsupported(CommonIterators); 97 | }, 98 | 99 | // [...spread] 100 | SpreadElement({parentPath}) { 101 | if (!parentPath.isObjectExpression()) { 102 | this.addUnsupported(CommonIterators); 103 | } 104 | }, 105 | 106 | // yield* 107 | YieldExpression({node}) { 108 | if (node.delegate) { 109 | this.addUnsupported(CommonIterators); 110 | } 111 | }, 112 | 113 | // Symbol(), new Promise 114 | ReferencedIdentifier({node: {name}, scope}) { 115 | if (scope.getBindingIdentifier(name)) return; 116 | 117 | this.addBuiltInDependencies(name); 118 | }, 119 | 120 | MemberExpression(path) { 121 | const source = resolveSource(path.get("object")); 122 | const key = resolveKey(path.get("property")); 123 | 124 | // Object.entries 125 | // [1, 2, 3].entries 126 | this.addPropertyDependencies(source, key); 127 | }, 128 | 129 | ObjectPattern(path) { 130 | const {parentPath, parent, key} = path; 131 | let source; 132 | 133 | // const { keys, values } = Object 134 | if (parentPath.isVariableDeclarator()) { 135 | source = resolveSource(parentPath.get("init")); 136 | // ({ keys, values } = Object) 137 | } else if (parentPath.isAssignmentExpression()) { 138 | source = resolveSource(parentPath.get("right")); 139 | // !function ({ keys, values }) {...} (Object) 140 | // resolution does not work after properties transform :-( 141 | } else if (parentPath.isFunctionExpression()) { 142 | const grand = parentPath.parentPath; 143 | if (grand.isCallExpression() || grand.isNewExpression()) { 144 | if (grand.node.callee === parent) { 145 | source = resolveSource(grand.get("arguments")[key]); 146 | } 147 | } 148 | } 149 | 150 | for (const property of path.get("properties")) { 151 | if (property.isObjectProperty()) { 152 | const key = resolveKey(property.get("key")); 153 | // const { keys, values } = Object 154 | // const { keys, values } = [1, 2, 3] 155 | this.addPropertyDependencies(source, key); 156 | } 157 | } 158 | }, 159 | 160 | BinaryExpression(path) { 161 | if (path.node.operator !== "in") return; 162 | 163 | const source = resolveSource(path.get("right")); 164 | const key = resolveKey(path.get("left"), true); 165 | 166 | // 'entries' in Object 167 | // 'entries' in [1, 2, 3] 168 | this.addPropertyDependencies(source, key); 169 | }, 170 | }; 171 | 172 | return { 173 | name: "use-built-ins-devo", 174 | pre() { 175 | this.polyfillsSet = new Set(); 176 | 177 | this.addUnsupported = function (builtIn) { 178 | const modules = Array.isArray(builtIn) ? builtIn : [builtIn]; 179 | for (const module of modules) { 180 | this.polyfillsSet.add(module); 181 | } 182 | }; 183 | 184 | this.addBuiltInDependencies = function (builtIn) { 185 | if (has(BuiltIns, builtIn)) { 186 | const BuiltInDependencies = BuiltIns[builtIn]; 187 | this.addUnsupported(BuiltInDependencies); 188 | } 189 | }; 190 | 191 | this.addPropertyDependencies = function (source = {}, key) { 192 | const {builtIn, instanceType, isNamespaced} = source; 193 | if (isNamespaced) return; 194 | if (PossibleGlobalObjects.includes(builtIn)) { 195 | this.addBuiltInDependencies(key); 196 | } else if (has(StaticProperties, builtIn)) { 197 | const BuiltInProperties = StaticProperties[builtIn]; 198 | if (has(BuiltInProperties, key)) { 199 | const StaticPropertyDependencies = BuiltInProperties[key]; 200 | return this.addUnsupported(StaticPropertyDependencies); 201 | } 202 | } 203 | if (!has(InstanceProperties, key)) return; 204 | let InstancePropertyDependencies = InstanceProperties[key]; 205 | if (instanceType) { 206 | InstancePropertyDependencies = InstancePropertyDependencies.filter( 207 | m => m.includes(instanceType) || CommonInstanceDependencies.includes(m), 208 | ); 209 | } 210 | this.addUnsupported(InstancePropertyDependencies); 211 | }; 212 | }, 213 | post() { 214 | for (let i of this.polyfillsSet) { 215 | polyfills.push(i); 216 | } 217 | }, 218 | visitor: addAndRemovePolyfillImports, 219 | }; 220 | } -------------------------------------------------------------------------------- /src/rc.js: -------------------------------------------------------------------------------- 1 | import {existsSync, writeFileSync, readFileSync} from 'fs'; 2 | import {join} from 'path'; 3 | 4 | const cwd = () => process.cwd(); 5 | const DEVOLUTION_RC = '.devolutionrc.js'; 6 | 7 | const rcFileName = () => join(cwd(), DEVOLUTION_RC); 8 | 9 | export const ensureRCExists = () => { 10 | const rc = rcFileName(); 11 | if (!existsSync(rc)) { 12 | writeFileSync(rc, readFileSync(join(__dirname, '..', DEVOLUTION_RC))); 13 | } 14 | }; 15 | 16 | export const getRC = () => { 17 | ensureRCExists(); 18 | return require(rcFileName()); 19 | }; -------------------------------------------------------------------------------- /src/smoke-tester.js: -------------------------------------------------------------------------------- 1 | class SmokeTester { 2 | classField = () => 42; 3 | 4 | constructor() { 5 | this.magic = 42; 6 | // import('./detector') 7 | } 8 | } -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import path from "path"; 3 | 4 | /** 5 | * checks if target is below rule 6 | * @param ruleName 7 | * @param rule minimal passable value 8 | * @param target current value 9 | * @returns {*} 10 | */ 11 | export const isBelow = (ruleName, rule, target) => ( 12 | rule && Object 13 | .keys(target) 14 | .some(x => ( 15 | !rule[x] || +rule[x] > +target[x] 16 | ) 17 | ) 18 | ); 19 | 20 | export const fileSize = file => fs.statSync(file).size; 21 | 22 | export const getSize = (location, files) => ( 23 | files.reduce((acc, name) => acc + fs.statSync(path.join(location, name)).size, 0) 24 | ); 25 | 26 | export const inTime = async cb => { 27 | const timeIn = Date.now(); 28 | await cb(); 29 | console.info('\n'); 30 | console.info(' --- step finished in ', Math.round(100 * (Date.now() - timeIn) / 1000) / 100, 's'); 31 | console.info('\n'); 32 | }; -------------------------------------------------------------------------------- /src/workers/composePolyfill.js: -------------------------------------------------------------------------------- 1 | import terser from "terser"; 2 | 3 | import {rollup} from 'rollup'; 4 | import rollupReplace from 'rollup-plugin-replace'; 5 | import rollupCommonjs from 'rollup-plugin-commonjs'; 6 | import rollupNodeResolve from 'rollup-plugin-node-resolve'; 7 | 8 | export const composePolyfillRollup = (fileIn) => ( 9 | new Promise(async resolve => { 10 | try { 11 | const bundle = await rollup({ 12 | input: fileIn, 13 | 14 | plugins: [ 15 | rollupReplace({ 16 | 'process.env.NODE_ENV': JSON.stringify('production') 17 | }), 18 | 19 | rollupNodeResolve({ 20 | main: true 21 | }), 22 | 23 | rollupCommonjs({ 24 | include: 'node_modules/**', 25 | extensions: ['.js'], 26 | ignoreGlobal: false, // Default: false 27 | sourceMap: false, // Default: true 28 | }) 29 | ] 30 | }); 31 | const {output} = await bundle.generate({ 32 | format: 'iife' 33 | }); 34 | resolve(terser.minify(output[0].code).code); 35 | } catch (e) { 36 | console.error(e); 37 | resolve({error: e.message}); 38 | } 39 | }) 40 | ); 41 | 42 | export const composePolyfill = (fileIn) => composePolyfillRollup(fileIn); 43 | -------------------------------------------------------------------------------- /src/workers/detect.js: -------------------------------------------------------------------------------- 1 | import {readFileSync} from 'fs'; 2 | import {join} from 'path'; 3 | 4 | import {transformSync} from "@babel/core"; 5 | 6 | import createDetector from '../plugins/detectPolyfills'; 7 | 8 | export const extractPolyfills = (dist, file, plugins, definitions) => { 9 | const fills = []; 10 | const flags = { 11 | usesRegenerator: false 12 | }; 13 | const code = readFileSync(join(dist, file)).toString(); 14 | transformSync(code, { 15 | babelrc: false, 16 | plugins: [ 17 | createDetector(fills, flags, definitions), 18 | ...Array.from(plugins), 19 | ], 20 | }); 21 | 22 | if (flags.usesRegenerator) { 23 | fills.push('@regenerator'); 24 | } 25 | 26 | return fills; 27 | }; -------------------------------------------------------------------------------- /src/workers/transpile.js: -------------------------------------------------------------------------------- 1 | import {readFileSync, writeFileSync} from 'fs'; 2 | import {join} from 'path'; 3 | 4 | import terser from "terser"; 5 | 6 | const compileBabel = (code, targets, plugins) => { 7 | const {transformSync} = require("@babel/core"); 8 | return transformSync(code, { 9 | babelrc: false, 10 | presets: [ 11 | [ 12 | '@babel/preset-env', { 13 | targets, 14 | }]], 15 | plugins, 16 | }).code; 17 | }; 18 | 19 | const compileSWC = async (code, minify) => { 20 | const {transform} = require("@swc/core"); 21 | 22 | return (await transform(code, { 23 | "minify": minify, 24 | "module": { 25 | "type": "commonjs", 26 | "strict": false, 27 | "strictMode": false, 28 | }, 29 | "jsc": { 30 | "parser": { 31 | "syntax": "ecmascript", 32 | "classProperty": true 33 | }, 34 | "target": "es5", 35 | "transform": { 36 | "optimizer": undefined 37 | } 38 | } 39 | })).code; 40 | }; 41 | 42 | export const compile = async (dist, file, target, {targets, plugins, useSWC, useTerser}) => { 43 | const code = readFileSync(join(dist, file)).toString(); 44 | try { 45 | const transformedCode = await ( 46 | target === 'esm' 47 | ? code 48 | : ((useSWC && target === "es5") 49 | ? compileSWC(code, useTerser) 50 | : compileBabel(code, targets, plugins) 51 | ) 52 | ); 53 | 54 | if (useTerser) { 55 | const {code, error} = terser.minify(transformedCode, { 56 | mangle: false, 57 | keep_fnames: true, 58 | keep_classnames: true, 59 | 60 | // modern target 61 | ecma: target === "es5"? 5 : 8, 62 | safari10: true 63 | }); 64 | 65 | if (error) { 66 | console.error('terser[', file, ':', error); 67 | } 68 | 69 | return code || `/* with terser error: ${error}*/\n${transformedCode}`; 70 | } 71 | 72 | return transformedCode; 73 | } catch (e) { 74 | console.error('while processing', dist, file); 75 | console.error(e); 76 | throw e; 77 | } 78 | }; 79 | 80 | export const compileAndWrite = async (dist, file, target, fileOut, prepend, options) => { 81 | const code = await compile(dist, file, target, options); 82 | 83 | writeFileSync( 84 | fileOut, 85 | `var devolutionBundle = '${target}';\n${prepend}\n${code}` 86 | ); 87 | }; 88 | --------------------------------------------------------------------------------