preface

This exploration of Babel builds on my previous article, webpack4.0 primer – building a basic environment for front-end development. Webpack Babel was covered almost in passing in the previous article, so this article will supplement it.

Babel is a JS compilation tool that allows us to use new ES features. We can configure Babel in Webpack to write JS code using ES6 and ES7 standards.

This section uses the latest version of babel-7.10 as an example to configure Babel. Related version numbers are as follows

{
  "devDependencies": {
    "@babel/core": "^ 7.1.6." "."@babel/plugin-proposal-decorators": "^ 7.1.6." "."@babel/plugin-transform-runtime": "^ 7.1.0"."@babel/preset-env": "^ 7.1.6." "."@babel/runtime": "^ 7.1.5." "."babel-loader": "^ 8.0.4"."webpack": "^ 4.26.1"."webpack-cli": "^ 3.1.2." "}}Copy the code

Babel – loader and @ Babel/core

Create a basic WebPack configuration file

mkdir webpack-babel= > cd  webpack-babel= > yarn init -y  / / initialization
npm i yarn -g // If yarn is installed, you can ignore it
yarn add webpack webpack-cli -D

// Package. json to add:
"scripts": {
  "start": "webpack --mode development"."build": "webpack --mode production"
}

yarn add babel-loader @babel/core -D
Copy the code
  • yarnAnd:npmAlmost the same as used in this articleyarnInstall…
  • Babel-loader: loader to escape js file code
  • @babel/core: Babel core library

Add webpack.config.js to the root directory

const path = require('path')

module.exports = {
  entry: './src/index.js'.output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[hash:8].js'
  },
  module: {
    rules: [{test: /\.m? js$/.exclude: /(node_modules|bower_components)/.use: { loader: 'babel-loader' } // Options are defined in.babelrc}}}]Copy the code

src/index.js

const func = (a)= > {
  console.log('hello webpack')
}
func()

class User {
  constructor() {
    console.log('new User')}}const user = new User()
Copy the code

After the YARN Build command is executed, the package is successful and the packaged code is compressed. The code after YARN Start is uncompressed. To make the code more readable, we can add it to webpack.config.js:

module.exports = {
  / /...
  devtool: true
}
Copy the code

@babel/preset-env

After packing, we can see that the arrow function has not been converted to ES5 syntax!

Look at the Babel Plugins documentation, and if you want to escape the arrow function, Use @babel/plugin-transform-arrow-functions to escape classes using @babel/plugin-transform-classes

yarn add @babel/plugin-transform-arrow-functions @babel/plugin-transform-classes -D
Copy the code

Create.babelrc file in root directory:

{
  "plugins": [
    "@babel/plugin-transform-arrow-functions"."@babel/plugin-transform-classes"]}Copy the code

After YARN build, you can see that the arrow functions and classes have been escaped.

But if you use es6 syntax like async await, you have to add them one by one, which is not practical.

@babel/preset-env incorporates these syntactic escapes:

Using plugins:
transform-template-literals {}
transform-literals {}
transform-function-name {}
transform-arrow-functions {}
transform-block-scoped-functions {}
transform-classes {}
transform-object-super {}
/ /...
Copy the code

Use as follows:

yarn add @babel/preset-env -D
Copy the code

.babelrc

{
  "presets": ["@babel/preset-env"]}Copy the code

@babel/polyfill

By default, Babel only converts new JavaScript syntax, not new apis, such as Iterator, Generator, Set, Maps, Proxy, Reflect, Symbol, Promise, etc. And some methods defined on global objects (such as Object.assign) do not transcode.

As a result, some new apis are incompatible with older browsers. As mentioned above, for new apis, you may need to introduce @babel-Polyfill for compatibility

yarn add @babel-polyfill -D
Copy the code

Modify weboack. Config. Js

module.exports = {
  entry: ['@babel-polyfill'.'./src/index.js']}Copy the code

Yarn Build found that the file size was much larger because the code above indicated that the @babel-Polyfill code was also packaged.

That’s not what we want, of course, but how do you compile on demand? Here’s what we can do:

index.js

import '@babel/polyfill' / / introduction

const func = (a)= > {
  console.log('hello webpack')
}
func()

class User {
  constructor() {
    console.log('new User')}}const user = new User()

new Promise(resolve= > console.log('promise'))

Array.from('foo')
Copy the code

Restore webpack. Config. Js

module.exports = {
  entry: './src/index.js'
}
Copy the code

Modify. Babelrc

{
  "presets": [["@babel/preset-env", { "useBuiltIns": "usage"}}]]Copy the code

After yarn build, we found that the size of our code became very small!

@ Babel/runtime and @ Babel/plugin – transform – runtime

  • babel-polyfillContaminates the global scope, as in importArray.prototype.includes– Modified the Array prototype, in addition to String…
  • babel-polyfillIntroduce new objects:Promise,WeakMap

That’s not what we want.

  • @babel/runtimeThe role of:
    • Extract the auxiliary function. For ES6 transcoding, Babel requires some helper functions, such as _extend. By default, Babel inlines these helper functions into every JS file. Babel provides transform-Runtime to “move” these helper functions into a separate modulebabel-runtimeThis reduces the size of the project file.
    • providepolyfill: does not pollute the global scope, but instance methods such as array.includes are not supported
  • @transform-runtimeThe role of:
    • babel-runtimeIt’s more like scatteredpolyfillModules need to be imported separately in their own modules. Use the Transform-Runtime plugin to automate this, which means you don’t import related modules at the beginning of the filepolyfill, you just use,transform-runtimeWill help you introduce.
yarn add  @babel/runtime-corejs2
yarn add @babel/plugin-transform-runtime -D
Copy the code

Modify. Babelrc

{
  "presets": ["@babel/preset-env"]."plugins": [["@babel/plugin-transform-runtime", { "corejs": 2}}]]Copy the code

Index. js removes import ‘@babel/polyfill’

@babel/plugin-proposal-decorators

Added support for decorator patterns

yarn add @babel/plugin-proposal-decorators -D
Copy the code

index.js

function annotation(target) {
  target.annotated = true
}

@annotation
class User {
  constructor() {
    console.log('new User')}}/ /...
Copy the code

.babelrc

{
  "presets": ["@babel/preset-env"]."plugins": [["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }],
    ["@babel/plugin-transform-runtime", { "corejs": 2}}]]Copy the code

At the end

  • The code address generated by this article