Deno 如何在不以“watch”模式运行 TypeScript 编译器的情况下快速启动

Posted

技术标签:

【中文标题】Deno 如何在不以“watch”模式运行 TypeScript 编译器的情况下快速启动【英文标题】:How is Deno startup fast without running the TypeScript compiler in "watch" mode 【发布时间】:2019-06-27 14:28:16 【问题描述】:

据我所知,Deno 总是在启动时将 TypeScript 编译为 JS,并且没有“监视”模式。 我的理解也是,除了 TS 监视模式之外,TypeScript 没有“增量编译”之类的东西。因此,如果想要快速 TS 编译,就必须使用 watch 模式。

所以我希望 Deno 有一个监视模式。但事实并非如此。那么 Deno 的 TS 编译速度如何?

注意:我知道 Deno 使用 tsc 的 V8 快照,以便 tsc 快速启动,但是对于大型 TS 项目,tsc 的启动时间与实际编译时间相比会相形见绌。所以我不是在问 V8 快照,我问的是 Deno 还使用了哪些其他技巧。它是否使用构建守护进程?

【问题讨论】:

【参考方案1】:

如果本地源文件未更改(或远程模块缺少 --reload 标志),Deno 会缓存 TypeScript 的转译输出并在后续模块请求中使用该输出。

从 Deno 0.2.8 开始,TypeScript 会在需要转译 TypeScript 模块时延迟实例化。 Deno 逐个模块而不是整个项目进行编译,并缓存每个单独模块的结果。因此,当仅对单个文件进行更改时,只会转译该模块。

由于这种单文件方法,它确实意味着您有时会遇到运行时错误,这些错误会被 TypeScript 编译器捕获。如果你想确保你的程序从类型的角度来看是完全一致的,使用--recompile会导致每个模块都被重新编译。

可以添加监视功能,但这将是一个功能请求。但是,由于运行时环境的工作方式,处理此类功能存在重大挑战。

【讨论】:

那么期望用户使用 IDE 来捕获类型错误吗?此外,这种逐个文件的方法是否意味着依赖跨文件信息的功能(如const enum)在 Deno 中不起作用? > 那么用户是否期望用户使用 IDE 来捕获类型错误?不完全是。编译 TypeScript 时,编译器将收集所有依赖项并执行 .emitFile() 并注销已生成的任何诊断。这类似于 IDE 如何与语言服务一起工作,并获取诊断输出并在红色曲线下划线。 Deno 编译器会将它获取的所有源代码缓存在内存中,因此如果您正在处理多个文件,它只会在注入 ESM 模块时发出 V8 请求的每个文件。 const enum(和enum)可以工作,因为 TypeScript 编译器拥有转换文件所需的所有信息。目前我们可能想要解决的唯一“风险”是它不会使已转译模块的缓存无效,因此如果您在文件a.ts 中更改了const enum,但它被导入到b.ts但是您没有更改 b.ts 否则,您最终可能会不同步。使用 const enum b.ts 仍将使用“硬连线”值,如果它们被外部依赖,这可能是一个问题。 Deno 如何处理增量编译进入奇怪状态@Kitson 的情况?是否有 --clean 或 --force 之类的?考虑到我必须在 VS Code 中重新启动 TS 语言服务器多少次,如果奇怪的状态不是问题,我会感到惊讶。 再次声明,目前没有 watch 模式,所以 TypeScript 编译器状态不会持久化。启动时,它会编译它需要的每个 TypeScript 模块,然后什么也不做。 --recompile 将使缓存无效并强制 TypeScript 重新编译所有模块,无论发出是否被缓存。

以上是关于Deno 如何在不以“watch”模式运行 TypeScript 编译器的情况下快速启动的主要内容,如果未能解决你的问题,请参考以下文章

我如何在公司代理后面运行Deno

如何学习Deno

如何在不刷新整个页面的情况下让 Grunt/Watch/LiveReload 重新加载 Sass/CSS?

如何在 Deno 中构建一个 URL 短链生成器

运行Create-React-App测试不在Watch模式下

如何使用/获取 Apple Watch 全屏模式