Babel插件指南

Max2Babylon-1.3.33 插件 文件放入 C:/Programs/Autodesk/3ds Max 2015/bin/assemblies下。右键3Dmax有Babaylon选项。选择导出gltf或glb文件。 立即下载

Babel插件指南

Babel简介

Babel 是一个通用的多功能的 JavaScript 编译器。此外它还拥有众多模块可用于不同形式的静态分析。

静态分析是在不需要执行代码的前提下对代码进行分析的处理过程。静态分析的目的是多种多样的, 它可用于语法检查,编译,代码高亮,代码转换,优化,压缩等等场景。

  • 通过图进一步理解:

浏览器编译你的js代码,需要把js转化成ast。2015年es6语法发布,但浏览器还普遍不支持es6语法。于是催生出babel模块,默认支持js到ast的转化,并通过修改ast,将es6的特性代码转化为同效用的es5代码,同时也提供了ast的操作函数。

Babel操作流程:js代码 -> 原AST -> babel处理 -> 修改后的AST -> 修改后的js代码 -> 交给浏览器编译

即: 解析(parse),转换(transform),生成(generate)

实现上述功能的插件见小节:Babel API

Babel 更确切地说是源码到源码的编译器,通常也叫做“转换编译器(transpiler)”。 意思是说你为 Babel 提供一些 js代码,Babel 更改这些代码,然后返回给你新生成的js代码。

由于babel提供了操作AST的函数,所以开发者可以由此做各种各样的静态分析。

AST(Abstract syntax tree)简介

常见编译型语言(例如:Java)编译程序一般步骤分为:词法分析->语法分析->语义检查->代码优化和字节码生成。具体的编译流程如下图:

js的AST生成和java略有不同,java是走上图所有流程,通过本地jdk将**.java文件编译成.class后缀的文件,然后交给jvm(虚拟机)处理。js默认是通过浏览器**编译,流程到上图的语义检查器为止,生成最终的AST

  • AST解析示例

js代码

let a = 1;

解析后AST

{
  "type": "Program",
  "start": 0,
  "end": 10,
  "body": [
    {
      "type": "VariableDeclaration",
      "start": 0,
      "end": 10,
      "declarations": [
        {
          "type": "VariableDeclarator",
          "start": 4,
          "end": 9,
          "id": {
            "type": "Identifier",
            "start": 4,
            "end": 5,
            "name": "a"
          },
          "init": {
            "type": "Literal",
            "start": 8,
            "end": 9,
            "value": 1,
            "raw": "1"
          }
        }
      ],
      "kind": "let"
    }
  ],
  "sourceType": "module"
}

在线js转换到AST工具:https://astexplorer.net/#/

JS生态里,基于 AST 实现功能的工具有很多,babel只是其中一个工具。其他例如:

  • ESlint: 代码错误或风格的检查,发现一些潜在的错误
  • IDE 的错误提示、格式化、高亮、自动补全等
  • UglifyJS 压缩代码
  • 代码打包工具 webpack

ESTree AST Node

babel完整的流程,最后一步是将修改后的AST生成为js代码,即深度优先遍历整个 AST,然后构建可以表示转换后代码的字符串。

Visitors(访问者)

当谈及“进入”一个节点,实际上是说我们在访问它们, 之所以使用这样的术语是因为有一个**访问者模式(visitor)**的概念。

visitor是一个用于 AST 遍历的跨语言的模式。 简单的说visitor就是一个对象,定义了用于在一个树状结构中获取具体节点的方法。例如:

visitor: {
  // 变量声明函数
  VariableDeclarator(path, state) {
		// todo
  }
}

上面AST小节示例有 “type”: “VariableDeclarator” ,诸如此类的树节点在访问时,就会进入visitor对象声明的对应类型的成员方法。此时你访问到的不是节点本身,而是一个Path,所以可以追踪树的父节点等其它信息。

常用写法是取path.node,如上即取到type = VariableDeclarator 的对象

举个栗子:

// 设定一个访问者对象
const visitor = {
  Identifier(path) {
    console.log("Visiting: " + path.node.name);
  }
};
// 声明js代码
a + b + c;
// js编译成ast
{
  "type": "Program",
  "start": 0,
  "end": 10,
  "body": [
    {
      "type": "ExpressionStatement",
      "start": 0,
      "end": 10,
      "expression": {
        "type": "BinaryExpression",
        "start": 0,
        "end": 9,
        "left": {
          "type": "BinaryExpression",
          "start": 0,
          "end": 5,
          "left": {
            "type": "Identifier",
            "start": 0,
            "end": 1,
            "name": "a"
          },
          "operator": "+",
          "right": {
            "type": "Identifier",
            "start": 4,
            "end": 5,
            "name": "b"
          }
        },
        "operator": "+",
        "right": {
          "type": "Identifier",
          "start": 8,
          "end": 9,
          "name": "c"
        }
      }
    }
  ],
  "sourceType": "module"
}
// 运行后打印结果:
Visiting: a
Visiting: b
Visiting: c

js声明后被编译成AST,AST被访问时,Identifier类型有3次,执行visitor对象的Identifier成员方法3次,打印对应日志

Babel API

babylon

Babylon 是 Babel 的解析器,作用是把js字符串解析成AST

$ npm install --save babylon
import * as babylon from "babylon";
const code = `function square(n) {
  return n * n;
}`;
babylon.parse(code);
// Node {
//   type: "File",
//   start: 0,
//   end: 38,
//   loc: SourceLocation {...},
//   program: Node {...},
//   comments: [],
//   tokens: [...]
// }
babel-traverse

Babel Traverse(遍历)模块维护了整棵树的状态,并且负责替换、移除和添加节点。就是触发访问者(Visitors)的步骤

$ npm install --save babel-traverse

遍历更新节点:

// 把变量 n 改成 x
import * as babylon from "babylon";
import traverse from "babel-traverse";
const code = `function square(n) {
  return n * n;
}`;
const ast = babylon.parse(code);
traverse(ast, {
  enter(path) {
    if (
      path.node.type === "Identifier" &&
      path.node.name === "n"
    ) {
      path.node.name = "x";
    }
  }
});
babel generator

Babel Generator模块是 Babel 的代码生成器,它读取AST并将其转换为代码和源码映射(sourcemaps)

$ npm install --save babel-generator

通过visitors处理后的AST再转成js

import * as babylon from "babylon";
import generate from "babel-generator";
import traverse from "babel-traverse";
const code = `function square(n) {
  return n * n;
}`;
const ast = babylon.parse(code);
traverse(ast, {
  enter(path) {
    if (
      path.node.type === "Identifier" &&
      path.node.name === "n"
    ) {
      path.node.name = "x";
    }
  }
});
generate(ast, {}, code);
// {
//   code: "...",
//   map: "..."
// }

项目中实践

引用自定义的babel插件

babel-core版本是6.x的,vue项目有.babelrc文件,在plugins属性里直接配置路径即可,如下babelPluginConsole:

{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime", "./src/plugins/babel/babelPluginConsole"]
}

其他版本的babel也一个思路,找到plugins配置位置,对应加入即可。

新增插件js文件

如上配置,我们在 /src/plugins/babel/ 路径下新建 babelPluginConsole.js

module.exports = function(babel) {
  let t = babel.types;
  return {
    visitor: {
  		// todo      
    }
  };
};
确定要实现的功能,编译成AST进行分析

这里我们对console.log()进行处理,默认打印变量名,如下:

let test = 'hi babel'
console.log(test);
//打印: test hi babel

所以我们将console.log(test)和console.log('test',test); 解析成AST进行比较

{
  "type": "Program",
  "start": 0,
  "end": 67,
  "body": [
    {
      "type": "VariableDeclaration",
      "start": 0,
      "end": 21,
      "declarations": [
       // 变量定义的AST,忽略
      ],
      "kind": "let"
    },
    // console.log(test) 的AST
    {
      "type": "ExpressionStatement",
      "start": 22,
      "end": 40,
      "expression": {
        "type": "CallExpression",
        "start": 22,
        "end": 39,
        "callee": {
          "type": "MemberExpression",
          "start": 22,
          "end": 33,
          "object": {
            "type": "Identifier",
            "start": 22,
            "end": 29,
            "name": "console"
          },
          "property": {
            "type": "Identifier",
            "start": 30,
            "end": 33,
            "name": "log"
          },
          "computed": false,
          "optional": false
        },
        "arguments": [
          {
            "type": "Identifier",
            "start": 34,
            "end": 38,
            "name": "test"
          }
        ],
        "optional": false
      }
    },
    // console.log('test', test) 的AST
    {
      "type": "ExpressionStatement",
      "start": 41,
      "end": 67,
      "expression": {
        "type": "CallExpression",
        "start": 41,
        "end": 66,
        "callee": {
          "type": "MemberExpression",
          "start": 41,
          "end": 52,
          "object": {
            "type": "Identifier",
            "start": 41,
            "end": 48,
            "name": "console"
          },
          "property": {
            "type": "Identifier",
            "start": 49,
            "end": 52,
            "name": "log"
          },
          "computed": false,
          "optional": false
        },
        "arguments": [
          {
            "type": "Literal",
            "start": 53,
            "end": 59,
            "value": "test",
            "raw": "'test'"
          },
          {
            "type": "Identifier",
            "start": 61,
            "end": 65,
            "name": "test"
          }
        ],
        "optional": false
      }
    }
  ],
  "sourceType": "module"
}

比较后发现,arguments属性多了一个字符串对象。所以我们要做的就是,获取console.log(test)的AST然后定位到arguments数组,给它添加一个对象。

编写和调试插件

按上述分析,得到如下一种解决逻辑

module.exports = function(babel) {
  let t = babel.types;
  return {
    visitor: {
      ExpressionStatement(path) {
        if (path.node && path.node.expression && path.node.expression.callee
            && path.node.expression.callee.object && path.node.expression.callee.property
            && path.node.expression.arguments 
            && path.node.expression.callee.object.name === 'console' 
            && path.node.expression.callee.property.name === 'log') {
          if (path.node.expression.arguments[0].type === 'Identifier') {
            path.node.expression.arguments = [t.stringLiteral(path.node.expression.arguments[0].name), ...path.node.expression.arguments]
            console.log('path.node.expression.arguments2', path.node.expression.arguments);
          }
        }
      },      
    }
  };
};

注意
  • 插件实现的逻辑非常灵活,可以使用自带的方法处理节点,也可以使用推荐的babel插件处理节点,如babel-template
  • visitor访问的是所有的节点,vue框架下,npm run后每次修改逻辑,热响应都会执行visitor的成员方法
  • 插件本身的逻辑修改,需要重新npm run才能响应

额外说明polyfill

首先我们来理清楚这三个概念:

  • 最新ES语法,比如:箭头函数,let/const
  • 最新ES Api,比如Promise
  • 最新ES实例/静态方法,比如String.prototype.include

babel-prest-env仅仅只会转化最新的es语法,并不会转化对应的Api和实例方法,比如说ES 6中的Array.from静态方法。

一些内置方法模块,仅仅通过preset-env的语法转化是无法进行识别转化的,所以就需要一系列类似”垫片“的工具进行补充实现这部分内容的低版本代码实现。这就是所谓的polyfill的作用。

其他插件案例

  • 箭头函数转换插件
const babelTypes = require('@babel/types');

function ArrowFunctionExpression(path) {
  const node = path.node;
  hoistFunctionEnvironment(path);
  node.type = 'FunctionDeclaration';
}

/**
 * @param {*} nodePath 当前节点路径
 */
function hoistFunctionEnvironment(nodePath) {
  // 往上查找 直到找到最近顶部非箭头函数的this p.isFunction() && !p.isArrowFunctionExpression()
  // 或者找到跟节点 p.isProgram()
  const thisEnvFn = nodePath.findParent((p) => {
    return (p.isFunction() && !p.isArrowFunctionExpression()) || p.isProgram();
  });
  // 接下来查找当前作用域中那些地方用到了this的节点路径
  const thisPaths = getScopeInfoInformation(thisEnvFn);
  const thisBindingsName = generateBindName(thisEnvFn);
  // thisEnvFn中添加一个变量 变量名为 thisBindingsName 变量值为 this
  // 相当于 const _this = this
  thisEnvFn.scope.push({
    // 调用babelTypes中生成对应节点
    // 详细你可以在这里查阅到 https://babeljs.io/docs/en/babel-types
    id: babelTypes.Identifier(thisBindingsName),
    init: babelTypes.thisExpression(),
  });
  thisPaths.forEach((thisPath) => {
    // 将this替换称为_this
    const replaceNode = babelTypes.Identifier(thisBindingsName);
    thisPath.replaceWith(replaceNode);
  });
}

/**
 * 查找当前作用域内this使用的地方
 * @param {*} nodePath 节点路径
 */
function getScopeInfoInformation(nodePath) {
  const thisPaths = [];
  // 调用nodePath中的traverse方法进行便利
  // 你可以在这里查阅到  https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md
  nodePath.traverse({
    // 深度遍历节点路径 找到内部this语句
    ThisExpression(thisPath) {
      thisPaths.push(thisPath);
    },
  });
  return thisPaths;
}

/**
 * 判断之前是否存在 _this 这里简单处理下
 * 直接返回固定的值
 * @param {*} path 节点路径
 * @returns
 */
function generateBindName(path, name = '_this', n = '') {
  if (path.scope.hasBinding(name)) {
    generateBindName(path, '_this' + n, parseInt(n) + 1);
  }
  return name;
}

module.exports = {
  hoistFunctionEnvironment,
  arrowFunctionPlugin: {
    visitor: {
      ArrowFunctionExpression,
    },
  },
};

附录

类型原名称中文名称描述
Program程序主体整段代码的主体
VariableDeclaration变量声明声明一个变量,例如 var let const
FunctionDeclaration函数声明声明一个函数,例如 function
ExpressionStatement表达式语句通常是调用一个函数,例如 console.log()
BlockStatement块语句包裹在 {} 块内的代码,例如 if (condition){var a = 1;}
BreakStatement中断语句通常指 break
ContinueStatement持续语句通常指 continue
ReturnStatement返回语句通常指 return
SwitchStatementSwitch 语句通常指 Switch Case 语句中的 Switch
IfStatementIf 控制流语句控制流语句,通常指 if(condition){}else{}
Identifier标识符标识,例如声明变量时 var identi = 5 中的 identi
CallExpression调用表达式通常指调用一个函数,例如 console.log()
BinaryExpression二进制表达式通常指运算,例如 1+2
MemberExpression成员表达式通常指调用对象的成员,例如 console 对象的 log 成员
ArrayExpression数组表达式通常指一个数组,例如 [1, 3, 5]
FunctionExpression函数表达式例如const func = function () {}
ArrowFunctionExpression箭头函数表达式例如const func = ()=> {}
AwaitExpressionawait表达式例如let val = await f()
ObjectMethod对象中定义的方法例如 let obj = { fn () {} }
NewExpressionNew 表达式通常指使用 New 关键词
AssignmentExpression赋值表达式通常指将函数的返回值赋值给变量
UpdateExpression更新表达式通常指更新成员值,例如 i++
Literal字面量字面量
BooleanLiteral布尔型字面量布尔值,例如 true false
NumericLiteral数字型字面量数字,例如 100
StringLiteral字符型字面量字符串,例如 vansenb
SwitchCaseCase 语句通常指 Switch 语句中的 Case
  • babel-type api:https://www.npmjs.com/package/babel-types

参考资料地址

在线js转换到AST工具:https://astexplorer.net/#/

babel官网:https://www.babeljs.cn/docs/

AST说明:https://zhaomenghuan.js.org/blog/js-ast-principle-reveals.html

babel指南手册:https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md#toc-introduction

babel插件开发相关文章:https://juejin.cn/post/7155434131831128094#heading-7

Blender导出babylon格式插件 Blender转Babylon格式插件。 安装步骤见https://doc.babylonjs.com/ 立即下载

相关推荐

1 安装软件node-v14解决max内插件babylon.导出是不能压缩问题

1 安装软件node_v14解决max内插件babylon.导出是不能压缩问题

30分钟入门babel插件

快速学习什么是babel、babel的流程、通过AST可视化平台介绍babel ast、babel api等,快速入门Babel插件

Missy_xw2018的博客 1807

数字IC后端项目典型问题之后端实战项目问题记录

数字IC后端培训教程之数字后端实战项目问题debug及解决方案记录

weixin_37584728的博客 1715

3dmax导出gltf格式(安装插件 babylon)

根据自己的3dmax版本下载对应文件。

YG_zhh的博客 6467

大数据架构中的数据血缘追踪技术解析

数据血缘(Data Lineage)是指数据从源头到目标的完整流转路径,它记录了数据在整个生命周期中的变化过程。在大数据架构中,数据血缘追踪技术已经成为数据治理的核心组成部分。本文旨在全面解析数据血缘追踪的技术原理、实现方法和应用实践,帮助读者深入理解这一关键技术。本文将从基础概念入手,逐步深入到技术实现细节,最后探讨实际应用和未来趋势。数据血缘的核心概念和技术原理数据血缘的数学模型和算法实现实际项目案例和代码解析主流工具和解决方案比较未来发展方向和技术挑战。

架构师的AI之路,分享AI应用开发架构的学习与实践。 689

避坑指南:RK3588上编译EtherCAT 1.6时遇到的权限问题和模块安装错误

本文详细解析了在RK3588平台上编译EtherCAT 1.6时常见的权限问题和模块安装错误,提供了两种实战解决方案和嵌入式开发的通用权限管理策略。通过优化内核配置和编译参数,显著提升实时性能,帮助开发者高效完成EtherCAT主站部署。

weixin_33724046的博客 453

Babel ESM 插件使用指南

Babel ESM 插件使用指南 项目介绍 Babel ESM 插件 是由 Prateek Bhatnagar 开发的一个工具,旨在为现有的打包文件生成对应的 ES 模块版本。这个插件对于希望在现代Web开发中利用ES模块的同时,又不放弃现有CommonJS或UMD构建的开发者来说非常有用。通过添加此插件到您的构建流程中,可以轻松创建两套模块体系,便于支持不同的导入方式和环境。 项目快速启动 要...

gitblog_00374的博客 836

PPT+视频 | 详解智能营销增益模型(uplift model)

分享营销增益模型的原理和常见的建模及评估方法,并以淘票票智能票补为例介绍uplift model技术的实践经验。

阿里文娱技术 8626

Babel 插件:react-require 指南

Babel 插件:react-require 指南 项目简介 babel-plugin-react-require 是一个用于简化 React 应用中 JSX 文件导入 React 组件过程的 Babel 插件。它自动在每个文件顶部插入对 React 的导入语句,从而减少代码重复,提高开发效率。 项目目录结构及介绍 此 GitHub 存储库遵循标准的 Node.js 包结构,以下是其主要组成部分:...

gitblog_00603的博客 768

BUUCTF--[OGeek2019]babyrop

才学习了基本的ROP流程,到处找题练,不过也没做出来几道题,以这道32位的题作为例题吧。 这道题是BUUCTF上pwn练习题里的[OGeek2019]babyrop。 代码审计 老规矩先checksec一下: 没有canary保护,nx保护开启排除shellcode可能性,FULL RELEO为地址随机化。 观察主函数,先设定了一个闹铃,到时间就会强制退出程序,解除闹铃的方法在上一篇博客中提到过了, 这道题中闹铃函数依然对我们解题起不到什么干扰作用。 主函数的思路大概是:生成一个随机数,把这个随机数作为

N1rvana的博客 6006

Windows 10/11 下用 Docker 一键部署 CVAT 标注工具(附 WSL2 配置指南)

本文详细指导如何在Windows 10/11系统上,通过配置WSL2和Docker Desktop,实现CVAT标注工具的一键部署。内容涵盖从环境准备、Docker安装、CVAT服务启动到性能优化与安全配置的全流程,为计算机视觉开发者提供稳定高效的本地标注平台解决方案。

weixin_28839601的博客 464

Babel 插件 JSX v-model 使用指南

Babel 插件 JSX v-model 使用指南 项目介绍 Babel 插件 JSX v-model 是一个专门为React及其他支持JSX的库设计的Babel插件,它提供了在JSX中使用Vue-like的v-model语法糖的能力。这意味着开发者可以在非Vue环境下享受双向数据绑定的便利性,简化表单输入元素的数据处理流程。 项目快速启动 要开始使用 babel-plugin-jsx-v-mod...

gitblog_00948的博客 583

​ISP算法及架构分析介绍

ISP算法及架构分析介绍ISP即Image Signal Processor,是一种图像处理架构,不是我们用的下载器。ISP其实算是图像处理的一个特例,一般应用于前端设备(相对于SENSOR),从结果上看就是将RAW数据转换成压缩后的RGB(一般)数据,供后续CPU使用(识别、压缩等)。市面上很少有直接介绍ISP的书籍或者资料,今天我们主要是聊一聊ISP算法的架构,这样大...

OpenFPGA的博客 5405

自主编写 Babel 插件的完整指南

自主编写 Babel 插件的完整指南

嗨,欢迎来到我的 优快云 博客小天地!一名深耕多年的技术发烧友。在这里,我将把日常工作中积累的宝贵经验,从复杂架构设计的精妙之处,到代码优化的实战技巧,毫无保留地分享给大家。 1776

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Babel 插件 jsx-v-model 指南

Babel 插件 jsx-v-model 指南 本指南旨在详细介绍开源项目 babel-plugin-jsx-v-model 的关键组件,包括其目录结构、启动文件以及配置文件,帮助开发者快速上手并有效利用此插件在 JSX 中实现 v-model 风格的数据绑定。 1. 项目目录结构及介绍 ├── LICENSE ├── package.json ├── README.md // 项目说...

gitblog_00918的博客 764

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Babel 插件:Kneden 快速上手与实践指南

Babel 插件:Kneden 快速上手与实践指南 项目介绍 Kneden 是一个由 Marten de Vries 创建的开源项目,专为那些希望将现代的 ES2017 异步/等待语法(async/await)转换为更广泛兼容的 ES6 Promise 链的开发者设计。这个项目作为一个 Babel 插件,使得前端开发在保持代码清晰和可读性的同时,能够充分利用较新 JavaScript 版本的特性,...

gitblog_00657的博客 804

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Babel插件开发入门指南

文章概览 主要包括:Babel如何进行转码、插件编写的入门基础、实例讲解如何编写插件。 阅读本文前,需要读者对Babel插件如何使用、配置有一定了解,可以参考笔者之前的文章。 本文所有例子可以在 笔者的github 找到,欢迎访问笔者博客获取更多相关文章。 Babel运行阶段 首先来了解Babel转码的过程分三个阶段:分析(parse)、转换(transform)、生成(generate...

dengrong8117的博客 189

process插件_Babel插件开发入门指南

文章概览主要包括:Babel如何进行转码、插件编写的入门基础、实例讲解如何编写插件。Babel运行阶段首先来了解Babel转码的过程分三个阶段:分析(parse)、转换(transform)、生成(generate)。其中,分析、生成阶段由Babel核心完成,而转换阶段,则由Babel插件完成,这也是本文的重点。分析Babel读入源代码,经过词法分析、语法分析后,生成抽象语法树(AST)parse...

weixin_39661353的博客 444

Vue.js Babel 预设插件:babel-preset-vue-app 使用指南

Vue.js Babel 预设插件:babel-preset-vue-app 使用指南 1. 项目介绍 [已废弃] 此仓库 babel-preset-vue-app 是 Vue 应用专为 Babel 配置的预设插件,致力于简化 Vue.js 项目的转译设置。它集成了一系列现代 JavaScript 特性支持,包括通过 babel-preset-env 提供的最新 ECMAScript 版本特性、对...

gitblog_00796的博客 683

配置babel_Babel插件开发入门指南

文章概览主要包括:Babel如何进行转码、插件编写的入门基础、实例讲解如何编写插件。Babel运行阶段首先来了解Babel转码的过程分三个阶段:分析(parse)、转换(transform)、生成(generate)。其中,分析、生成阶段由Babel核心完成,而转换阶段,则由Babel插件完成,这也是本文的重点。分析Babel读入源代码,经过词法分析、语法分析后,生成抽象语法树(AST)parse...

weixin_34416909的博客 612

Babel插件开发全流程:从设计到发布的终极指南

Babel是一个通用的JavaScript多用途编译器,更是一个可用于多种静态分析的模块集合。Babel插件开发是扩展Babel功能的关键方式,本指南将带你从设计到发布,完整掌握Babel插件开发的全流程。 ## 一、Babel插件开发基础概念 ### 1.1 AST:抽象语法树 Babel的核心是对抽象语法树(AST)的操作。AST是代码的结构化表示,每个节点代表代码中的一个语法结构。例如,

gitblog_00956的博客 1303

如何快速掌握Babel插件开发:从AST到实战的完整指南

Babel是一个通用的JavaScript多用途编译器,也是一套可用于多种静态分析形式的模块集合。通过Babel,开发者可以使用和创建下一代JavaScript语法及工具,将现代JavaScript代码转换为向后兼容的版本,使其能在当前环境中运行。本指南将带你从基础开始,逐步掌握Babel插件开发的核心知识和实践技巧。 ## Babel工作原理:解析、转换与生成 Babel的工作流程主要分为三

gitblog_00334的博客 415

深入浅出Babel插件开发:从AST到代码转换的完整指南

摘要:Babel插件是前端开发中的强大工具,能够将现代JavaScript代码转换为兼容旧浏览器的版本。它通过解析代码生成AST(抽象语法树),使用Visitor模式遍历和修改节点,最终生成优化后的代码。Babel插件可以处理语法转换、API填充、代码优化等任务,支持提前使用实验性语法和框架特定转换(如JSX)。开发Babel插件需要理解AST结构,可通过AST Explorer工具直观学习。核心流程包括解析、转换和生成三个阶段,插件通过配置Visitor对象实现代码转换,为开发者提供了灵活的代码处理能力。

weixin_43359503的博客 1032
上一篇: 绘画作品简介
gcc_front
博客等级 码龄9年 16粉丝 98原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值