面试官:如何直接在浏览器环境编译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 协议层封装实现,让你无感使用

相关推荐
蓝天白云下遛狗3 分钟前
goole chrome变更默认搜索引擎为百度
前端·chrome
come1123426 分钟前
Vue 响应式数据传递:ref、reactive 与 Provide/Inject 完全指南
前端·javascript·vue.js
前端风云志1 小时前
TypeScript结构化类型初探
javascript
musk12121 小时前
electron 打包太大 试试 tauri , tauri 安装打包demo
前端·electron·tauri
翻滚吧键盘2 小时前
js代码09
开发语言·javascript·ecmascript
万少2 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
OpenGL2 小时前
Android targetSdkVersion升级至35(Android15)相关问题
前端
rzl022 小时前
java web5(黑马)
java·开发语言·前端
Amy.Wang2 小时前
前端如何实现电子签名
前端·javascript·html5
海天胜景2 小时前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui