TypeScript AST的序列化/反序列化API

44u64gxh  于 6个月前  发布在  TypeScript
关注(0)|答案(4)|浏览(60)

搜索词

序列化/反序列化AST节点
参考 #26871
参考 #28365

建议

实现/公开一个API,可以序列化/反序列化AST节点,尤其是一种将源文件序列化的方法,以便轻松传输或存储,可能进行操作并重新注入。
与此有些相关的是 #28365 ,它允许在某些用例中直接摄取AST。之前在 #26871 中建议出于性能原因这样做,但不是以一种可以轻易持久化的形式将AST外部化。

用例

特别是在Deno中,我们对在JavaScript运行时之外进行一些AST生成或操作感兴趣。在非JavaScript中进行一些计算密集型函数可以显著提高速度。例如,我们最初使用Mozilla的 source-map 包为JavaScript中的错误进行源Map重Map。然而,在0.7+版本中,Mozilla将其Rust转译为WASM的部分写入了源Map。我们能够在Deno的特权侧直接使用它,使用其原生Rust,并看到了大约100倍的性能提升。
目前,我们还不清楚具体如何使用它,尽管可能需要程序生成一些方面,如我们的运行时类型库或对AST进行一些变换以进行捆绑。我们已经尝试在JavaScript运行时中进行这种操作,想知道通过在Rust中做一些事情是否可以获得性能提升。
现在,完整的解析、转换和发射是“持久化”代码的唯一方法。如果您想进行进一步的更改,则需要重新解析。从逻辑上讲,这种暂时状态可以用于许多不同的高级用例。这在某种程度上也会使解析器和转换器与外部分离。
有许多基于AST生成器(如acorn和estree)的高级用例被人们构建起来,因此如果可用的话,其他高级用例也可以构建。
两个主要挑战可能是有很多循环引用,这使得JSON成为一个难以序列化的格式。SourceFile中有很多隐藏状态不属于表面对象。这必须作为序列化的一部分暴露出来,而现有节点中没有这些属性。
我开始查看 tsbuildinfo ,看看是否有某种编译器或AST状态被保存在某个地方,可以用来恢复编译器的 state 状态,但实际上还没有查看TypeScript内部是否可以序列化程序状态。

示例

const sourceFile = ts.createSourceFile("mymodule.ts", "console.log(\"hello\");", ts.ScriptTarget.ESNext, true);

// Returns a POJO of ts.SerializedNode?
const serializedSourceFile = ts.serialize(sourceFile);

// Because it is a POJO, it can be easily serialized
console.log(JSON.stringify(serializedSourceFile));

// Accepts a ts.SerializedNode?
const sourceFile2 = ts.deserialize(serializedSourceFile);

检查清单

我的建议符合以下准则:

  • 这不会对现有的TypeScript/JavaScript代码造成破坏性更改
  • 这不会改变现有JavaScript代码的运行时行为
  • 这可以在不根据表达式的类型发出不同的JS的情况下实现
  • 这不是一个运行时特性(例如库功能、带有JavaScript输出的非ECMAScript语法等)
  • 这个特性将与其他 TypeScript's Design Goals 相一致。
xlpyo6sf

xlpyo6sf1#

我无法在这方面取得任何进展。SourceFile节点嵌套得很深,将它们转换为字符串使得它们太大而无法存储。我正在努力提高浏览器内语言服务的启动时间(类似于Monaco),因此,脱水的SourceFile需要足够小,才能存储在IndexedDB中。

tmb3ates

tmb3ates2#

你好,我也遇到了序列化SourceFile的问题。有明确的方法可以做到这一点吗?查阅了文档:https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API#document-registry 提到了

A more advanced use of the document registry is to serialize SourceFile objects to disk 
and re-hydrate them when needed.

,但没有关于如何做到这一点的示例。

d6kp6zgx

d6kp6zgx3#

我们需要一些直接受益于TypeScript的用例,特别是在tsc类似的场景中,否则这可能只是其他解析器可以做的事情。我们做了很多事情,比如具有特定的节点构造函数来提取额外的性能,在这里所做的任何事情都必须对此具有容忍性。

nnvyjq4y

nnvyjq4y4#

#3662中似乎有关于这个的初步说明。出于与#3662中列出的相同原因,我对这个也很感兴趣 - 更快速的启动时间。根据createDocumentRegistryInternal方法和ExternalCache选项,这似乎是曾经考虑过但从未实现的东西。如果我在#3662中实施这些提示有任何进展,我会回报的。

相关问题