Open SyMind opened 1 year ago
催更大佬
主要是swc的项目感觉有点乱,文档也少,想调用的话根本不知道怎么办
@Dangerised 剩余文章你可以在掘金中看到
深入理解 swc - 第一部分,使用 https://juejin.cn/post/7218469497585336376 深入理解 swc - 第二部分,词法分析 https://juejin.cn/post/7280000052210876479 深入理解 swc - 第三部分,语法分析 https://juejin.cn/post/7283766466083471396
关于 swc 的调用,更多是关于访问者模式的使用,这部分我还没有写,计划在2月份写完。
PS:我其实都忘记我在 Github 中也同步记录了这些文章。
@SyMind 感谢大佬
学习,最近也在研究 Swc 了,感谢分享
写在前面的
在万字 esbuild 源代码批判,让你能够直接 PR 文章中详细研究了 esbuild 项目,为达到极限的编译速度,它的编译过程十分紧凑,仅有两次整体 AST 树传递。
这并非没有代价,esbuild 中对 AST 的解析、适配低版本语法、代码压缩等流程紧密耦合,难以基于它开发 vue、svelte 编译器(目前 esbuild 对于 Vue 和 Svelte 都是使用 js 编写的编译器处理后,在通过进程间通信传递转换后的结果)。而且目前 esbuild 中核心的数据结构和类型定义均位于 internal 目录下,开发者无法进行访问。
这就是要研究 swc 的理由。
目录结构
swc 通过 Cargo 的 workspace 管理多个相关的协同开发的 crate,它们位于 crates 目录下。
bindings 目录下的 crate 未放到 workspace 下的原因是,绑定程序使用已发布的
swc_core
SDK 来构建特定平台的绑定。若放置到 workspace 下时,可能使用并未发布的依赖的版本,导致混乱。使用 swc
文章是为了阅读 swc 的源代码,所以这里指的是通过 rust 使用 swc。下面是一个使用 swc 简单的例子,这段代码就位于 swc 项目中
crates/swc/examples/transform.rs
。上面的程序做了以下事情:
SourceMap
实例,由于该数据资源在同一时刻可拥有多个所有者,且可在线程间共享,故通过Arc
智能指针持有该值。Compiler
实例。cm
的load_file
方法加载 js 文件 examples/transform-input.js。cm
作为参数,调用c
的process_js_file
方法处理 js 文件。try_with_handler
会创建一个Handler
实例作为process_js_file
的参数,来处理错误信息。其返回值为Result
枚举,通过unwrap
方法,如果返回成功,就将Ok(T)
中的值取出来,如果失败,就直接panic
。涉及到 swc 中定义的
SourceMap
和Compiler
两个结构体,我们详细了解一下它们。SourceMap 结构体
SourceMap
记录所有所使用的源代码,可以将字节位置映射到源代码中的具体位置。解析过程中的每个源数据(通常是文件、字符串或宏扩展)都存储在SourceMap
中,表示为SourceFiles
。字节位置存储在span
中,并在编译器中广泛使用。它是SourceMap
绝对位置,可以将其转换为行列信息、源代码片段等。通过调用
SourceMap
实例的load_file
方法,传入 js 文件路径获取SourceFile
实例,SourceFile
的结构如下:Compiler 结构体
Compiler
结构体存储SourceMap
,提供用于编译 js 文件的方法。Handler 结构体
Compiler
提供的所有方法都需要传入一个Handler
结构体,除了会导致 swc 立即退出的错误,其他错误会通过Handler
结构体记录用于后续进行错误报告。Handler
结构体如下:swc 中还创建了一个
HANDLER
全局变量,它还是一个线程局部变量,try_with_handler
方法中会创建一个Handler
实例,并将实例注册到HANDLER
全局变量上。这种设计使得开发 swc 扩展时,让开发者进行错误报告更加简单:处理流程
回到
Compiler
的process_js_file
方法,它的处理流程与其他编译器一般无二,也将经历词法分析、语法分析、代码生成等阶段,简略流程如下:最后
这部分主要介绍 swc 最基本的使用和
SourceMap
和Compiler
两个结构体,下一部分会按照process_js_file
方法的处理流程逐步展开 swc 的内部实现。