面试官:如何直接在浏览器环境编译ES6+/TS代码?

背景

我们都知道 Babel 本身是一个 JavaScript 编译器,主要用于将现代 JavaScript(比如 ECMAScript 2015+TypeScriptJSX等)转换为向后兼容的 JavaScript,方便在较旧的浏览器环境中下运行。而且Babel 的编译过程是在构建过程(Webpack,Vite,Gulp等构建工具)进行,不会在浏览器中实时编译

大家好,我是芝士,欢迎点此扫码加我微信 Hunyi32 交流,最近创建了一个低代码/前端工程化交流群,欢迎加我微信 Hunyi32 进群一起交流学习,也可关注我的公众号[ 前端界 ] 持续更新优质技术文章

浏览器默认不支持 Babel 的原因主要是性能考虑和开发流程。Babel 的设计初衷应该就是作为一个编译工具,在构建阶段使用,而不是在浏览器中实时执行。

但是我们有时候想在浏览器环境中实现 JavaScript/TS的编译过程,比如在线编辑器中 CodePen ES10等 代码的执行需要先编译后执行等,这时候浏览器实现编译是一个必不可少的需求。

接下来我们文章的主角 @babel/standalone 就出现了。

@babel/standalone 的出现

这个模块的英文名字也挺有趣的 standalone(独立的),@babel/standaloneBabel 的一个独立版本,最早在 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 第二个参数中常用配置

  1. sourceType:指定输入代码的类型,它可以是 'script'(表示普通的 JavaScript 脚本)、'module'(表示 ES 模块)。
  2. filename:输入代码的文件名,这在某些情况下可能会影响 Babel 的处理行为,例如对于某些依赖于文件路径的插件,而且建议增加filename属性,在编译报错时候更清晰用于展示文件名称和调试问题。
  3. 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'],
})

常用的预设有哪些

  1. @babel/preset-env 自动将现代 JavaScript(ES6+)代码转换为兼容目标环境的旧版本 JavaScript,以支持较旧的浏览器或环境。 (最常用!!!!)
  2. @babel/preset-react:将 React JSX 语法转换为 JavaScript,使浏览器能够正确解析和执行 React 组件。
  3. 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 协议层封装实现,让你无感使用

相关推荐
前端拾光者11 分钟前
利用D3.js实现数据可视化的简单示例
开发语言·javascript·信息可视化
Json_1817901448029 分钟前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
大数据编程之光35 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
风尚云网1 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
木子02041 小时前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing1 小时前
React核心功能详解(一)
前端·react.js·前端框架
捂月1 小时前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
深度混淆1 小时前
实用功能,觊觎(Edge)浏览器的内置截(长)图功能
前端·edge
Smartdaili China1 小时前
如何在 Microsoft Edge 中设置代理: 快速而简单的方法
前端·爬虫·安全·microsoft·edge·社交·动态住宅代理
秦老师Q1 小时前
「Chromeg谷歌浏览器/Edge浏览器」篡改猴Tempermongkey插件的安装与使用
前端·chrome·edge