Browse Source

[Tooling] Expand browsers target while keeping Polyfills under control (#709)

* expand browsers target

* add eslint-plugin-compat

* sort polyfils

* adjust readme

* add polyfills sync check action

* only build js

* trim

* add Element.prototype.closest

* add closest to demo links

* fix ignore
pull/719/head
Konstantin Vyatkin 2 years ago
committed by Josh Johnson
parent
commit
172366d6fa
  1. 3
      .browserslistrc
  2. 25
      .eslintrc.json
  3. 14
      .github/actions-scripts/polyfills-sync.js
  4. 5
      .github/workflows/lint.yml
  5. 23
      .github/workflows/polyfills-sync.yml
  6. 31
      README.md
  7. 65
      package-lock.json
  8. 1
      package.json
  9. 24
      public/assets/scripts/.eslintrc.js
  10. 2
      public/index.html
  11. 2
      src/scripts/actions/general.js
  12. 1
      src/scripts/actions/groups.js

3
.browserslistrc

@ -1,2 +1 @@
> 5%
IE 11
> 1%

25
.eslintrc → .eslintrc.json

@ -2,13 +2,18 @@
"parserOptions": {
"ecmaVersion": 2020
},
"extends": ["airbnb-base", "plugin:prettier/recommended"],
"extends": [
"airbnb-base",
"plugin:prettier/recommended",
"plugin:compat/recommended"
],
"plugins": ["prettier"],
"env": {
"es6": true,
"browser": true
},
"rules": {
"import/prefer-default-export": "off",
"import/no-extraneous-dependencies": [
"error",
{
@ -41,7 +46,8 @@
"mocha": true
},
"rules": {
"no-restricted-syntax": "off"
"no-restricted-syntax": "off",
"compat/compat": "off"
}
},
{
@ -51,5 +57,18 @@
"cypress/globals": true
}
}
]
],
"settings": {
"polyfills": [
"Array.from",
"Array.prototype.find",
"Array.prototype.includes",
"Symbol",
"Symbol.iterator",
"Object.assign",
"CustomEvent",
"Element.prototype.classList",
"Element.prototype.closest"
]
}
}

14
.github/actions-scripts/polyfills-sync.js

@ -0,0 +1,14 @@
const { readFileSync } = require('fs');
const path = require('path');
const assert = require('assert');
const readme = readFileSync(path.resolve(__dirname, '../../README.md'), 'utf8');
const polyfillsFromDocs = /^```polyfills\s*\n([^`]+)\n^```/m
.exec(readme)[1]
.split('\n')
.map(v => v.trim())
.sort();
// @ts-ignore
const polyfillsFromSettings = require('../../.eslintrc.json').settings.polyfills.sort();
assert.deepStrictEqual(polyfillsFromDocs, polyfillsFromSettings);

5
.github/workflows/lint.yml

@ -31,3 +31,8 @@ jobs:
if [[ -z $(sed -e 's/[[:space:]]*$//' <<<${CHANGED_JS}) ]]; then CHANGED_JS="src/scripts"; fi
echo $CHANGED_JS
node node_modules/eslint/bin/eslint.js $CHANGED_JS
- name: Lint JS bundle
run: |
npm run js:build
npx eslint --no-ignore ./public/assets/scripts/*.js

23
.github/workflows/polyfills-sync.yml

@ -0,0 +1,23 @@
name: Polyfills documentation
on:
pull_request:
paths:
- 'README.md'
- '.browserslistrc'
- '.eslintrc.json'
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- uses: actions/setup-node@v1
with:
node-version: 12
- name: Check Polyfills documentation and settings sync
run: node .github/actions-scripts/polyfills-sync.js

31
README.md

@ -1029,29 +1029,30 @@ example.setChoiceByValue('Two'); // Choice with value of 'Two' has now been sele
## Browser compatibility
Choices is compiled using [Babel](https://babeljs.io/) to enable support for [ES5 browsers](http://caniuse.com/#feat=es5). If you need to support a browser that does not support one of the features listed below, I suggest including a polyfill from the very good [polyfill.io](https://cdn.polyfill.io/v2/docs/):
Choices is compiled using [Babel](https://babeljs.io/) targeting browsers [with more that 1% of global usage](https://github.com/jshjohnson/Choices/blob/master/.browserslistrc) and expecting that features [listed below](https://github.com/jshjohnson/Choices/blob/master/.eslintrc.json#L62) are available or polyfilled in browser.
You may see exact list of target browsers by running `npx browserslist` withing this repository folder.
If you need to support a browser that does not have one of the features listed below,
I suggest including a polyfill from the very good [polyfill.io](https://polyfill.io/v3/):
**Polyfill example used for the demo:**
```html
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=es5,fetch,Element.prototype.classList,requestAnimationFrame,Node.insertBefore,Node.firstChild,CustomEvent"></script>
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=es5,es6,fetch,Array.prototype.includes,CustomEvent,Element.prototype.closest"></script>
```
**Features used in Choices:**
- Array.prototype.forEach
- Array.prototype.map
- Array.prototype.find
- Array.prototype.some
- Array.prototype.includes
- Array.from
- Array.prototype.reduce
- Array.prototype.indexOf
- Object.assign
- Element.prototype.classList
- Element.prototype.closest
- window.requestAnimationFrame
- CustomEvent
```polyfills
Array.from
Array.prototype.find
Array.prototype.includes
Symbol
Symbol.iterator
Object.assign
CustomEvent
Element.prototype.classList
Element.prototype.closest
```
## Development

65
package-lock.json

@ -753,6 +753,15 @@
"source-map-support": "^0.5.9"
}
},
"@babel/runtime": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz",
"integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==",
"dev": true,
"requires": {
"regenerator-runtime": "^0.13.2"
}
},
"@babel/template": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz",
@ -1539,6 +1548,12 @@
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
"dev": true
},
"ast-metadata-inferer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.1.1.tgz",
"integrity": "sha512-hc9w8Qrgg9Lf9iFcZVhNjUnhrd2BBpTlyCnegPVvCe6O0yMrF57a6Cmh7k+xUsfUOMh9wajOL5AsGOBNEyTCcw==",
"dev": true
},
"astral-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
@ -2214,6 +2229,12 @@
}
}
},
"caniuse-db": {
"version": "1.0.30001004",
"resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001004.tgz",
"integrity": "sha512-VBTptWLoxsIhIGFZOEvtHhdRyhh+6JARUnVy2debGRNmrKfunVAa9cRuAvOnrQk4z/SDiNm5S2d6h32eIHZMoA==",
"dev": true
},
"caniuse-lite": {
"version": "1.0.30001002",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001002.tgz",
@ -3882,6 +3903,29 @@
}
}
},
"eslint-plugin-compat": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.3.0.tgz",
"integrity": "sha512-QCgYy3pZ+zH10dkBJus1xER0359h1UhJjufhQRqp9Owm6BEoLZeSqxf2zINwL1OGao9Yc96xPYIW3nQj5HUryg==",
"dev": true,
"requires": {
"@babel/runtime": "^7.4.5",
"ast-metadata-inferer": "^0.1.1",
"browserslist": "^4.6.3",
"caniuse-db": "^1.0.30000977",
"lodash.memoize": "4.1.2",
"mdn-browser-compat-data": "^0.0.84",
"semver": "^6.1.2"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"eslint-plugin-cypress": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.7.0.tgz",
@ -7971,6 +8015,12 @@
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
"dev": true
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
"dev": true
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
@ -8099,6 +8149,15 @@
"safe-buffer": "^5.1.2"
}
},
"mdn-browser-compat-data": {
"version": "0.0.84",
"resolved": "https://registry.npmjs.org/mdn-browser-compat-data/-/mdn-browser-compat-data-0.0.84.tgz",
"integrity": "sha512-fAznuGNaQMQiWLVf+gyp33FaABTglYWqMT7JqvH+4RZn2UQPD12gbMqxwP9m0lj8AAbNpu5/kD6n4Ox1SOffpw==",
"dev": true,
"requires": {
"extend": "3.0.2"
}
},
"mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
@ -11391,6 +11450,12 @@
"regenerate": "^1.4.0"
}
},
"regenerator-runtime": {
"version": "0.13.3",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
"integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==",
"dev": true
},
"regenerator-transform": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz",

1
package.json

@ -67,6 +67,7 @@
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-prettier": "^6.4.0",
"eslint-loader": "^3.0.2",
"eslint-plugin-compat": "3.3.0",
"eslint-plugin-cypress": "^2.7.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.1",

24
public/assets/scripts/.eslintrc.js

@ -0,0 +1,24 @@
// get polyfill settings from top level config
// @ts-ignore
const { settings } = require('../../../.eslintrc.json');
// Adding non-polyfilable Symbol-related functions as they are most probably
// behind the flag
settings.polyfills.push('Symbol.toStringTag', 'Symbol.for', 'Object.getOwnPropertySymbols', 'Object.getOwnPropertyDescriptors')
module.exports = /** @type {import('eslint').Linter.Config} */({
root: true,
extends: [
"plugin:compat/recommended"
],
parserOptions: {
// ensure that it's compatible with ES5 browsers, so, no `const`, etc
ecmaVersion: 5
},
env: {
browser: true
},
settings
})

2
public/index.html

@ -47,7 +47,7 @@
<!-- End ignore these -->
<!-- Optional includes -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=es5%2Ces6%2CArray.prototype.includes%2Cfetch%2CCustomEvent"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es5%2Ces6%2CArray.prototype.includes%2Cfetch%2CCustomEvent%2CElement.prototype.closest"></script>
<!-- End optional includes -->
<!-- Choices includes -->

2
src/scripts/actions/general.js

@ -1,5 +1,3 @@
/* eslint-disable import/prefer-default-export */
export const setIsLoading = isLoading => ({
type: 'SET_IS_LOADING',
isLoading,

1
src/scripts/actions/groups.js

@ -1,6 +1,5 @@
import { ACTION_TYPES } from '../constants';
/* eslint-disable import/prefer-default-export */
export const addGroup = (value, id, active, disabled) => ({
type: ACTION_TYPES.ADD_GROUP,
value,

Loading…
Cancel
Save