背景
我们都知道 Babel
本身是一个 JavaScript
编译器,主要用于将现代 JavaScript
(比如 ECMAScript 2015+
,TypeScript
,JSX
等)转换为向后兼容的 JavaScript
,方便在较旧的浏览器环境中下运行。而且Babel
的编译过程是在构建过程(Webpack,Vite,Gulp
等构建工具)进行,不会在浏览器中实时编译。
大家好,我是芝士,欢迎点此扫码加我微信 Hunyi32 交流,最近创建了一个低代码/前端工程化交流群,欢迎加我微信 Hunyi32 进群一起交流学习,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章
浏览器默认不支持 Babel
的原因主要是性能考虑和开发流程。Babel
的设计初衷应该就是作为一个编译工具,在构建阶段使用,而不是在浏览器中实时执行。
但是我们有时候想在浏览器环境中实现 JavaScript/TS
的编译过程,比如在线编辑器中 CodePen
ES10等
代码的执行需要先编译后执行等,这时候浏览器实现编译是一个必不可少的需求。
接下来我们文章的主角 @babel/standalone
就出现了。
@babel/standalone 的出现
这个模块的英文名字也挺有趣的 standalone
(独立的),@babel/standalone
是 Babel
的一个独立版本,最早在 Babel 6 版本发布之后推出的。它的目的就是为了在浏览器环境中直接使用 Babel
,将现代 JavaScript
代码(例如 ES6、TypeScript、JSX
等)编译为浏览器可执行的 JavaScript
。
@babel/stonelone 使用
如果是在 React
项目中,可以直接导入 @babel/stonealone
模块
tsx
import { transform, registerPreset, registerPlugin } from '@babel/standalone/babel';
transform, registerPreset, registerPlugin
我认为是 @babel/standalone
中最常用的函数,下文中会一一讲解。
实现代码编译
使用 transform
函数实现代码编译转换
js
const code = ` const add = (a, b) => a + b; console.log(add(2, 3)); `;
const result = transform(code,{
sourceType: 'script',
filename: 'result.ts',
presets: [],
plugins: [],
})
babel/standalone 常用函数
transform
transform
第二个参数中常用配置
sourceType
:指定输入代码的类型,它可以是'script'
(表示普通的 JavaScript 脚本)、'module'
(表示 ES 模块)。filename
:输入代码的文件名,这在某些情况下可能会影响 Babel 的处理行为,例如对于某些依赖于文件路径的插件,而且建议增加filename属性,在编译报错时候更清晰用于展示文件名称和调试问题。presets
:一个数组,用于指定要应用的 Babel 预设。 4.plugins
:一个数组,用于指定要应用的 Babel 插件。
配置预设
registerPreset
函数用于注册预设
registerPreset
函数允许你注册任意的 Babel
预设,这样你就可以在浏览器环境中使用这些预设来转换代码。例如,如果你想使用 @babel/preset-env
和 @babel/preset-typescript
,你需要先通过 registerPreset
函数注册它们,然后在调用 transform
方法引用这些预设。
以注册 @babel/preset-env
预设并使用为例子
js
import { transform, registerPreset, registerPlugin } from '@babel/standalone/babel';
import presetEnv from '@babel/preset-env';
// 注册@babel/preset-env 预设
registerPreset('my-preset', {
presets: [
[
presetEnv,
{
targets: {
chrome: '58',
ie: '11',
},
},
],
],
});
// 在transform中使用注册的自定义预设名称 env-preset
const code = ` const add = (a, b) => a + b; console.log(add(2, 3)); `;
const result = transform(code,{
sourceType: 'script',
filename: 'result.ts',
presets: ['my-preset'],
})
配置插件
registerPlugin
函数也可以用于注册任意的 Babel
插件。使用 @babel/standalone
你可以在浏览器中加载并注册任意的 Babel
插件,包括自己自定义的 Babel
插件
js
import { transform, registerPreset, registerPlugin } from '@babel/standalone/babel';
import presetEnv from '@babel/preset-env';
// 注册自定义插件该改变Identifier类型节点名称
registerPlugin('my-custom-plugin',
{ visitor: {
Identifier(path) {
if (path.node.name === 'oldName') {
path.node.name = 'newName';
}
},
},
});
// 注册@babel/preset-env 预设
registerPreset('my-preset', {
presets: [
[
presetEnv,
{
targets: {
chrome: '58',
ie: '11',
},
},
],
],
});
// 在transform中使用注册的自定义预设名称 my-preset
// 在transform中使用注册的自定义插件 my-custom-plugin
const code = ` const add = (a, b) => a + b; console.log(add(2, 3)); `;
const result = transform(code,{
sourceType: 'script',
filename: 'result.ts',
presets: ['my-preset'],
plugins: ['my-custom-plugin'],
})
常用的预设有哪些
- @babel/preset-env 自动将现代
JavaScript
(ES6+)代码转换为兼容目标环境的旧版本JavaScript
,以支持较旧的浏览器或环境。 (最常用!!!!) - @babel/preset-react:将
React JSX
语法转换为JavaScript
,使浏览器能够正确解析和执行React
组件。 - babel/preset-typescript : 将
TypeScript
代码转换为纯JavaScript
,并移除类型注释,以便在浏览器中运行。
这里我其实也有一个疑问,除了常见的预设可以在官网看到 否支持在浏览器环境中运行?但是有预设的不会写且没有正规官网,这种只能靠验证 transform 编译时看是否报错吗?不过目前除了几个常用的其他也未用到过,小伙伴们有更好的办法可以和我说下。
@babel/stonealone的应用场景
在线代码编辑器
许多在线代码编辑器(如CodePen
)允许用户编写和运行 JavaScript
。这些编辑器通常是支持现代 JavaScript
语法特性的,为了所有浏览器可以兼容执行这些代码,编辑器需要将现代 JavaScript
语法转换为旧版本的JavaScript
,这时候可能会用到 @babel/standalone
比如 编辑器中书写箭头函数会被转换
js
// ES6代码
const greet = (name) => `Hello, ${name}!`;
// Babel会将其转换为ES5
var greet = function(name) {
return "Hello, " + name + "!";
};
一些在线教程或学习网站
很多教学和学习网站(比如一些官方学习网站,在线看执行结果),可能会需要测试和演示一些现代 JavaScript
语法。这时候也可以用到 @babel/standalone
,不需设置复杂的开发环境,就能快速样式 ES6
特性或者 TypeScript
语法
比如线课程和编程教程网站使用 @babel/standalone
来展示现代 JavaScript
语法,如箭头函数、解构赋值、模块导入等,并实时显示转换后的代码或执行结果。
js
// ES6+代码
const [a, b] = [1, 2];
console.log(`a: ${a}, b: ${b}`);
// Babel将其转换为ES5
var _ref = [1, 2],
a = _ref[0],
b = _ref[1];
console.log('a: ' + a + ', b: ' + b);
大家好,我是芝士,最近创建了一个低代码/前端工程化交流群,欢迎点此扫码加我微信 Hunyi32 交流,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章
总结
其实这也是上一篇文章整个项目中的一个知识点,预告下篇文章 WebWorker
协议层封装实现,让你无感使用