什么是Babel?preset与polyfill区别?

babel本身是一个空壳,它只是一个流程工具,它之所以可以将ES6转换成ES5语法,是每个plugin起的作用,而所需要的plugin太多的话,难以记住,所以采取preset预设方案,preset就是把许多plugin重新打一个包取一个名字,比如preset-env,preset-flow,preset-react,preset-typescript, preset-env就包含了很多转换ES6语法的plugin,如果不够用的话还可以配置单独的plugin Babel 配置文件 .babelrc 是做什么的? 回答:.babelrc 是 Babel 的配置文件,用于定义 Babel 的插件、预设以及其他编译选项。一般来说,它放置在项目的根目录下。 Presets顾名思义预设。 我们要转换一些语法就得使用各种插件,并且添加到配置文件,如果每次项目需要的babel插件都差不多,而我们每次都要进行重复的下载,配置工作,这样效率是不是很低,很繁琐。 这个时候我们就可以利用presets这个功能,将一些常用的babel插件,配置放入预设中,下载直接将这个预设放入配置文件即可 将其设为预设后下次在.babelrc文件配置即可 { "presets": ["@babel/preset-env"], "plugins": ["@babel/plugin-transform-runtime"]} presets 是一组插件集合,指定代码的转换目标(如 ES6+ 到 ES5)。 plugins 则是特定功能的转换器,比如 @babel/plugin-transform-runtime 可以减少编译时的冗余代码。 当然除了我们自定义预设,我们还可以使用别人定义好的一些预设,如你经常看到的 @babel/preset-env、@babel/preset-react 什么是 Babel Preset?常用的有哪些? 回答:Babel Preset 是一组 Babel 插件的集合,适用于特定的转换需求。常用的 Preset 有: @babel/preset-env:根据目标环境自动选择需要的转换插件。 @babel/preset-react:支持 React 的 JSX 语法转换。 @babel/preset-typescript:将 TypeScript 编译为 JavaScript。 通过这些预设,可以轻松实现不同场景的编译需求。 @babel/preset-env 是如何工作的? 回答:@babel/preset-env 会自动判断目标环境(比如浏览器版本、Node.js 版本等)是否支持特定的 JavaScript 特性。如果不支持,preset-env 会启用相应的插件,将代码转换为目标环境可以执行的形式。 配置示例: { "presets": [ [ "@babel/preset-env", { "targets": "> 0.25%, not dead", "useBuiltIns": "usage", "corejs": 3 } ] ] } targets:定义支持的环境。 useBuiltIns:usage 表示只添加代码中用到的 polyfill。 corejs:指定 Core-JS 版本,以引入更全面的 polyfill。 Babel Polyfill 是什么?什么时候需要它? 回答:Babel Polyfill 用于填补现代 JavaScript 环境中的缺失功能,比如 Promise、Array.from 等 API。需要 Polyfill 的情况包括: 旧浏览器或环境不支持某些新的 JavaScript API。 项目需要支持更老的 JavaScript 运行环境,但代码中使用了不兼容的 API。 在使用 @babel/preset-env 时,可以通过配置 useBuiltIns: "usage" 来自动引入必要的 Polyfill。 由于babel只能将es6+语法转换为低级语法,而当我们使用一些高级特性时比如 async、await类似的Api,babel就显得无能为力了,因为babel无法实现这些高级Api的功能,这个时候就需要一个垫片(polyfill),而babel又包含了一个polyfill叫@babel/polyfill这个polyfill本身也无法实现像async等高级API的功能,但是市面上有现成的封装好的类库实现了,于是@babel/polyfill将他们包含进来。这样当我们引入@babel/polyfill时,就可以丝滑的写高级语法了! Babel 插件是如何工作的?有哪些常用插件? 回答:Babel 插件是一个独立的转换工具,用于处理 JavaScript 的特定功能或语法。每个插件负责特定的转换,例如: @babel/plugin-transform-arrow-functions:将箭头函数转换为普通函数。 @babel/plugin-transform-async-to-generator:将 async/await 语法转换为生成器函数。 @babel/plugin-proposal-class-properties:支持类的属性定义(类字段)语法。 通过插件可以灵活控制代码转换,满足特定的编译需求。 如何在项目中结合 Webpack 使用 Babel? 回答:在 Webpack 项目中使用 Babel 时,通常需要安装 babel-loader 以进行 Babel 和 Webpack 的集成。配置如下: module.exports = { module: { rules: [ { test: /.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } } ] }}; 这样 Webpack 会在编译过程中调用 Babel,对 .js 文件进行处理。需要注意的是,还需要安装 .babelrc 中定义的预设和插件。 如何在项目中结合 Webpack 使用 Babel? babel-parse / babel-traverse 回答:在 Webpack 项目中使用 Babel 时,通常需要安装 babel-loader 以进行 Babel 和 Webpack 的集成。配置如下: module.exports = { module: { rules: [ { test: /.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } } ] }}; 这样 Webpack 会在编译过程中调用 Babel,对 .js 文件进行处理。需要注意的是,还需要安装 .babelrc 中定义的预设和插件。 什么是 Babel Runtime?如何减少冗余代码? 回答:Babel Runtime 是一个独立的辅助库,提供常用的工具函数,如 _extends、_asyncToGenerator 等,避免在每个文件中重复生成冗余代码。可以通过 @babel/plugin-transform-runtime 插件引入 Runtime。 配置示例: { "plugins": ["@babel/plugin-transform-runtime"]} 如何使用 Babel 编译 TypeScript? 要用 Babel 编译 TypeScript 代码,可以使用 @babel/preset-typescript 预设。在 .babelrc 中加入如下配置: { "presets": ["@babel/preset-env", "@babel/preset-typescript"]} 如何通过 Babel 支持 ECMAScript 新提案? 回答:Babel 的插件系统支持最新的 JavaScript 提案,例如: @babel/plugin-proposal-optional-chaining:可选链 ?. @babel/plugin-proposal-nullish-coalescing-operator:空值合并操作符 ?? 可以在 .babelrc 中加入这些插件,来使用尚未完全成为标准的新特性。 Babel 如何支持 React JSX 语法? 回答:Babel 使用 @babel/preset-react 预设来编译 JSX 语法,使得 React 组件代码可以直接在浏览器中执行。配置示例如下: { "presets": ["@babel/preset-env", "@babel/preset-react"]} 通过这个预设,Babel 会将 JSX 转换为 React.createElement,使 JSX 代码在 React 项目中正常运行。

补充

补充:

  • Babel 只做 语法层 的转换(syntax transform),对于 Promise、Array.from、Symbol 等 新增的内建对象 / API 必须通过 polyfill(垫片)来补齐,@babel/preset-env 配合 useBuiltIns: "usage" 可自动按需注入 core-js 垫片。
  • @babel/polyfill 已被官方废弃(自 Babel 7.4 起),请改用 core-js/stable + regenerator-runtime/runtime。
  • 配置文件三选一:.babelrc(项目内)、babel.config.js(项目根)、package.json 的 babel 字段。优先用 babel.config.js 以便在 monorepo 中集中管理。
  • 升级工具链:用 @swc/core 或 esbuild 替代 Babel 可获得 10x+ 速度提升,但仍需 Babel 处理部分非标准提案时使用。

来源整理自:我的有道云笔记