十问babel,用最简单的话说清楚babel(二)

简介: 十问babel,用最简单的话说清楚babel

如何配置@babel/polyfill 呢?

使用 preset-env 的 useBuiltIns 参数

  • false 不使用babel/polyfill
  • entry 在入口处手动引入 polyfill
import '@babel/polyfill''
import 'core-js/stable';
import 'regenerator-runtime/runtime';
  • 两个等效
  • Babel 就会根据我们配置需要支持的浏览器列表,将目标浏览器中不支持的 polyfill 进行全量引入并且转译
  • usage
  • ****仅仅会为我们引入目标浏览器中不支持并且我们在代码中使用到的内容,会剔除没有使用到的 polyfill 内容。

两种配置方案优缺点对比


1686899563696.png

entry 会引入全部的polyfill,导致代码体积大

usage 无法处理三方依赖包中的新的API

babel/polyfill的缺点

1686899626712.jpg

通过在线转译平台,转译这个 ES6 类的声明语句,我们发现在当前文件多了6个function

<www.babeljs.cn/repl

转译后,相同的方法会被重复定义

但是如果其他文件也使用了类声明语句,也会在当前文件生成类似的6个辅助函数function

如果我们能把相同的方法抽离出来,改成运行时引入,这样可以大大缩小代码体积

所以@babel/runtime 就时来解决这个重复定义的问题,会提前好在一个地方定义好这些通用方法,其他地方用大直接引用即可,这样可以缩小编译后的代码体积

babel/runtime 和 babel/plugin-transform-runtime 是什么关系?

babel 的 polyfill 机制是

对于例如 Array.from 等静态方法,直接在 global.Array 上添加;对于例如 includes 等实例方法,直接在 global.Array.prototype 上添加。

这样直接修改了全局变量的原型,有可能会带来意想不到的问题。这个问题在开发第三方库的时候尤其重要,因为我们开发的第三方库修改了全局变量,有可能和另一个也修改了全局变量的第三方库发生冲突,或者和使用我们的第三方库的使用者发生冲突。

公认的较好的编程范式中,也不鼓励直接修改全局变量、全局变量原型。

于此同时 ,babel-runtime无法做到智能化分析,需要我们手动引入。

为了解决这个问题,babel/plugin-transform-runtime 出现了

babel/plugin-transform-runtime 内部依赖了 babel/runtime

babel/plugin-transform-runtime 在babel/runtime的基础上解决了全局变量污染的问题,从一个统一的模块中引入,避免了对全局变量及其原型的污染。

@babel/plugin-transform-runtime插件会智能化的分析我们的项目中所使用到需要转译的js代码,从而实现模块化从babel-runtime中引入所需的polyfill实现。

最佳实践是什么?我到底该如何在项目中使用?

从来没有最佳,只有最适合的。

1686899693241.jpg

stackoverflow 有一条很好的回答我来翻译翻译

what-is-best-practice-for-babel-preset-env-usebuiltins-babel-runtime

stackoverflow.com/questions/6…

如果你是开发应用项目

建议在入口处引入polyfill, 并将 useBuiltIns 设置为entry

配合@babel/transform-runtime 作为依赖性

这样我们自己开发,可以接受全局环境被污染,也不用担心node_modules中有语法没有被转译,可以仅可能适应浏览器的环境

babel/plugin-transform-runtime

这个helpers参数开启后可以将上边提到编译阶段重复的工具函数提到公共部分

想当于只使用 babel/transform-runtime

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry",
        "debug": true
      }
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": 3
        // 默认为true 表示将这些工具函数抽离成为工具包引入而不必在每个模块中单独定义
        "helpers": true,
        // 切换生成器函数是否污染全局 
        // 为true时打包体积会稍微有些大 但生成器函数并不会污染全局作用域
        // 为false时体积小
        "regenerator": false,
      }
    ]
  ]
}

如果是开发类库

类库项目的构建如果需要注入 polyfill 的话,最好使用 @babel/transform-runtime,因为它提供了一种不污染全局作用域的方式。

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "debug": true
      }
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": 3
        "helpers": true,
      }
    ]
  ]
}

最后

这篇文章大量参考了19组清风的babel系列的内容

juejin.cn/column/7031…

看他的文章内容很多,很细,知识量太密集,研究很深入,看起来就有些费劲了。

我做了一些精简和理解,加上一些自己的理解和其他文章的积累,写成了此篇,希望对屏幕前的你有所帮助。

参考链接

juejin.cn/post/705135…www.cnblogs.com/qinyuandong…

zhuanlan.zhihu.com/p/58624930juejin.cn/post/703338…

相关文章
|
10月前
|
JavaScript 前端开发 编译器
分享:Babel7的配置
分享:Babel7的配置
221 0
|
9月前
|
自然语言处理 前端开发 JavaScript
Babel 的工作原理以及怎么写一个 Babel 插件
Babel 的工作原理以及怎么写一个 Babel 插件
132 0
|
5月前
|
编解码 前端开发
ES6学习(一)— Babel转码器的使用和配置
ES6学习(一)— Babel转码器的使用和配置
|
11月前
|
Web App开发 移动开发 JavaScript
十问babel,用最简单的话说清楚babel(一)
十问babel,用最简单的话说清楚babel
230 0
|
11月前
Babel6 如何升级 7 #60
Babel6 如何升级 7 #60
358 0
|
11月前
|
编解码
|
JSON 自然语言处理 JavaScript
浅谈babel原理
很早之前就听同事分享了babel原理,其核心就是 AST(Abstract Syntax Tree),今天将自己所了解的知识点简单整理记录一下。
|
缓存 JSON 自然语言处理
浅聊Vite
vite 是个啥? 推荐阅读指数 ⭐️⭐️⭐️ vite 打包阶段 推荐阅读指数 ⭐️⭐️⭐️⭐️⭐️ 打包阶段的插件执行顺序 推荐阅读指数 ⭐️⭐️⭐️⭐️⭐️ Vite+React的项目打包优化(简单版) 推荐阅读指数 ⭐️⭐️⭐️⭐️
850 0
|
缓存 Rust 前端开发
esbuild + swc 能有多快?
前端工具层出不穷,之前有常用的打包工具webpack,现在有了速度更快的vite。 vite的开发模式是基于esBuild编译的,打包又是基于rollup,启动项目是很快的。
655 0
esbuild + swc 能有多快?
|
JavaScript 前端开发 编译器
什么是 Babel?
什么是 Babel?
121 0
什么是 Babel?