Babel的理解、用途及配置

168 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

在webpack中编写javascript代码,可以使用最新的ES语法,而最终打包的时候,
webpack会借助babel将ES6+语法转换成在目标浏览器可执行的ES5语法

什么是Babel

Babel是javascript的编译器,通过Babel可以将最新ES语法的代码轻松转换成任意版本的javascript语法。
随着浏览器逐步支持ES标准,我们不需要改变代码,只需要修改Babel配置就可以适配新的浏览器。

Babel配置文件

Babel会在正在被转义的文件当前目录中查找一个.babelrc文件。
如果不存在,它会项外层目录遍历目录树,直到找到一个.babelrc文件,或一个有‘babel’:{}的package.json文件。
修改index.js入口文件,添加ES6+的语法内容:
index.js:

const arr=[new Promise(()=>{}),new Promise(()=>{})];  
arr.map((item)=>{
console.log(item);
})

使用Babel生态处理ES6+语法

安装一下Babel相关依赖:
npm i babel-loader @babel/core @babel/preset-env -D
babel-loader是webpack与babel的通信桥梁,不会把es6语法转换成es5,
这部分工作由@babel/preset-env来完成。

修改webpack.config.js文件,对.js格式文件匹配:

{
   test:/\.js$/,  
   exclude:/node-modules/,  
   use:{
     loader:'babel-loader',  
     options:{
       presets:['@babel/preset-env']
     }
   }
}

执行 npx webpack启动构建,这里不推荐使用devServer,因为这样看不到本地的bundle文件。

被Babel处理后的bundle文件:
index.js:

eval("//...")

语法会发生了转换,但是还不够,在ES5中,有些对象、方法实际在浏览器中可能是不支持的,
例如:Promise、Array.prototype.icludes,这时候就需要用@babel/polyfill来做模拟处理。
@babel/polyfill使用方法是先安装依赖,然后在对应的文件内显性的引入:
安装: npm i @babel/polyfill
这里因为代码中引入了polyfill,所以不再是开发依赖(--save-dev,-D)

在文件内直接import或者require:

import '@babel/polyfill';

以上来看,问题似乎是解决了,polyfill引入后,补全了低版本浏览器缺失特性,
但是打包后会发现,bundle体积大了很多,
这是因为polyfill会把所有特性一次性引入导致的。
解决这个问题需要按需加载,就是用到哪个新特性,polyfill就引入哪个。
useBuiltIns选项是babel7的新功能,这个选项的功能是告诉babel如何配置@babel/polyfill。
它有以下3个参数可使用:

  1. entry:需要在webpack的入口文件里import '@babel/polyfill'一次。babel会根据用户的使用情况导入垫片,没有使用的功能不会被导入相应的垫片。
  2. usage:不需要import,全自动检测,但是要安装@babel/polyfill
  3. false: 如果用户import '@babel/polyfill',它不会排除掉没有使用的垫片,程序体积会变庞大。(不推荐)

使用babel配置文件

在项目根目录下创建.babelrc文件,
把webpack.config.js中babel相关的options选项里挪到新文件就可以,这样可以减少webpack.config.js文件的体积。
.babelrc:

{ 
    presets:[
      [
        '@babel/preset-env',
        {
          targets:{
              edge:'17',
              firefox:'60'
          },
        corejs:2,
        useBuiltIns:'usage'
        }
     ]
  ]
}

webpack.config.js:

{
   test:/\.js$/,  
   exclude:/node-modules/, 
   loader:'babel-loader',  
}