美文网首页让前端飞
webpack4入门学习笔记(三)--Babel的使用

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

作者: qfstudy | 来源:发表于2019-04-24 08:48 被阅读0次

    系列博客链接

    代码

    下载代码(demo3):github

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


    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语法了。

    下一篇:webpack4入门学习笔记(四)--Tree Shaking与拆分配置文件

    相关文章

      网友评论

        本文标题:webpack4入门学习笔记(三)--Babel的使用

        本文链接:https://www.haomeiwen.com/subject/yhqwgqtx.html