We will use some new apis during development, but the user’s browser has different versions, may not support these apis, but we can not use them, in this case, we can solve the problem through Polyfill.

Polyfill stands for shim, which means to inject some implementation of the API globally before running the business code so that it will be available when running the business code using the API and there will be no compatibility issues.

However, users may have a variety of browsers, and it is possible that our Polyfill API already supports polyfill, so loading Polyfill is unnecessary and wasteful of performance.

Is there a way to resolve the compatibility issues with environments that don’t support the API without introducing unnecessary code into environments that do?

The answer is preset-env, which implements the introduction of polyfills on demand.

Here preset-env refers to @babel/preset-env of Babel and postCSS-preset -env of postCSS, one of which is an on demand syntactic shift, and an on demand JS polyfill, One is to add CSS compatibility processing such as prefix as needed.

Although they are for JS and CSS respectively, their principles are similar, so let’s take a look at them separately.

@babel/preset-env

On-demand refers to whether the target runtime environment is supported or not. How do you specify the target runtime environment?

@babel/preset-env supports targets to specify the target environment:

{ 
   "presets": [["@babel/preset-env", { 
            "targets": "> 0.25%, not dead." "}}]]Copy the code

Targets here is the browserslist query string, which can parse the query string to return the corresponding browser version:

With these target browser versions in hand, you also need to know in what version the various features are supported:

Babel maintains a database in the @babel/compat-data package:

This allows you to filter out which features are supported and which are not, based on the version of the target browser. Then do syntactic conversions and polyfills only for unsupported features.

This is how polyfill on demand works.

On-demand compatibility with CSS is similar:

postcss-preset-env

Postcss is built on demand using postCSS-preset -env and also supports configuring the target environment, which is built:

postcssPresetEnv({ browsers: 'last 2 versions' })
Copy the code

Browserslist is also used to convert the query string to the corresponding browser version.

It then filters out unsupported CSS features based on which CSS features are supported from which browser version.

Here we use caniuse data in the CSSDB package:

Knowing the version of the target browser and what version of the browser these features are supported on, you can naturally filter out unsupported CSS features. Then introduce different PostCSS plug-ins to handle the prefix and so on for these features.

This is how CSS’s on-demand prefix processing works.

As you can see, both Babel and POTCSS rely on browerslist to query the target browser version, which can be unified into a.browserslistrc configuration file in the root directory. By specifying the same environment to do JS and CSS compatibility on demand.

conclusion

Users’ browsers may be various. The FEATURES of JS and CSS used in our development may not be supported by users’ browsers. In order to ensure normal functions, compatibility processing must be done.

JS compatibility processing is polyfill, CSS compatibility processing is to add prefix, etc.

Babel is polyfilled and turned on demand via @babel/preset-env by querying the target browser version via Browserslist, It then filters out what features are not supported in these browser versions based on the @babel/compat-data database, and then introduces the corresponding plug-in processing.

Postcss postCSS-preset -env is used for on-demand prefixes, etc. Browserslist is also used to query the target browser version, It then filters out unsupported CSS features from the CSSDB database (from Caniuse), and then handles them.

As preset-env is named, they are preset to on-demand processing according to the target environment, also known as intelligent processing, which is much smarter than the brutal preset of ES5 and ES6.