babel 基本使用

169 阅读3分钟

初始化项目

mkdir babel && cd babel && npm init -y

安装babel-cli

pnpm i @babel/core @babel/cli -D  
  • 创建src目录并创建文件
    //src/test1.js
    const arr = [1, 2, 3];
    let [a, b, ...rest] = arr;
    
    

执行babel转换

npx babel src --out-dir dist

完美,dist目录的文件原封不动,并没有被转换!!

image.png

翻翻官网,Babel's code transformations are enabled by applying plugins (or presets) to your configuration file.(Babel的代码转换是通过对配置文件应用插件(或预置)来实现的。)

  • 创建babel.config.json
    {
        "plugins": [
            ["@babel/plugin-transform-block-scoping"],
            ["@babel/plugin-transform-destructuring",{ "useBuiltIns": true }]
        ]
    }

安装对应的plugin

pnpm i @babel/plugin-transform-block-scoping @babel/plugin-transform-destructuring -D

babel plugins列表

再次执行命令

image.png

Perfect!!,转换成功了 const 转换成了var ,数组的解构赋值也转换成功了,但是太麻烦了,这个配置要一个一个找plugin,不完美,所以babel提供了预设presets

安装@babel/preset-env 并配置

pnpm i @babel/preset-env -D

修改babel.config.json

{
    // "plugins": [
    //     ["@babel/plugin-transform-block-scoping"],
    //     ["@babel/plugin-transform-destructuring",{ "useBuiltIns": true }]
    // ]
    "presets": [
        [
          "@babel/preset-env"
        ]
      ]
}

再次执行命令,查看dist,也被转换了,这方便多了,之前转换的都是一些语法,我门转换一些新特性API(Iterator、Generator、Set、Maps)试试

const arr = [1,2,3]
let [a, b, ...rest] = arr;
const arr3 = Array.from('arrayLike')

WTF?? Array.from 并没有被转换 image.png

转换新特性API,babel6.X用的是babel-polyfill(7.x已经废弃),最新都使用core-js@3 版本,关于core-js@3

安装corejs 并继续配置@babel/preset-env

pnpm i core-js@3.27.1 -D    
{
    "presets": [
        [
          "@babel/preset-env",
          {
            "useBuiltIns":"usage",
            "corejs":"3.27.1"
          }
        ]
      ]
}

执行命令查看打包结果,需要的垫片通过require加载

image.png

关于browserslist

  1. 现在的babel、css 转换插件都可以根据 browserslist配置文件来生成兼容目标浏览器的代码
  2. 在线查看浏览器覆盖率
  3. 本地查看覆盖的浏览器
pnpm i browserslist -D 
npx browserslist

image.png 4. 相关资料 Speed up with Browserslist
接下来配置browserlist,直接在跟文件下创建.browserslistrc,什么都不写会默认不使用browserlist,defaults相当于[> 0.5%, last 2 versions, Firefox ESR, not dead]

在配置只配置defaults,继续打包,看到打包后的文件又不会转换了,证明目前使用的es6默认配置覆盖的浏览器是支持的,生产中有一些配置可以加上,比如ios版本的要求

//.browserslistrc
defaults
ios >= 7

再次打包,不支持的一些helper会再次加载进来

runtime

在测试文件里再加入一些async、promise

function sleep(m){
    return new Promise(resolve => {
        setTimeout(resolve,m * 1000,true)
    })
}

async function point(){
    console.log('start');
    await sleep(3)
    console.log('end')
}

point()

再次打包可以看到async 并不想其他es6一样直接require一个helper函数,而是直接注入的,这就有一个问题如果项目很多文件helper直接注入就会导致包很大,babel提供了解决方案@babel/plugin-transform-runtime

image.png

// 安装 @babel/plugin-transform-runtime
pnpm i @babel/plugin-transform-runtime -D
// @babel/runtime 要安装生产依赖
pnpm i @babel/runtime -S

// 修改babel配置文件
{
  "presets": [
    [
      "@babel/preset-env"
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",{
        "corejs":3
      }
    ]
  ]
}

image.png

打包后async的helper不是直接注入了,而且也不会直接require辅助函数到全局。这里需要注意的是corejs 在@babel/preset-env跟@babel/plugin-transform-runtime都可以配置,当使用babel/plugin-transform-runtime配置corejs后@babel/preset-env就不需要配置,可以试着分别设置corejs 查看打包产物

最后一个点

babel 打包出来的不能直接运行在浏览器,只能运行在node,运行浏览器需要借助webpack等打包工具把helper函数打包进生成的文件里