js兼容性

113 阅读2分钟

存在的问题

不同版本的浏览器能识别的ES标准并不相同,导致开发者面对不同版本的浏览器要使用不同的语言

babel

概念

Babel 是一个 JavaScript 编译器,可以把不同标准书写的语言,编译为统一的,能被各种浏览器识别的语言

由于语言转换工作灵活多样,babel的做法和postcss、webpack差不多,本身仅提供一些分析功能,真正的转换需要依托于插件完成

使用和配置

babel可以和构建工具联合使用,也可以独立使用

如果要独立使用,需要安装下面两个库

npm i @babel/core @babel/cli

使用

babel 要编译的文件 -o 编译结果文件
babel 要编译的目录 -o 编译结果目录

配置

babel本身没有做任何事情,真正的编译要依托于babel插件和babel预设来完成

如何告诉babel要使用哪些插件或预设呢,需要通过一个配置文件.babelrc

// .babelrc
{
    "preset":[],
    "plugins":[]
}

预设

预设是一个多个插件的集合体,用于解决一系列的常见的兼容问题

babel有多种预设,最常见的预设是@babel/preset-env

@babel/preset-env可以让你使用最新的js语法,而无需针对每种语法转换设置具体插件

配置

// .babelrc
{
    "preset":["@babel/preset-env"]
}

@babel/preset-env会根据需要兼容的浏览器范围来确定如何编译,和postcss一样,可以使用.browserslistrc来描述浏览器的兼容范围

// .browserslistrc
last 3 versions
>1%
not ie<=8

@babel/preset-env自身有一些配置

预设只转换新语法,不对新的api进行任何的处理,所以需要配置useBuiltIns,它的默认值是false,表明不注入任何新的api,配置"useUbiltIns":"usage"后,会在编译碰到新的api时,从cors-js中引入新的api(core-js实现了所有的新的api),所以需要npm i core-js,碰到部分新的语法先编译成新的api,再继续编译实现的(async await),需要借助reganerator-runtime来处理。

// .babelrc
{
    "preset":[
        ["@babel/preset-env",{
            "useBuiltIns":"usage",
            "corejs":3, //默认值2,设置useBuiltIns后不设置corejs,corejs版本下载的是3的,会报错
        
        }]
    ]
}

插件

预设只转换正式标准,其他非正式标准的语法需要编译则通过插件来完成

预设和插件的执行顺序

  1. 先执行插件(从左到右)
  2. 后执行预设(从右到左)
{
    "preset":["a","b"],
    "plugins":["c","d"]
}

执行顺序:c---->d--->b---->a

在webpack中使用babel

安装

npm i babel-loader @babel/core

配置loader

// webpack.config.js
module.exports={
    module:{
        rules:[
            {
                test:/\.js$/,
                exclude:/node_modules/,
                use:["babel-loader"]
            }
        ]
    }
}
//.babelrc
{
    "presets": [["@babel/preset-env",{
        "useBuiltIns":"usage",
        "corejs":3
    }]]
}

配置需要兼容的浏览器范围

//.browserslistrc
last 3 versions
>1%
not ie<=8