webpack advanced applications: Polyfills

Polyfills

npm install --save @babel/polyfill

Then, import it into our main bundle file:

import '@babel/polyfill'
console.log(Array.from([1, 2, 3], x => x + x))

Note that this approach gives priority to correctness rather than bundle size. In order to be safe and reliable, polyfill/shim must run before all other codes and need to be loaded synchronously, or all application codes need to be loaded after all polyfill/shim are loaded. There are many misconceptions in the community that modern browsers "don't need" polyfill, or polyfill/shim is only used to add missing functions - in fact, they are usually used to repair broken implementation, even in the most modern browsers. Therefore, the best practice remains to load all polyfill/shim indiscriminately and synchronously, although this results in additional bundle volume costs.

Further optimize Polyfills

Import @ Babel / polyfill is not recommended. Because the disadvantage of this is that the whole polyfill package, such as array. Com, will be introduced globally From will be introduced globally, which not only has a large package volume, but also pollutes the global environment.

Babel preset env package browserslist To translate features that are not supported in your browser. This preset uses useBuiltIns Option. The default value is false. In this way, the global Babel Polyfill import can be improved to a more fine-grained import format:

import 'core-js/modules/es7.string.pad-start';
import 'core-js/modules/es7.string.pad-end';
import 'core-js/modules/web.timers';
import 'core-js/modules/web.immediate';
import 'core-js/modules/web.dom.iterable';
  • Install @ Babel / preset Env and related packages
npm i babel-loader @babel/core @babel/preset-env -D
  • webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  plugins: [new HtmlWebpackPlugin()],
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                targets: [ // Tell @ Babel / preset env that if you encounter such a browser, you need to add shims through Polyfills
                  '> 1%',
                  'last 1 version',
                ],
                useBuiltIns: 'usage',
              },
            ],
          ],
        },
      },
    }],
  },
};

useBuiltIns: the parameter has three values: entry, usage and false

The default value is false. This parameter determines how to handle @ babel / Polyfill statements when babel is packaged.

"entry": the import '@ Babel / Polyfill' statement in the file will be combined with targets and converted into a series of import statements. The Polyfill module supported by the target browser will be removed. Whether it is used in the code or not, as long as the target browser does not support it, the corresponding Polyfill module will be introduced.

"Usage": there is no need to manually write import '@babel/polyfilll' in the code. When packaging, it will automatically introduce some polyfilll modules actually used in the code according to the actual code usage and in combination with targets

false: import '@babel/polyfilll' will not be processed, nor will the polyfilll module be automatically introduced. It should be noted that @ babel/polyfill introduced in the entry of webpack package file configuration will not configure any conversion processing according to useBuiltIns.

Since @ babel/polyfill is in 7.4 0 is deprecated. We recommend adding corejs directly and setting the version through the corejs option.

Perform compilation npx webpack

HuaJi:step_11-Polyfills HuaJi$ npx webpack

WARNING (@babel/preset-env): We noticed you're using the `useBuiltIns` option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default version will likely change in future versions of Babel, we recommend explicitly setting the core-js version you are using via the `corejs` option.

You should also be sure that the version you pass to the `corejs` option matches the version specified in your `package.json`'s `dependencies` section. If it doesn't, you need to run one of the following commands:

  npm install --save core-js@2    npm install --save core-js@3
  yarn add core-js@2              yarn add core-js@3

More info about useBuiltIns: https://babeljs.io/docs/en/babel-preset-env#usebuiltins
More info about core-js: https://babeljs.io/docs/en/babel-preset-env#corejs

  When setting `useBuiltIns: 'usage'`, polyfills are automatically imported when needed.
  Please remove the direct import of `@babel/polyfill` or use `useBuiltIns: 'entry'` instead.
asset main.js 16.8 KiB [emitted] [minimized] (name: main)
asset index.html 214 bytes [emitted]
runtime modules 663 bytes 3 modules
modules by path ../../node_modules/core-js/modules/*.js 38.9 KiB 68 modules
./src/index.js 346 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 2242 ms

A warning appears: useBuiltIns requires a core JS translator. Install core JS

npm i core-js@3 -S

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  plugins: [new HtmlWebpackPlugin()],
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                targets: [ // Tell @ Babel / preset env that if you encounter such a browser, you need to add shims through Polyfills
                  '> 1%',
                  'last 1 version',
                ],
                useBuiltIns: 'usage',
                corejs: 3, // Add corejs configuration
              },
            ],
          ],
        },
      },
    }],
  },
};

Execute npx webpack

See the warning. When 'usebuiltins:' usage 'is set, polyfills will be imported automatically when necessary.
Please remove the direct import of '@ babel/polyfill' or use 'usebuiltins:' entry 'instead.

Delete import '@babel/polyfill'

// import '@babel/polyfill';

console.log(Array.from([1, 2, 3], (x) => x + x));

Execute npx webpack again

Optimization succeeded! The volume of packaged bundle file has been abbreviated!

Keywords: Front-end Webpack Babel

Added by djdaz on Sun, 19 Dec 2021 22:37:59 +0200