Project Icon

tsimp

Node.js高性能TypeScript模块加载器 支持完整类型检查

tsimp是专为Node.js设计的TypeScript模块加载器,采用微软官方TypeScript实现。它通过持久化守护进程和大量缓存提高性能,同时保持完整的类型检查。tsimp确保与tsc程序严格一致,支持Node v20.6新特性,专注模块加载并默认启用类型检查。无需额外tsc步骤,适合频繁运行TypeScript程序的开发环境。

tsimp 😈

Node.js 的 TypeScript 导入加载器

简介

这是一个使用微软官方 TypeScript 实现来运行用 TypeScript 编写的 Node.js 程序的导入器。

它旨在提供完整的类型检查支持,并在重复使用时(例如,在生成多个 TS 进程的测试套件中)具有可接受的性能。

为什么需要它

市面上有很多 TypeScript 加载器和编译器!你应该选择哪一个,为什么我需要创建这个呢?

  • swc 是用 Rust 实现的 TypeScript 编译器
  • tsx 是一个零配置的 TypeScript 执行器,旨在成为 node 的直接替代品,由 esbuild 提供支持。
  • ts-node 可能是其中最成熟的,具有庞大的功能集,支持你可能需要的所有 node 和 TypeScript 版本。

tsimp 的不同之处:

  • 它使用微软的 TypeScript 实现作为编译器。对 swc 和 esbuild 没有不敬之意,它们快速且功能强大,但 tsimp 的目标是与"官方" tsc 程序严格一致,而直接使用它是最简单的方法。
  • 它支持 node v20.6 中添加的 --importModule.register() 行为,只在不可用时才退回到带有警告的实验性 API。
  • 默认启用类型检查,因此无需在运行测试后再执行额外的 tsc --noEmit 步骤,使用持久的 sock daemon 和大量缓存来提高性能。
  • 它只是一个模块加载器,而不是其他东西的集合。所以没有 repl,没有打包器等。它基本上只做一件事:让 TypeScript 模块在 Node 中工作。

使用方法

使用 npm 安装 tsimp

npm install tsimp

在 node v20.6 及更高版本中这样运行 TypeScript 程序:

node --import=tsimp/import my-typescript-program.ts

或在 v20.6 之前的 Node 版本中这样运行:

node --loader=tsimp/loader my-typescript-program.ts

你也可以使用 tsimp 作为可执行文件来运行你的程序(但 import/loader 方式快约 100ms,因为它不会产生额外的 spawn 调用):

tsimp my-typescript-program.ts

注意,虽然不带参数运行 tsimp 将启动 Node repl,并且在该上下文中它能够导入/require TypeScript 模块,但它并不包含可以直接运行 TypeScript 的 repl。这只是一个导入加载器。

在 Node v20.6 及更高版本中,你还可以在程序中加载 tsimp,之后 TypeScript 模块就可以直接使用了。

注意,import 声明在代码执行之前并行发生,所以你需要像这样拆分:

import 'tsimp'
// 必须作为异步 import() 完成,以便在 tsimp 导入完成后进行。
// 但 TypeScript 程序中的任何导入都可以是"正常"的顶级导入。
const { SomeThing } = await import('./some-thing.ts')

相比之下,这样是不行的,因为导入是并行发生的:

import 'tsimp'
import { SomeThing } from './some-thing.ts'

CommonJS 的 require() 也被修补了。要在 CommonJS 程序中使用 tsimp,你可以按上述方式运行它,或在程序中 require() 它。

//commonjs
require('tsimp')
// 现在可以加载 TypeScript
require('./blah.ts')

在 Node 20.6 及更高版本中,这也会附加 ESM 导入支持所需的加载器。在早期 Node 版本中,你必须使用 --loader=tsimp/loader 来支持 ESM。

配置

大多数配置是通过查找模块入口点所在或其上级文件夹树中最近的 tsconfig.json 文件来完成的。

你可以通过在环境中设置 TSIMP_PROJECT=<filename> 来使用不同的文件名。

如果 tsconfig json 文件中有 tsimp 字段,那么它将覆盖文件中的其他任何内容。例如:

{
  "compilerOptions": {
    "rootDir": "./src",
    "declaration": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "inlineSources": true,
    "jsx": "react",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "noUncheckedIndexedAccess": true,
    "resolveJsonModule": true,
    "skipLibCheck": false,
    "sourceMap": false,
    "strict": true,
    "target": "es2022"
  }
  "tsimp": {
    "compilerOptions": {
      "skipLibCheck": true,
      "strict": false
    }
  }
}

使用 tsimp 时始终启用源映射,以便错误引用 TypeScript 代码中的适当调用位置。

配置文件更改和 extends 选项

如果 tsimp 使用的 tsconfig.json 文件发生更改,它将自动使其内存和磁盘缓存过期,因为新选项可能会导致非常不同的结果。

然而,虽然完全支持 extends(如果 tsc 可以加载它,tsimp 也可以,因为这就是它加载配置的方式),但任何扩展的配置文件都不会被跟踪变化或导致缓存过期。

如有疑问,tsimp --restart 将根据需要重新加载所有内容。

"module""moduleResolution" 和其他必需项

tsimp 的最终模块样式必须是 Node 可理解的,无需任何额外的打包或转译。

为此,无论 tsconfig.json 中的设置如何,modulemoduleResolution 设置都在 tsimp 中硬编码为 NodeNext

此外,tsimp 总是硬编码以下字段:

  • outDir 因为 tsimp 不是构建工具,而是模块导入器,它实际上不会将生成的 JavaScript 写入磁盘。(好吧,从技术上讲它确实写入了,但只是作为缓存。)所以,outDir 被硬编码为 .tsimp-compiled,但这从未被使用。
  • sourceMap 总是设置为 undefined,因为:
  • inlineSourceMap 总是设置为 true。将源映射内联到生成的 JavaScript 输出中要简单和快速得多。
  • inlineSources 总是设置为 false。当输入肯定存在于磁盘上时,没有必要增加输出的大小。
  • declarationMapdeclaration 总是设置为 false,因为类型声明是无关紧要的。
  • noEmit 总是设置为 false,因为整个目的是获取 Node 运行的 JavaScript 代码。话虽如此,"emit" 是完全虚拟的,不会向磁盘写入任何内容(除非为了避免多次编译相同的代码)。

文件扩展名、模块解析等

使用tsimp时,文件扩展名、模块解析和其他方面的规则与使用tsc时相同。

这意味着:如果你在ESM模式下运行,即使磁盘上的实际文件是.ts,你也需要将导入语句的文件名以.js结尾,因为当module设置为"NodeNext"且目标方言是ESM时,TypeScript就是这样处理的。

编译诊断

设置TSIMP_DIAG环境变量来控制编译诊断出现时的行为。

  • TSIMP_DIAG=warn(默认)将诊断信息打印到stderr,但如果可能的话仍会转译代码。
  • TSIMP_DIAG=error将诊断信息打印到stderr,如果有任何诊断信息就会失败。
  • TSIMP_DIAG=ignore仅转译代码,忽略所有诊断信息。(类似于ts-node的TS_NODE_TRANSPILE_ONLY=1选项。)

它有多快?

如果守护进程正在运行,即使启用了类型检查,它也非常快。如果守护进程正在运行,并且之前已经编译过你正在运行的文件,它会快得惊人,快到你会觉得它是不是坏了,甚至超过了用Rust和Go编写的TypeScript编译器,因为它实际上只需要检查一些文件状态,然后将缓存的结果传给Node。(事实上,由于它在内存和磁盘上都进行缓存,在许多情况下可能甚至比运行普通的JavaScript还要快,特别是如果程序很大的话。)

而且,这是在进行完整的类型检查的情况下,这也是使用TypeScript的意义所在。无论你的编译器有多快,如果你随后还要运行tsc --noEmit来检查类型,那实际上并没有获得多少好处。

如果守护进程没有运行,而且是一次冷启动且没有缓存,那它会相当慢,特别是在启用类型检查的情况下,速度与ts-node相当。

下面是一个非常不科学的对比示例:

$ time node --loader @swc-node/register/esm hello.ts
(node:89220) ExperimentalWarning: `--experimental-loader`可能在未来被移除;请改用`register()`:
--import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("%40swc-node/register/esm", pathToFileURL("./"));'
(使用`node --trace-warnings ...`来显示警告的创建位置)
hello, world

real	0m0.268s
user	0m0.255s
sys	0m0.033s

$ time node --import=tsx hello.ts
hello, world

real	0m0.135s
user	0m0.126s
sys	0m0.020s

$ time node --import=./dist/esm/hooks/import.mjs hello.ts
hello.ts:2:18 - 错误 TS2322: 类型"string"不能赋给类型"boolean"。

2 const f: Foo = { bar: 'hello' }
                   ~~~

  hello.ts:1:14
    1 type Foo = { bar: boolean }
                   ~~~
    预期的类型来自此处声明的"Foo"类型的"bar"属性

hello, world

real	0m0.126s
user	0m0.110s
sys	0m0.022s

它为什么这么快?

漫画"我们需要让它运行得更快""用rust重写它""用zig重写它""使用基本的缓存和工作跳过"最后一个人被扔出窗外

基本的缓存和工作跳过。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号