搜索词
序列化/反序列化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 相一致。
4条答案
按热度按时间xlpyo6sf1#
我无法在这方面取得任何进展。
SourceFile
节点嵌套得很深,将它们转换为字符串使得它们太大而无法存储。我正在努力提高浏览器内语言服务的启动时间(类似于Monaco),因此,脱水的SourceFile
需要足够小,才能存储在IndexedDB中。tmb3ates2#
你好,我也遇到了序列化
SourceFile
的问题。有明确的方法可以做到这一点吗?查阅了文档:https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API#document-registry 提到了,但没有关于如何做到这一点的示例。
d6kp6zgx3#
我们需要一些直接受益于TypeScript的用例,特别是在
tsc
类似的场景中,否则这可能只是其他解析器可以做的事情。我们做了很多事情,比如具有特定的节点构造函数来提取额外的性能,在这里所做的任何事情都必须对此具有容忍性。nnvyjq4y4#
在#3662中似乎有关于这个的初步说明。出于与#3662中列出的相同原因,我对这个也很感兴趣 - 更快速的启动时间。根据
createDocumentRegistryInternal
方法和ExternalCache
选项,这似乎是曾经考虑过但从未实现的东西。如果我在#3662中实施这些提示有任何进展,我会回报的。