一文带你零基础认识Babel,Babel到底可以用来干嘛

一文带你零基础认识Babel,Babel到底可以用来干嘛Babel 是一个工具链 主要用于将采用 ECMAScript20 语法编写的代码转换为向后兼容的 JavaScript 语法 以便能够运行在当前和旧版本的浏览器或其他环境中

大家好,欢迎来到IT知识分享网。

目录

🌲 前言

🌲 Babel是什么?

🌲 Babel 的工作原理

◼️ 如何设置

◼️ Babel 有哪些值得注意的选项

◼️ @babel/core | @babel/cli | @babel/preset-env 到底做了哪些事情

🌲 Babel 的使用

◼️ 配置文件

◼️ Babel 配置文件的优先级

🌲 Plugins

如何使用插件

转换插件​

语法插件

插件顺序​

插件参数​

插件开发​

🌲 Presets

如何使用预设 

如何创建预设

预设的排列顺序​

预设的参数​

🌲 Polyfill

1、@babel/polyfill

2、babel-runtime

3、babel-plugin-transform-runtime

🎋 babel-runtime 和 babel-plugin-transform-runtime

🎋 使用技巧分享

🔆 参考文献

🔆 参考资料


一文带你零基础认识Babel,Babel到底可以用来干嘛

一文带你零基础认识Babel,Babel到底可以用来干嘛  

🌲 前言

在此之前或许你已经用过babel,也许听说过什么 babel-loader babel-core、babel-cli、babel-plugin-…、babel-preset-env。

反正各种乱七八糟的做项目随便用一下就可以了,对他只有个一知半解,甚至不知道他到底是干什么的,反正项目要用,照着用就行了,至少博主之前的状态是这样,如果只对他有个一知半解甚至都不了解,那么项目出bug了你都不知道怎么去调试,只能复制 –> 粘贴 –> 百度。基于此,写下自己对Babel的理解。Babel是什么?

🌲 Babel是什么?

我们在babel的官方网站找到这样一句话:

Babel is a JavaScript compiler | Babel 是一个 JavaScript 编译器

Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。下面列出的是 Babel 能为你做的事情: 

  • 语法转换
  • 通过 Polyfill 方式在目标环境中添加缺失的功能(通过引入第三方 polyfill 模块,例如 core-js)
  • 源码转换(codemods)
  • 更多参考资料!(请查看这些 视频 以获得启发)

Babel是一个编译器,针对JavaScript,为什么会有Babel这样一个工具的存在?

本文默认你对es6、es7等有所涉足,我们在写es6+语法的时候是不是很方便,什么promise、async await,可是es6+语法写的虽然很酸爽,但是浏览器他不兼容啊,你想想你写的代码在浏览器上跑不起来,再好的语法、再好的特性又有什么用?

这个时候Babel这样一个工具出来了,它可以将我们写的es6+语法转换为浏览器兼容的语法,比如将箭头函数转换为普通函数,有了这样一个工具我们就即可以写酸爽的语法,又可以让使浏览器兼容。相信到这你已经知道了Babel的概念,并且可以脑补出Babel可以干什么。

🌲 Babel 的工作原理

Babel 使用 AST 把不兼容的代码编译成 es5 版本,因为大多数浏览器都支持这个版本的 JavaScript 代码。

◼️ 如何设置

整个配置过程包括:

1. 在控制台运行如下命令安装所需的包(package):

npm方式

npm install --save-dev @babel/core @babel/cli @babel/preset-env

Yarn方式

yarn add --dev @babel/core @babel/cli @babel/preset-env

2. 应用程序的根目录会默认创建一个 babel.config.json 文件(需要 v7.8.0 或更高版本)。Babel 将遍历 src 目录下的所有 JS 文件。

{ "presets": [ [ "@babel/preset-env", { "targets": { "edge": "17", "firefox": "60", "chrome": "67", "safari": "11.1" }, "useBuiltIns": "usage", "corejs": "3.6.5" } ] ] }

上述浏览器列表仅用于示例。请根据你所需要支持的浏览器进行调整。参见 此处 以了解 @babel/preset-env 接受哪些参数。 

如果你使用的是 Babel 的旧版本,则文件名为 babel.config.js

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

package.json 文件我们也不陌生,可以直接通过 npm init 命令来创建。或者我们还可以将 .babelrc 或.babelrc.json 中的配置信息作为 babel 键(key)的值添加到 package.json 文件中,如下所示:

{ "name": "demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "babel": { "presets": [...], "plugins": [...] } }

当然我们除了将把配置写在上述这几种配置文件中,我们也可以写在构建工具的配置里。对于不同的构建工具,Babel 也提供了相应的配置项,例如 webpackbabel-loader 的配置项,其本质和配置文件是一样的。

配置文件中的主要配置项就是 pluginspresets 这两个数组,plugins为插件数组,presets 为预设数组。其他的例如 ignoreminified 等我们一般用不到。 

3. 运行此命令将 src 目录下的所有代码编译到 lib 目录:

./node_modules/.bin/babel src --out-dir lib

你可以利用 npm@5.2.0 所自带的 npm 包运行器将 ./node_modules/.bin/babel 命令缩短为 npx babel 

🎋 想要更详细的分步讲解,了解其工作原理以及每个工具的功能,可以参看:使用指南 · Babel 中文文档 | Babel中文网。 

◼️ Babel 有哪些值得注意的选项

{ "presets": [ [ "@babel/oreset-env", { "targets": { "edge": "17", "firefox": "60", "chrome": "67", "safari": "11.1" }, "useBuiltIns": "usage", "corejs": "3.6.5" } ] ], }
  • 如果要缩减输出代码,需要增加选项 "minified": true
  • 如果要忽略某些文件,则添加 ignore: ["file or directory path"]
  • 只编译特定的文件或文件夹,则添加如下代码:
// For Files "only" : ["./src/some_file.js"], // For Directory "only" : ["./src"], 

◼️ @babel/core | @babel/cli | @babel/preset-env 到底做了哪些事情

  • @babel/core:Babel 的所有核心功能都在这里
  • @babel/cli:提供了 CLI 工具,使我们能够运行 npm run build
  • @babel/preset-env:提供预置功能

🌲 Babel 的使用

  • 单体文件
  • 命令行
  • 配合Webpack使用

本文将介绍Babel配合webpack使用的情况

◼️ 配置文件

babel的配置文件常用的有几种:.babelrc,.babelrc.json、babelrc.js、babel.config.json、babel.config.js

以下是官网关于配置文件类型的介绍:Config Files

Configuration File Types | 配置文件类型

History

Version Changes
v7.21.0 Support .babelrc.cts and babel.config.cts (Experimental)
v7.8.0 Support .babelrc.mjs and babel.config.mjs
v7.7.0 Support .babelrc.json.babelrc.cjsbabel.config.jsonbabel.config.cjs
  • Project-wide configuration
    • babel.config.* files, with the following extensions: .json.js.cjs.mjs.cts.
  • File-relative configuration
    • .babelrc.* files, with the following extensions: .json.js.cjs.mjs.cts.
    • .babelrc file, with no extension.
    • package.json files, with a "babel" key.

大致翻译一下:

Babel 有两种并行的配置文件格式,可以一起使用,也可以分开使用。

◾ 项目范围的配置 ——全局配置

你是否采用的是单一仓库(monorepo)模式?你是否需要编译 node_modules

👉 根目录:babel.config.json会影响整个项目中的代码,包含node_modules中的代码

babel.config.* 文件,具有不同的拓展名(.json.js.cjs, .mjs.cts.)

babel.config.js 是按照 commonjs 导出对象,可以写js的逻辑。

相对文件的配置 ——局部配置

👉 项目中:babelrc 只会影响本项目中的代码

.babelrc.* 文件,具有不同的拓展名(.json.js.cjs, .mjs.cts.)

.babelrc 文件,不带扩展名

babel官方建议使用 babel.config.json 格式的配置文件。 Babel 自身使用的就是这种格式

🎋 配置文件的使用场景,更多详细信息:配置 Babel · Babel 中文文档 | Babel中文网

◼️ Babel 配置文件的优先级

从低到高依次为:

  • babel.config.json
  • babelrc.json
  • @babel/cli

依照优先级,babel.config.json 会被 .babelrc 覆盖,依次类推。

注意:.babelrc 文件放置在项目的根目录中时和 babel.config.js 效果一致,我们只需要选择一种创建即可。如果两种类型的配置文件都存在,.babelrc 会覆盖 babel.config.js 的配置。

理解 babel.config.js 和 babelrc

  • babel.config.js 或是babel.config.json当前项目维度 (Project Wide)的配置文件,相当于一份全局配置,如果 babel 决定应用这个配置文件,则一定会应用到所有文件的转换。
  • .babelrc 或是.babelrc.js、.babelrc.json相对文件(File Relative)的配置文件, babel 决定一个 js 文件应用哪些配置文件时,会执行如下策略: 如果要转换的这个 js 文件在当前项目内,则会先递归向上搜索最近的一个 .babelrc 文件(直到遇到package.json目录),将其与全局配置合并。如果这个 js 文件不在当前项目内,则只应用全局配置,忽略与这个文件相关的 .babelrc 。

这两个我更愿意将其称为全局配置 (babel.config.js) 和局部配置 (.babelrc) 便于理解一些。

这个定义在官方文档就有说明

New in Babel 7.x, Babel has a concept of a “root” directory, which defaults to the current working directory. For project-wide configuration, Babel will automatically search for a babel.config.json file, or an equivalent one using the supported extensions, in this root directory.

大白话就是: 当前所在目录即为*当前项目*根目录,babel 会读取当前所在目录的 babel.config.js 作为全局配置。
 

—— 为了清晰记忆上面的规则我来稍微总结一下:
 

babel 会在当前执行目录搜索 babel.config.js, 若有则读取并作为全局配置,若无则全局配置为空。然后在转换一个具体的js文件时会去判断,如果这个文件在当前执行目录外面,则只应用全局配置。如果这个文件在当前执行路径内,则会去基于这个文件向上搜索最近的一个 .babelrc ,将其与全局配置合并作为转换这个文件的配置。


babel的配置文件的配置方法都一样,本文以 .babelrc 配置文件为主 

在初次接触Babel我们只要用到一下两项配置:预设插件

预设只是插件的集合,您可以在plugins阵列中单独包含插件,也可以在阵列中包含插件集合presets,如果插件是集合(预设)的一部分,则不必单独包含它plugins当你包含它们时,npm包也是如此package.json

预设是插件的集合或正如他们所说:预设是可共享的.babelrc配置或简单的一系列babel插件。

* .babelrc

{   "presets": [...],   "plugins": [...] }

下面介绍presets与plugins

🌲 Plugins

Plugins顾名思义插件。

Babel的代码转换是通过在配置文件中应用插件(或预设)来启用的。

babel 本身不具有任何转化功能,我们要的代码要转换某些功能,比如将es6转换为es5,我们就需要下载相应的插件,并且将这些插件配置到.babelrc文件的plguins里面。

如何使用插件

如果插件是在npm上,你可以传入插件的名称,Babel会检查它是否安装在node_modules中。这是添加到插件配置选项,它接受一个数组。

* .babelrc

{ "plugins": ["babel-plugin-myPlugin", "@babel/plugin-transform-runtime"] } 

你也可以为你的插件指定一个相对/绝对路径。

* .babelrc

{ "plugins": ["./node_modules/asdf/plugin"] }

有关配置插件或预置路径的更多细节,请参阅名称规范化:参数 · Babel 中文文档 | Babel中文网

插件的使用方法:举个例子

Babel 使用插件来执行代码转换,插件其实就是用 JavaScript 所写的程序片段。比如,将箭头函数转换为浏览器能识别的普通函数,我们就需要用到 @babel/plugin-transform-arrow-functions插件,并将其添加到配置文件,它的代码实现如下:

1. 首先下载插件

npm i @babel/plugin-transform-arrow-functions -D

2. 添加至配置文件

* .babelrc

{ "plugins":[    "@babel/plugin-transform-arrow-functions"    ] }

这样babel就能够将箭头函数转换为普通函数了

//转换前 var a = () => {}; //转换后 var a = function () {};

🙋‍♂️ Q:什么?你怎么知道要用这个插件?

🤷 A:看文档啊!插件 · Babel 中文文档 | Babel中文网

转换插件​

转换插件用于转换你的代码。

转换插件将启用相应的语法插件,因此你不必同时指定这两种插件。

语法插件

大多数语法都可以通过Babel进行转换。在更罕见的情况下(如果转换还没有实现,或者没有默认的方式来实现),你可以使用@babel/plugin-syntax-bigint这样的插件,只允许Babel解析特定类型的语法。或者您想保留源代码,因为您只想让Babel进行代码分析或代码删除。

注意:如果已经使用了相应的转换插件,则不需要指定语法插件,因为它会自动启用它。

* .babelrc 

或者,你也可以通过 Babel 解析器传递任何 plugins 参数 :

JSON

{ "parserOpts": { "plugins": ["jsx", "flow"] } }

插件顺序​

插件的排列顺序很重要。

这意味着如果两个转换插件都将处理“程序(Program)”的某个代码片段,则将根据转换插件或 preset 的排列顺序依次执行。

  • 插件在 Presets 前运行。
  • 插件顺序从前往后排列。
  • Preset 顺序是颠倒的(从后往前)。

例如:

* .babelrc 

{ "plugins": ["transform-decorators-legacy", "transform-class-properties"] } 

先执行 transform-decorators-legacy ,在执行 transform-class-properties

重要的时,preset 的顺序是 颠倒的。如下设置:

* .babelrc 

{ "presets": ["@babel/preset-env", "@babel/preset-react"] } 

将按如下顺序执行: 首先是 @babel/preset-react,然后是 @babel/preset-env

插件参数​

插件和 preset 都可以接受参数,参数由插件名和参数对象组成一个数组,可以在配置文件中设置。

如果不指定参数,下面这几种形式都是一样的:

* .babelrc 

{ "plugins": ["pluginA", ["pluginA"], ["pluginA", {}]] } 

要指定参数,请传递一个以参数名作为键(key)的对象。

* .babelrc 

{ "plugins": [ [ "transform-async-to-module-method", { "module": "bluebird", "method": "coroutine" } ] ] } 

preset 的设置参数的工作原理完全相同:

* .babelrc 

{ "presets": [ [ "env", { "loose": true, "modules": false } ] ] } 

插件开发​

请参考 babel-handbook 学习如何创建自己的插件。

一个简单的用于反转名称顺序的插件(来自于首页):

JavaScript

export default function() { return { visitor: { Identifier(path) { const name = path.node.name; // reverse the name: JavaScript -> tpircSavaJ path.node.name = name .split("") .reverse() .join(""); }, }, }; }

🌲 Presets

Presets顾名思义预设。预设是可共享的.babelrc配置或简单的一系列babel插件.

我们要转换一些语法就得使用各种插件,并且添加到配置文件,如果每次项目需要的babel插件都差不多,而我们每次都要进行重复的下载,配置工作,这样效率是不是很低,很繁琐。

这个时候我们就可以利用presets这个功能,将一些常用的babel插件配置放入预设中,下载后直接将这个预设放入配置文件即可。具体操作可参照文档:预设(Presets) · Babel 中文文档 | Babel中文网

如何使用预设 

在Babel配置中,如果预设是在npm上,你可以传入预设的名称,Babel会检查它是否已经安装在node_modules中。这被添加到presets配置选项中,该选项接受一个数组。

* .babelrc

{ "presets": ["babel-preset-myPreset", "@babel/preset-env"] }

除此之外,您也可以指定预设的相对路径或绝对路径。 

{ "presets": ["./myProject/myPreset"] }

有关配置插件或预置路径的更多细节,请参阅名称规范化:参数 · Babel 中文文档 | Babel中文网

预设的使用方法,举个例子

例如,你经常看到的 @babel/preset-env@babel/preset-react

1.下载preset

npm i @babel/preset-env

2. 配置文件

* .babelrc

{ "presets":[ "preset-env" ] }

🙋‍♂️ Q:我怎么知道有哪些预设?

🤷 A:看文档 ,在npm上搜preset

一文带你零基础认识Babel,Babel到底可以用来干嘛

🙋‍♂️ Q:我怎么知道预设里面有哪些插件?

🤷 A:要知道预设里面有哪些插件,最好的方式就是搜npm看他的依赖项

可以看到preset-env有 76个插件

一文带你零基础认识Babel,Babel到底可以用来干嘛

不过,preset 分为以下几种:

最常见的预设是官方预设和实验预设。

◾ 第一种:官方内容 env, react, flow 等

官方提供的预设

babel官方已经针对常用环境编写了一些预设(preset):

  • @babel/preset-env for compiling ES2015+ syntax
  • @babel/preset-typescript for TypeScript
  • @babel/preset-react for React
  • @babel/preset-flow for Flow

◾ 第二种:Stage-X(实验性质的预设),这里面包含的都是当年最新规范的草案,每年更新。

TC39 将提案分为以下几个阶段:

  • Stage 0 – 设想(Strawman):只是一个想法,经过 TC39 成员提出即可,可能有 Babel插件。
  • Stage 1 – 建议(Proposal):这是值得跟进的,初步尝试。
  • Stage 2 – 草案(Draft):初始规范。
  • Stage 3 – 候选(Candidate):完成规范并在浏览器上初步实现。
  • Stage 4 – 完成(Finished):将添加到下一个年度版本发布中。

这也就是你在早期的项目或文档中看到 stage-0,stage-1的字眼,原来他们都是预设,不过现在你不用纠结这个问题Babel7已经放弃stage预设了。

一文带你零基础认识Babel,Babel到底可以用来干嘛

如何创建预设

如需创建一个自己的预设(无论是为了本地使用还是发布到 npm),需要导出(export)一个配置对象。

可以是返回一个插件数组…

JavaScript

module.exports = function() { return { plugins: ["pluginA", "pluginB", "pluginC"], }; }; 

preset 可以包含其他的 preset,以及带有参数的插件。

JavaScript

module.exports = () => ({ presets: [require("@babel/preset-env")], plugins: [ [require("@babel/plugin-proposal-class-properties"), { loose: true }], require("@babel/plugin-proposal-object-rest-spread"), ], }); 

有关更多信息,请参考 babel 手册 中关于 preset 的部分。

预设的排列顺序​

Preset 是逆序排列的(从后往前)。

 * .babelrc

{ "presets": ["a", "b", "c"] } 

将按如下顺序执行: cb 然后是 a

这主要是为了确保向后兼容,由于大多数用户将 “es2015” 放在 “stage-0” 之前。

预设的参数​

插件和 preset 都可以接受参数,参数由插件名和参数对象组成一个数组,可以在配置文件中设置。

如果不指定参数,下面这几种形式都是一样的:

 * .babelrc

{ "presets": [ "presetA", // bare string ["presetA"], // wrapped in array ["presetA", {}] // 2nd argument is an empty options object ] } 

要指定参数,请传递一个以参数名作为键(key)的对象。

 * .babelrc

{ "presets": [ [ "@babel/preset-env", { "loose": true, "modules": false } ] ] }

🌲 Polyfill

Plolyfill 垫片。| 使用指南 · Babel 中文文档 | Babel中文网

babel默认只转换新的 JavaScript 语法,比如箭头函数、扩展运算(spread)不转换新的 API,例如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转译。如果想使用这些新的对象和方法,则需要为当前环境提供一个垫片(polyfill)。

Polyfill主要有三种

1、@babel/polyfill

Babel 包含一个polyfill 库即@babel/polyfill。@babel/polyfill模块包含 core-js 和一个自定义的 regenerator runtime 来模拟完整的 ES2015+ 环境。

◼️ 什么是regenerator?

npm地址:regenerator-runtime – npm

github地址:https://github.com/facebook/regenerator

官方对他的描述直译过来是;

Standalone runtime for Regenerator-compiled generator and async functions.
 

重新生成编译的生成器和异步函数的独立运行时 | Regenerator编译的生成器和异步函数的独立运行时。

在网上找到这样一句话,解释道:

生成器函数、async、await函数经babel编译后,regenerator-runtime模块用于提供功能实现。

博主对于生成器(regenerator)也是一知半解,这里我们就简单的理解成,项目中要使用async、await函数就必须使用这个库吧!🤔 (对于regenerator有知道更详细的,欢迎下方留言已作解释)。

◼️ 什么是core-js?

npm地址:core-js – npm

下面是babel官方对core-js的解释:

简单粗暴的理解就是,你要使用一些js高级特性,如promise就得使用这个库。

经过上面潦草的描述,我们在总结一下:

由于babel只能将es6+语法转换为低级语法,而当我们使用一些高级特性时比如 async、await类似的Api,babel就显得无能为力了,因为babel无法实现这些高级Api的功能,这个时候就需要一个垫片(polyfill),而babel又包含了一个polyfill叫@babel/polyfill,这个polyfill本身也无法实现像async等高级API的功能,但是市面上有现成的封装好的类库实现了,于是@babel/polyfill将他们包含进来。这样当我们引入@babel/polyfill时,就可以丝滑的写高级语法了!

◼️ 使用方式

1. 下载

npm方式

npm install --save @babel/polyfill

注意,使用 --save 参数而不是 --save-dev,因为这是一个需要在你的源码之前运行的 polyfill。也就是说polyfill要在源代码之前运行!

Yarn方式  

yarn add @babel/polyfill

 2. 在入口文件导入

import "@babel/polyfill";

🚨 从 Babel 7.4.0 版本开始,这个软件包已经不建议使用了,建议直接包含 core-js/stable (用于模拟 ECMAScript 的功能): 

import "core-js/stable";

当然在webpack中你也可以这样干,在@babel/polyfill的描述有这样一段

大概意思就是建议我们将@babel/polyfill和@babel/preset-env配合使用并根据需求设置 useBuiltlns选项,这样就不至于将这个polyfill加载进来,显得很大。不然就使用手动导入各个polyfill的方式。

—— 在webpack中我们可以将@babel/polyfill和@babel/preset-env配合使用!

主要是设置 useBuiltlns选项。更多preset-env的配置请参照:@babel/preset-env · Babel

{   "presets" : [     ["@babel/preset-env",{       "targets": {         "browsers": [           "last 2 versions",           "not ie <= 9"         ]       },       "useBuiltIns": "usage"     }]   ] }

useBuiltlns:false:此时不对 polyfill 做操作。如果引入 @babel/polyfill,则无视配置的浏览器兼容,引入所有的 polyfill。

useBuiltlns:usage:按需加载polyfill,根据配置的浏览器兼容以及代码所用到的polyfill,不至于将所有polyfill加载进来,使用这种方式我们不用手动导入polyfill,但是需要安装。

useBuiltlns:entry:根据配置的浏览器兼容,引入浏览器不兼容的 polyfill。需要在入口文件手动添加 import @babel/polyfill,会自动根据 browserslist 替换成浏览器不兼容的所有 polyfill。

—— @babel/polyfill带来的问题

babel-polyfill,通过改写全局prototype的方式实现,它会加载整个polyfill,针对编译的代码中新的API进行处理,并且在代码中插入一些帮助函数,比较适合单独运行的项目。

babel-polyfill解决了Babel不转换新API的问题,但是直接在代码中插入帮助函数,会导致污染了全局环境,并且不同的代码文件中包含重复的代码,导致编译后的代码体积变大。虽然这对于应用程序或命令行工具来说可能是好事,但如果你的代码打算发布为供其他人使用的库,或你无法完全控制代码运行的环境,则会成为问题。

//import "@babel/polyfill"; //之前的写法 import "core-js/stable"; import "regenerator-runtime/runtime";

2、babel-runtime

npm install --save babel-runtime

为了解决 @babel/polyfill带来的问题,Babel提供了单独的包babel-runtime用于提供编译模块的工具函数,启用插件babel-plugin-transform-runtime后,Babel就会使用babel-runtime下的工具函数。

babel-runtime插件能够将这些工具函数的代码转换成require语句,指向为对babel-runtime的引用。每当要转译一个api时都要手动加上require(‘babel-runtime’)。简单说 babel-runtime 更像是一种按需加载的实现,比如,你哪里需要使用 Promise,只要在这个文件头部 require Promise from ‘babel-runtime/core-js/promise’就行了。

不过如果你许多文件都要使用 Promise,难道每个文件都要 import 一遍不成?

3、babel-plugin-transform-runtime

为了方便使用 babel-runtime,解决手动 require 的苦恼。它会分析我们的 ast 中,是否有引用 babel-rumtime 中的垫片(通过映射关系),如果有,就会在当前模块顶部插入我们需要的垫片。

transform-runtime 是利用 plugin 自动识别并替换代码中的新特性,你不需要再引入,只需要装好 babel-runtime 和 配好 plugin 就可以了。

好处是按需替换,检测到你需要哪个,就引入哪个 polyfill,如果只用了一部分,打包完的文件体积对比 babel-polyfill 会小很多。而且 transform-runtime 不会污染原生的对象,方法,也不会对其他 polyfill 产生影响。

所以, transform-runtime 的方式更适合开发工具包,一方面是体积够小,另一方面是用户(开发者)不会因为引用了我们的工具包而污染了全局的原生方法,产生副作用,还是应该留给用户自己去选择。

🎋 babel-runtime 和 babel-plugin-transform-runtime

在大多数情况下,你应该安装 babel-plugin-transform-runtime 作为开发依赖(使用 –save-dev),并且将 babel-runtime 作为生产依赖(使用 –save)。这个看vue-cli生成的 package.json就能发现。

因为babel编译es6到es5的过程中,babel-plugin-transform-runtime这个插件会自动polyfill es5不支持的特性,这些polyfill包就是在babel-runtime这个包里(core-js 、regenerator等)

npm install —save-dev babel-plugin-transform-runtime npm install —save babel-runtime

🎋 使用技巧分享

以下内容摘自:babel从入门到精通_babel学习

◼️ @babel/preset-env 包含了一些基本es语法转换的插件(箭头函数、类转换等等),同时还支持polyfill,有usage跟entry模式,但是preset-env添加polyfill会像之前使用@babel/polyfill一样,会污染全局变量。

◼️ @babel/plugin-transform-runtime 主要是利用@babel/runtime提取了一些公共的babel帮助函数,同时也支持polyfill的添加,添加的polyfill都是以一个局部变量的形式引入,不会污染全局变量。

◾ 如果你做的是一个二方库,然后需要被别人依赖,那么建议使用@babel/plugin-transform-runtime来引入polyfill,因为你要尽可能的专注于做自己的事,而不是说去影响别人,语法转换可以使用preset-env预设,比如以下配置:

module.exports = { presets: [['@babel/preset-env']], plugins: [ [ '@babel/plugin-transform-runtime', { corejs: { version: 3, proposals: true }, helpers: true, useESModules: true, regenerator: true, absoluteRuntime: './node_modules' } ] ] }

◾ 如果你做的是一个普通的业务项目的话,可以用preset-env来转换语法和polyfill,然后再利用@babel/plugin-transform-runtime来引入helpers跟generator做到代码重复利用,比如以下配置:

module.exports = { presets: [ [ '@babel/preset-env', { corejs: 3, useBuiltIns: 'usage' } ] ], plugins: [ [ '@babel/plugin-transform-runtime', { corejs: false, helpers: true, useESModules: false, regenerator: true, absoluteRuntime: './node_modules' } ] ] } 

◾ @babel/plugin-transform-runtime 常见配置参照:@babel/plugin-transform-runtime · Babel

◼️ 下面再介绍几个与Babel相关的:

  • @babel/core:babel的核心库
  • babel-loader:使用webpack时作为有个loader在代码混淆之前进行代码转换
  • @babel/preset-env:babel预设的一种
  • @babel/cli:允许使用babel命令转译文件

到此相信你已经对babel有个初步了解,还有很多细节本文没有提及,欢迎指教。


🔆 参考文献

Babel 中文文档 | Babel中文网 · Babel 中文文档 | Babel中文网

预设(Presets) · Babel 中文文档 | Babel中文网

插件 · Babel 中文文档 | Babel中文网

🔆 参考资料

Babel 插件有啥用? – 知乎

Babel 配置文件 – 简书

理解babel.config.js和babelrc

一文带你零基础认识Babel,Babel到底可以用来干嘛

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/133262.html

(0)
上一篇 2025-07-24 21:45
下一篇 2025-07-24 22:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信