Babel 7 + Webpack 設定和解說

如何使用 Babel

  1. 安裝相關 NPM 套件
  2. 建立 .babelrc 檔案
  3. 建立 .browserslistrc 檔案
  4. webpack.config.js 調整設定
  5. 設定 Polyfills

1. 安裝 NPM 套件

npm install --save-dev @babel/core @babel/register @babel/preset-env babel-loader
npm install --save  @babel/polyfill

Make sure that you install @babel/polyfill as a dependency, not a dev-dependency

套件說明

  • @babel/core

    The core package. The package is responsible for compiling javascript code and outputting usable code.

  • @babel/register

    Use new features of javascript in our Webpack config.

  • @babel/preset-env

    Knowing what browser supports what javascript feature is essential in transforming your code. You tell Babel: “I need support for these browsers”, and it will transform your javascript so it will work on the list you provide.

  • @babel/polyfill

    It provide polyfills for those featured ex. Array.from()fetch …, based on what browsers you wish to support.

  • babel-loader

    Allows us to transpile our code using Babel and Webpack.

2. 建立 .babelrc 檔案

Create a .babelrc file in the root of your project. Babel will look for this file as a source for your configuration.

{
  "presets": [
    ["@babel/preset-env", {
      "debug":true
    }]
  ]
}

↑ This will tell Babel to use the preset-env-package to look for what browsers to support.

.babelrc 只是其中一種設定方式,也可在其他地方設定,見官網

3. 建立 .browserslistrc 檔案

The easiest way to tell Babel what browsers to use it to make a .browserslistrc file.

This file contains a list of the browsers you wish to support. Browserlist has a really nice tool that you can play around with to show you what browsers are selected based on the query you write.

# Browsers that we support
> .05% in BE
not ie <= 9

↑ I want to support every browser that has more then 0.05% coverage in Belgium and that’s newer then IE9.

you define your browsers in one place, and other tools like postCss will use that same resource. So your supported browsers are defined in a single source of truth, which is a best practice.

4. 在 webpack.config.js 調整設定

const path = require('path');

module.exports = {
  entry: './src/index.js',
  mode: 'development',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
      }
    }]
  },
};

↑ This will tell Webpack to use the babel-loader plugin when going through javascript files (except for handling files from within the node_modules folder), so your javascript code goes through Babel’s optimisation.

5. 設定 Polyfills

總共有 3 種方式設定 Polyfills,任選其中一種方式做,最推薦的是 5-3

5-1. 快速但骯髒

The easiest way to import the polyfills provided by Babel is by including it in your entry point in Webpack. Change your webpack.config.js to the following:

const path = require('path');

module.exports = {
  entry: {
    main: [
      '@babel/polyfill',
      './src/index.js',
    ]
  },
  mode: 'development',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
      }
    }]
  },
};

What we did here, we created an entry point (main), with multiple entry-files. First we’re including all the polyfills from @babel/polyfill, regardless wether we’re going to need them. Next we’re using our index.js as our entry point.

缺點

  • File size:Almost 400kb big. 99% 的 code 客戶端根本不需要
  • Multiple-instances of polyfills:If your code would have multiple entry points, you will be pushing the same polyfills for every entry point, resulting in even more network traffic. Babel also advises against using multiple instances of the polyfills on the same page.

5-2 較乾淨的使用

A better way is to use the useBuiltIns option. This option is a way of telling Babel what kind of polyfilling it should be doing. The possible options are:

useBuiltIns Result
false Never apply polyfills
entry Replace top-level polyfill with individual polyfills
usage Add individual polyfills in every file based on usage


webpack.config.js 回復成原本的設定

const path = require('path');

module.exports = {
  entry: './src/index.js',
  mode: 'development',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
      }
    }]
  },
};

.babelrc 裡新增設定,"useBuiltIns": "entry"

{
  "presets": [
    ["@babel/preset-env", {
      "useBuiltIns": "entry",
      "debug":true
    }]
  ]
}

在 Entry file (ex. src/index.js) 頂端 import @babel/polyfill

// index.js

import '@babel/polyfill';

const greetings = (name) => {
  return `hello ${name}`;
}
console.log(greetings('Steve'));

缺點

  • 雖然整體大小縮減到約 400kb,但是還是有點大

5-3 最聰明也較推薦 :tipping_hand_woman::bulb::point_left:

在 Entry file (ex. src/index.js) 裡移除 import '@babel/polyfill

// index.js
// 不需要 import polyfill

const greetings = (name) => {
  return `hello ${name}`;
}
console.log(greetings('Steve'));

只需要在 .babelrc 裡修改設定 → "useBuiltIns": "usage"

{
  "presets": [
    ["@babel/preset-env", {
      "useBuiltIns": "usage",
      "debug":true
    }]
  ]
}

優點

  • With the usage option enabled, Babel goes through your javascript and only includes the polyfills it needs to transform your code. This will result in a much smaller file-size (only 60kb) :tada: :confetti_ball: :grin:

相關閱讀

Working with Babel 7 and Webpack

好奇,做了 5-3 的設定之外?
還需要在任何 Entry file 加入?

import '@babel/polyfill';

不需要喔
我沒寫清楚,我把這段文字稍微再修改了

1個讚