Browser compability with core-js and eslint
When building public websites or libraries it's easy to assume that everyone is on a an evergreen browser, but as for instance the older iOS devices work pretty will we need to handle browsers that are missing the newer features. So how do we make sure we don't rely on newer api't that isn't supported in older browser? We can add a polyfill to our app build time using core-js or we can add dynamic polyfill using cloudflare. In this post we'll add core-js in a vite-project and also add the eslint-plugin-compat plugin to eslint to validate that we're not using any features not available the browsers we target.
Core-js polyfill
Start by installing core-js from npm:
yarn add core-js -D
Assuming that your building a typescript app with esm you just add the imports to the top of the index.ts file, for instance for adding polyfills for URL, UrlSearchParams and fetch:
import 'core-js/actual/url';
import 'core-js/actual/url-search-params';
import 'core-js/actual/fetch';
If the app is packaged using vite you need to add core-js as an external in the rollupOptions in the vite.config.ts
file:
module.exports = defineConfig({
build: {
...
rollupOptions: {
external: ['core-js/actual/URL', 'core-js/actual/URLSearchParms', 'core-js/actual/fetch'],
},
},
});
Eslint rule
This applies to eslint version 9 and uses the eslint.config.mjs
file.
Install the eslint-plugin-compat
library from npm:
yarn add eslint-plugin-compat -D
Add the plugin to the eslint configuration.
// eslint.config.mjs
import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import compat from 'eslint-plugin-compat';
export default [
{ files: ['**/*.{js,mjs,cjs,ts}'] },
{ languageOptions: { globals: globals.browser } },
pluginJs.configs.recommended,
compat.configs['flat/recommended'],
...tseslint.configs.recommended,
{
settings: {
polyfills: ['URL', 'URLSearchParams', 'fetch'],
},
},
];
Add the eslint-plugin-compat configuration to the package.json file. This config will validate the compatibility against the 99.5% most common browsers:
{
"browserslist": [
"> 0.5%"
],
....
}
Run eslint to check if any polyfills are missing:
npx eslint src