babel详解

Posted on 2020-12-28 14:22  过鹿人  阅读(533)  评论(0)    收藏  举报
1.babel的由来
由于不同版本的浏览器能识别的ES标准不相同,就导致了开发者面对不同版本、不同内核的浏览器要使用不同的js语句,为了解决这样的问题,就有了babel,它可以把基于不同es标准书写的js语法,编译为统一的、能被各种浏览器识别的js语法。
 
2.babel的使用
babel本身仅提供一些语法分析功能,真正的语法转换还需要依赖插件和预设。
使用babel可以配合webpack等构建工具使用,或者独立使用,独立使用需要安装@babel/core @babel/cli这两个库,

@babel/core是babel核心库,提供了编译所需的所有api
@babel/cli是一个命令行工具,用来调用核心库的api完成编译
 
3.babel预设
`@babel/preset-env`提供了插件(plugins配置)的集合,无需针对每种语法转换(例如解构语法 箭头函数语法)设置具体的插件
babelrc文件的配置示例:
{
    "presets": [
        ["@babel/preset-env", {
            "配置项1": "配置值",
            "配置项2": "配置值",
            "配置项3": "配置值"
        }]
    ]
}
其中一个比较常见的配置项是`usebuiltins`,该配置的默认值是false
它的作用是仅转换新的语法,并不对新的API进行任何处理,例如:代码中使用了Promise,遇到没有Promise构造函数的旧版本浏览器,该代码就会报错,而处理新的api需要借助polyfill实现,下文会展开介绍。
通常情况下,`@babel/preset-env`只转换那些已经形成正式标准的语法,对于某些处于早期阶段、还没有确定的语法不做转换。

如果要转换这些不确定的语法,就要单独使用插件
例如:`@babel/plugin-proposal-class-properties`该插件可以让你在类中书写初始化字段
class A {
    a = 1;
    constructor(){
        this.b = 3;
    }
}
`@babel/preset-env`需要根据兼容的浏览器范围来确定如何编译,可以使用文件`.browserslistrc`或者package.json文件来描述浏览器的兼容范围
(1)该工程项目的 package.json 里面增加如下配置:
{
  "browserslist": [
    "last 1 version",
    "> 1%",
    "maintained node versions",
    "not dead"
  ]
}

 

(2)该工程项目的根目录下创建文件.browserslistrc

# 注释是这样写的,以#号开头
last 1 version
> 1%
maintained node versions
not dead

 

4.在webpack中使用babel

module.exports = {
    module: {
        rules: [
            { test: /\.js$/, use: "babel-loader" }
        ]
    }
}

5.babel-polyfill

babel-polyfill是什么?

polyfill:把高级api(Array.of Promise Symbol等)转换成各种浏览器都识别的js语句的一个工具

core-js库:提供了多个常用的polyfill的集合

regenerator库:提供了generators的polyfill

而babel-polyfill是core-js和regenerator的集合

注:bebel7.4之后已弃用babel-polyfill,推荐使用core-js和regenerator

 

 项目中若使用了babel-polyfill,还需要在.babelrc文件配置`usebuiltins`,

它的值默认为`false`,表示无视配置的浏览器兼容,引入所有的 polyfill

将其设置为`usage`,表示根据API的使用情况,按需导入API。
将其设置为`entry`,需要在入口文件手动添加 import '@babel/polyfill',会自动根据 browserslist 替换成浏览器不兼容的所有 polyfill
通常情况下 都使用usage配置
 
{
    "presets": [
        ["@babel/preset-env", {
            "useBuiltIns": "usage",
            "corejs": 3,
        }]
    ]
} 

6. babel-runtime

babel-polyfill的问题:
会污染全局环境
例如:
Promise会编译成全局window上的方法
数组的方法Array.of会编译成Array.prototype上的方法
 
解决方案:使用babel-runtime
需要在.babelrc文件中配置插件@babel/plugin-transform-runtime
{
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": false,
        "helpers": true,
        "regenerator": true,
        "version": "7.0.0-beta.0"
      }
    ]
  ]
}

 

 这样编译出来的api并不会保留书写时的名称 所以就不会污染到全局环境
 

博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3