记录一次babel配置引发的问题

341 阅读3分钟

背景

之前接触过babel,也是一知半解,在写umd插件的过程中,发现在chrome 78版本中报错了,整个插件没加载出来,控制台发现,chrome 78版本不能识别obj?.name这种写法。

去了Can i use查了结果如下:

截屏2023-02-27 下午2.36.41.png

确实识别不了....

库简介:写一个用在多个项目中的意见反馈弹窗,打包成umd的形式,希望项目能在多个环境下使用(react、vue等),rollup打包。

定位问题:旧版本浏览器无法识别js新语法,是babel的问题。

babel

我查看项目中babel的配置:

{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-typescript",
        "@babel/preset-react"
    ],
    "plugins":["babel-plugin-transform-scss"]
}

看不懂以上配置问题出在哪里?

恶补babel

babel是一种js编译工具,是将js新的语法、旧版本的浏览器不能识别的语法编译成浏览器可以识别的js语法。

babel是由@babel/corepluginpreset(预设)组成的,如果不配置任何插件和预设,babel不做任何事情。

@babel/core是babel最核心的库,作用是经过词法分析-语法分析-AST等过程将js解析成机器可以识别的语言,进行操作,然后通过generator库转成代码,返回(所以不配置插件和预设的话,babel经过一系列过程啥也没干,就返回了)。

preset是plugin的集合

预设和插件的作用是:告诉babel要按照什么样的规则编译js

几个重要的预设
  1. @babel/preset-env

是一个智能预设,具有最全的js插件的集合,可以根据配置项将高版本的js转换为旧版本浏览器可以识别的js。 如果用到的语法,preset-env没有的话,可以从官网查找,引入。

// 常用配置

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                    "browsers": [
                        "firefox >= 70",
                        "chrome >= 70"
                    ]
                }
            }
        ],
        "@babel/preset-typescript",
        "@babel/preset-react"
    ],
    "plugins":["babel-plugin-transform-scss"]
}

@babel/preset-env配置项

1.没有任何配置的情况下:会根据package.json下的browserList中的配置,引入相应浏览器需要的插件进行转换

2.targets表示按照目标配置项,引入相应的插件,比如chrome >= 70,只需要引入70版本需要的插件,70版本浏览器已经可以识别箭头函数,这里就不需要引入编译箭头函数的插件。

3.还有一个关于polyfill的配置项,将在下面介绍

  1. @babel/preset-react

编译jsx语法的预设

  1. @babel/preset-typescript

编译ts语法的预设

也可以用tsc

关于polyfill

以上,我们已经可以根据自己的需要让babel帮我们将js语法编译成所需浏览器可以识别的内容。

但是!!!

js新内容分为两部分:

1.语法部分 (解构、.?用法)

2.api 实例方法、静态方法 (Promise、Array.from Function.prototype.includes等)

关于api、实例方法、静态方法等,如果在我们的程序当中用到,babel/preset-env帮不了我们。

这个时候,就需要用到垫片--@babel/polyfill。

垫片:浏览器不能识别的东西,垫片帮我们加上去。

polyfill和runtime两种垫片实现方式

参考文章

上面这篇文章其实已经讲得很清楚了,polyfill和runtime是两种方式。

polyfill是在全局对象或者内置对象上加上我们想要的方法和属性,会污染全局环境,可以用在我们的项目当中。

runtime不会污染全局环境,一般用在库环境当中。

总结

写不动了...

我的项目打包之后之所以不能识别?.语法,因为preset-env没有任何配置,这个时候babel会找到package.json中的browserList,根据它来配置,这个配置里面写着'last 1 versions'。

破案了...