webpack4入门学习笔记三Babel的使用

34次阅读

共计 3941 个字符,预计需要花费 10 分钟才能阅读完成。

系列博客链接

  • webpack4 入门学习笔记(一)
  • webpack4 入门学习笔记(二)
  • webpack4 入门学习笔记(三)–Babel 的使用

代码

下载代码(demo3):github

本文的代码是在前面笔记基础上修改的,可以下载代码:githubl 参考或是先看前面的笔记。


Babel 是一个广泛使用的转码器,可以将 ES6 代码转为 ES5 代码,从而在现有环境执行。

Babel 总共分为三个阶段:解析(parse),转换(transform),生成(generate)。

Babel 本身不具有任何转化功能,它把转化的功能都分解到一个个 plugin 里面。因此当我们不配置任何插件时,经过 Babel 输出的代码和输入是相同的。

Babel 插件的使用

  1. 将插件的名字增加到配置文件中: 项目根目录下创建 .babelrc 配置文件或是 webapck.config.js 中配置,一般都是在 .babelrc 中配置。
  2. 使用 npm install xxx 进行安装

Babel 的配置文件是.babelrc,存放在项目的根目录下。使用 Babel 的第一步,就是配置这个文件。

该文件用来设置转码规则和插件,基本格式如下。

{"presets": [],
  "plugins": []}

Babel 简单介绍

preset

preset(预设)就是一系列插件的集合
@babel/preset-env 包含所有 ES6 转译为 ES5 的插件集合

core-js

转换一些内置类 (Promise, Symbols 等等) 和静态方法(Array.from 等)。

@babel/core

是作为 Babel 的核心存在,Babel 的核心 api 都在这个模块里面。

babel-loader

babel-loader在 webpack 中使用,是 webpack 和 Babel 之间的通讯桥梁

@babel/polyfill 介绍

@babel/preset-env默认只转译 js 语法,而不转译新的 API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法 (比如Object.assign) 都不会转译。这时就必须使用 @babel/polyfill(内部集成了core-jsregenerator)。

使用时,在所有代码运行之前增加import "@babel/polyfill"

或者是在 webpack.config.js 入口配置

module.exports = {entry: ["@babel/polyfill", "./app/js"],
}

因此必须把 @babel/polyfill 作为 dependencies 而不是devDependencies

@babel/polyfill 主要有两个缺点:

1. 使用 @babel/polyfill 需要做些额外配置,实现打包的时候按需引入,否则会把 @babel/polyfill 全部注入代码中会导致打出来的包非常大。

2.@babel/polyfill会污染全局变量。

Babel7的一个重大变化就是 npm package 名称的变化,把所有babel-* 重命名为@babel/*,例如:

  • babel-polyfill重命名为@babel/polyfill
  • babel-preset-env重命名为@babel/preset-env

Babel 在 webpack 中的用法

首先实现对 ES6 语法的转译

安装babel-loader、@babel/core、@babel/preset-env

  • npm i babel-loader -D
  • npm i @babel/core -D
  • npm i @babel/preset-env -D

babel-loader@8需要安装 @babel/core7.x 版本。

在 webpack.config.js 配置

module.exports={
  module: {
    rules:[
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use:{
          loader: 'babel-loader',         
          options:{
            presets: [
              ["@babel/preset-env",{
                //targets:表示编译出的代码想要支持的浏览器版本
                targets: {chrome: "67"}
              }]
            ]
          }
        }
      }
    ]
  }
}

执行 npm run buildnpx webpack就可以看到 dist 目录下的打包文件,但是只是将 ES6 的语法进行转译,并没有对 ES6 新 API 进行转译,所以我们需要配置 @babel/polyfill 解决这个问题。

安装@babel/polyfill
npm i @babel/polyfill --save

index.js 中引入@babel/polyfill

index.js

//index.js

import '@babel/polyfill'

let arr=[new Promise(()=>{}),
  new Promise(()=>{}),
  2
]

arr.map((item)=>{console.log(item)
})

引入 @babel/polyfill 前,main.js 的大小为 29.5KB

引入 @babel/polyfill 后,main.js 的大小为 1MB

注意:以上对比都是在没有 targets 这个选项的情况下,因为有些浏览器几乎都支持 ES6,在这种情况下,@babel/preset-env将不会对代码进行处理。

这是因为把 @babel/polyfill 对所有 API 的实现都注入到打包文件中,但是里面很多的 API 我们在代码中并没有用到,所以需要修改配置,按需引入对应的 API。

修改 webpack.config.js 配置

添加 "useBuiltIns": "usage" 以后,需要安装 core-js@2,并且添加"corejs": 2 配置项,这时配置选项比较多,需要在项目根目录下新建 .babelrc 文件,在这个文件中配置。

.babelrc配置如下:

  • "useBuiltIns"属性值为 "usage" 时,会自动引入@babel/polyfill,必须保证已经安装了@babel/polyfill
  • "useBuiltIns"属性值为 "usage" 时,需要添加 "corejs": 2 配置项,否则报错,需要安装core-js

首先删掉 index.js 中的import '@babel/polyfill'

安装 core-js
npm i --save core-js@2npm i --save core-js@3

{
  "presets": [["@babel/preset-env",{
    "useBuiltIns": "usage", // 不需要把 polly 都打包到代码中,根据代码按需转译
    // core-js@3和 core-js@2二选一
    //"corejs": 3,  //npm i --save core-js@3
    "corejs": 2  //npm i --save core-js@2
  }]]
}

修改 webpack.config.js,删除options 对象

module.exports={
  module: {
    rules:[
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  }
}

执行npm run build,打包后的文件大小为165KB

但是,在开发类库或是第三方模块时不适合使用 @babel/polyfill,所以接下来使用@babel/plugin-transform-runtime 来解决这个问题。

@babel/plugin-transform-runtime、@babel/runtime 和 @babel/runtime-corejs2 的用法

@babel/runtime-corejs2:是一个包含 Babel modular runtime helpersregenerator-runtime以及 core-js 的库。

@babel/runtime:是一个包含 Babel modular runtime helpersregenerator-runtime的库。

在配置项中 corejs 属性值为默认为 false,如果需要将PromiseAPI进行转译,则需要设置属性值为 2 时,并且安装@babel/runtime-corejs2

安装:

  • npm i @babel /plugin-transform-runtime -D
  • npm i --save @babel/runtime
  • npm i --save @babel/runtime-corejs2

修改.babelrc 文件

{
  "plugins": [
    ["@babel/plugin-transform-runtime",{
      "helpers": true,
      "regenerator": true,
      "useESModules": false,
      "corejs": 2
    }]
  ]
}

我们把 presets 配置项去掉了,然后 npm run build 打包,打开打包后的 main.js 查看,虽然把转译了 Promise,但是 ES6 新语法并没被转译,例如:let 没有被转译为var

所以还是需要配置 presets,因为"@babel/preset-env" 包含了对所有 ES6 语法转译为 ES5 插件。

再次修改.babelrc 文件

{"presets": ["@babel/preset-env"],
  "plugins": [
    ["@babel/plugin-transform-runtime",{
      "helpers": true,
      "regenerator": true,
      "useESModules": false,
      "corejs": 2
    }]
  ]
}

添加 presets 配置项,然后 npm run build 打包,打开打包后的 main.js 查看,可以看到 let 和箭头函数都被转译为 ES5 语法了。

正文完
 0