zoukankan      html  css  js  c++  java
  • [转] 最近折腾 @babel/preset-env 的一些小心得

    近来厂里的项目越来越多,代码共享必不可少。我现在采取的方案是:

    1. 把公共组件拿出来,开一个新仓库
    2. 使用 webpack 进行打包编译,libraryTarget: 'umd'
    3. 将打包编译的代码一起提交到仓库
    4. 使用 npm i <owner>/<repo> -S 安装依赖,因为我厂的仓库均为私有,所以不能发布到 NPM

    这套方案简单好用,实操效果良好。接下来我希望优化打包结果,于是研究了打包配置项,下面是我的一点心得。

    @babel/preset-env

    首先,Babel 推荐使用 @babel/preset-env 套件来处理转译需求。顾名思义,preset 即“预制套件”,包含了各种可能用到的转译工具。之前的以年份为准的 preset 已经废弃了,现在统一用这个总包。

    同时,babel 已经放弃开发 stage-* 包,以后的转译组件都只会放进 preset-env 包里。

    browserslist

    @babel/preset-env 支持一些参数,用来处理哪些 feature 要转译,哪些不要。其中比较重要的是 targets,用来指定目标环境。targets 使用 browserslist 来筛选浏环境,这样我们就不需要指定所有浏览器版本,而可以使用类似 last 2 versions 这样的描述。具体怎写,可以看文档,这里不再赘述。

    如果你想知道自己配置的是否合适,可以在仓库目录下执行 npx browserslist,列出所有目标浏览器,比如:

    zhailujiadeiMac:fe meathill$ npx browserslist
    and_chr 73
    and_ff 66
    and_qq 1.2
    and_uc 11.8
    android 67
    android 4.4.3-4.4.4
    baidu 7.12
    chrome 73
    chrome 72
    edge 18
    edge 17
    firefox 66
    firefox 65
    ios_saf 12.2
    ios_saf 12.0-12.1
    kaios 2.5
    op_mini all
    op_mob 46
    op_mob 12.1
    opera 58
    opera 57
    safari 12.1
    safari 12
    samsung 9.2
    samsung 8.2
    Bash

    Babel 官方建议我们把 targets 写到 .browserslistrc 或者 package.json 里,这样其它工具也能更轻易的获取到目标浏览器。另外,npx browserslist 无法从 .babelrc 等 babel 配置文件里读取配置,所以执行的时候看到的会是默认结果。

    useBuiltIns

    接下来,我们可以配置 useBuiltIns,这个属性决定是否引入 polyfill。它有三个可选值,默认是 false,即不引入,或者说,Babel 编译结果不引入,把引入的位置、引入哪些 polyfill 交给用户处理。因为我们的页面中通常有大量的 JS,在每个文件里分别引用 polyfill 太浪费资源,所以可以在核心入口 JS 引用一次即可。

    但是这样我们必须手动 import '@babel/polyfill' 引入所有 polyfill,其实并不理想,因为大部分浏览器不需要这些。

    所以推荐用 useBuiltIns: 'usage' 即“按需引用”。虽然文档中标记为“experimental”,但我用起来也没遇到什么问题。如果目标浏览器不支持需要的 feature,那么就引入 polyfill,不然的话就不引用。由于目前的打包工具越发智能,随着 tree shaking 的完善,这样可以最低限度引入 polyfill。

    core-js

    core-js 目前最新版本是 3.0.1,关于 v3 和 v2 的对比,大家可以看这篇博文:https://github.com/zloirock/core-js/blob/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md。这里简单总结一下,core-js 2 封版于 1.5 年之前,所以里面只有对 1.5 年之前 feature 的 polyfill,最近 1.5 年新增的 feature 都不支持,也就存在因为新功能没有 polyfill 于是在旧浏览器里失败的风险。

    所以我们应当升级到最新版,npm i core-js@3 -D 然后修改 babel 配置:

    {
      "presets": [
        [
          "@babel/preset-env",
          {
            "targets": "> 5%",
            "useBuiltIns": "usage",
            "corejs": 3
          }
        ]
      ]
    }
    JSON

    注意,目前 Vue Cli 3 集成了 core-js 2,不支持升级到 v3,无法手动升级。需要等待 Vue Cli 4。

    @babel/polyfill

    @babel/polyfill 是对 core-js 的封装,引用了 core-js 的内容和生成器(regenerator-runtime)。 v7.4 之后,这个仓库就被废弃了,希望用户自己选择使用哪个兼容库。

    换言之,以前:

    import "@babel/polyfill";
    JavaScript

    需要被替换成

    import "core-js/stable";
    import "regenerator-runtime/runtime";
    JavaScript

    不过我不建议这么做。对于绝大部分情况,使用 @babel/preset-env + useBuiltIns: 'usage' 仍然是最好的选择。


    总结

    这些知识并不复杂,基本上文档里都有。不过一次性看大量英文文档可能对很多同学来说都是负担。我比较提倡这样学习:

    1. 遇到需求就去看一遍,不求全部理解,能解决目前的问题即可
    2. 重复这个过程,争取每次都比上一次理解更多
    3. 建立不同工具之间的逻辑体系,要求能够内恰
    4. 继续重复这个过程,知道确认自己理解了
    5. 通过看文档巩固
  • 相关阅读:
    常见的兼容问题
    css3新增伪类
    完美的js运动框架
    C++ 常用宏
    多线程代码段 自清理线程
    寒假自学(十一)
    寒假自学(十)
    寒假自学(九)
    寒假自学(八)
    寒假自学(七)
  • 原文地址:https://www.cnblogs.com/chris-oil/p/13940593.html
Copyright © 2011-2022 走看看