美文网首页
2021-04-14 --- 由promise.finally(

2021-04-14 --- 由promise.finally(

作者: jeff_nz | 来源:发表于2021-04-14 16:51 被阅读0次

    问题记录:

    1. 项目在产线中出现问题,定位问题后发现,是promise.finally() 报错is not a function导致。
    2. 问题只有部分人员出现

    定位过程:

    1. 保证代码逻辑没有错误,定位出问题的浏览器,发现都是chrome版本较低的浏览器会报错,大概在60~61版本。
    2. 去MDN查看promise.finally的定义和支持情况,发现是ES7中引入,对chrome浏览器的支持度是83以上。
    3. 到此问题已经定位,但是为什么我们的babel没有polyfill这段代码呢? 因为对babel一直不太熟悉,正好借助这个问题,熟悉一下babel的相关知识点。

    一直对babel的概念都停留在它可以自动polyfill新语法的js用来支持老旧浏览器,但是具体的配置情况到底如何,如何识别新语法的js等原理都不甚了解。由于是编译工具,在此只做了解,不做深入学习。

    基本用法:

    在项目的根目录下创建一个命名为 babel.config.json 的配置文件(需要 v7.8.0 或更高版本),并将以下内容复制到此文件中:

    const presets = [
      [
        "@babel/env",
        {
          targets: {
            edge: "17",
            firefox: "60",
            chrome: "67",
            safari: "11.1",
          },
          useBuiltIns: "usage",
          corejs: "3.6.4",
        },
      ],
    ];
    
    module.exports = { presets };
    

    babel,主要作用是为了兼容浏览器,让你在爽快的使用新特性的同时,不用担心浏览器的兼容问题。 由于项目中使用的是vue-cli生成的脚手架,在使用过程中主要参考vue-cli对babel的配置。

    browserslist

    @babel/preset-envAutoprefixer 会根据browserlist中的配置来匹配对应的浏览器。

    "browserlist":[
      "> 1%",
     "last 2 versions",
     "not ie <= 8"
    ]
    

    一个默认的 Vue CLI 项目会使用 @vue/babel-preset-app,它通过 @babel/preset-envbrowserslist 配置来决定项目需要的 polyfill。
    默认情况下,它会把 useBuiltIns: 'usage' 传递给 @babel/preset-env,这样它会根据源代码中出现的语言特性自动检测需要的 polyfill。这确保了最终包里 polyfill 数量的最小化。然而,这也意味着如果其中一个依赖需要特殊的 polyfill,默认情况下 Babel 无法将其检测出来
    如果有依赖需要 polyfill,你有几种选择:

    1. 如果该依赖基于一个目标环境不支持的 ES 版本撰写: 将其添加到 vue.config.js 中的 transpileDependencies 选项。这会为该依赖同时开启语法转换和根据使用情况检测 polyfill。

    2. 如果该依赖交付了 ES5 代码并显式地列出了需要的 polyfill: 你可以使用 @vue/babel-preset-apppolyfills 选项预包含所需要的 polyfill。注意 es.promise 将被默认包含,因为现在的库依赖 Promise 是非常普遍的。

    3. 如果该依赖交付 ES5 代码,但使用了 ES6+ 特性且没有显式地列出需要的 polyfill (例如 Vuetify):请使用 useBuiltIns: 'entry' 然后在入口文件添加 import 'core-js/stable'; import 'regenerator-runtime/runtime';。这会根据 browserslist 目标导入所有 polyfill,这样你就不用再担心依赖的 polyfill 问题了,但是因为包含了一些没有用到的 polyfill 所以最终的包大小可能会增加。

    babel 实际上使用各种插件来进行polyfill的转换,例如@babel/plugin-transform-arror-functions就是用来转义箭头函数。在整个项目中可能存在很多需要转换的特性,这时候可以直接使用babel的一个preset来进行设置。@babel/preset-env。 在使用vue-cli生成的项目中,默认使用了vue的preset,‘@vue/app’.

    preset 中的useBuiltIns

    该属性有3个参数:

    1. usage:也就是只包含你所需要的 polyfill,Babel 将检查你的所有代码,以便查找目标环境中缺失的功能,然后只把必须的 polyfill 包含进来。示例代码如下:
    Promise.resolve().finally();
    

    会被转换为

    require("core-js/modules/es.promise.finally");
    
    Promise.resolve().finally();
    
    1. entry
      根据配置的浏览器兼容,引入浏览器不兼容的 polyfill。需要在入口文件手动添加 import '@babel/polyfill',会自动根据 browserslist 替换成浏览器不兼容的所有 polyfill。
    2. false
      此时不对 polyfill 做操作。如果引入 @babel/polyfill,则无视配置的浏览器兼容,引入所有的 polyfill。

    相关文章

      网友评论

          本文标题:2021-04-14 --- 由promise.finally(

          本文链接:https://www.haomeiwen.com/subject/fyyxlltx.html