TSX
The easiest way to run TypeScript
in Node.js
.
Background
不管是 Typescript
的编辑器 tsc
和 esbuild
的 transform
api 在转译后并不会对路径进行重写操作。
The reason why tsc
does not perform rewriting paths
从
paths
的说明中可以得知:Note that this feature does not change how import paths are emitted by tsc, so paths should only be used to inform TypeScript that another tool has this mapping and will use it at runtime or when bundling.
paths
的配置项仅用来告知typescript
一件事情,其他工具会在运行时或构建阶段处理路径重写工作。对于typescript
自身来说,主要是引导typescript
正确的类型检测工作,同时确保 编辑器 不报类型错误。从 Module resolution 中可以得知:
TypeScript doesn’t modify import specifiers during emit: the relationship between an import specifier and a file on disk (if one even exists) is host-defined, and TypeScript is not a host.
告知了
typescript
不重写导入路径的根本原因:导入说明符(
import specifier
)与实际文件之间的关系是由 宿主环境 定义的,而typescript
并 不是 宿主环境。这不是一个缺陷,而是一个经过深思熟虑的设计决策,应该利用合适的构建工具来处理 路径重写 的需求。
The reason why esbuild
's transform
API does not perform rewriting paths
从 官方文档 的说明中可以得知:
These options affect esbuild's resolution of import/require paths to files on the file system. You can use it to define package aliases and to rewrite import paths in other ways. Note that using esbuild for import path transformation requires bundling to be enabled, as esbuild's path resolution only happens during bundling. Also note that esbuild also has a native alias feature which you may want to use instead.
esbuild
的路径解析特性仅在 构建阶段 会执行,转译阶段并不会执行路径重写工作。
Existing Solutions
tsc-alias
tsc-alias
会在 tsc
转译 ts
为 js
模块后检查生成的 js
模块,然后根据 tsconfig.json
中的 complier.paths
配置项规则来替换掉别名路径。
执行指令:
npx tsc && npx tsc-alias
参考 issue #81
可以看出 tsc-alias
是分步执行的,并不支持运行时使用。
tsconfig-paths
支持运行时加载和支持 api
加载。typescript
默认模仿 node.js
运行时模块解析策略。不一样的是 typescript
也支持使用路径映射,允许指定任意模块路径(不以 "/"
或 "."
开头)并将其映射到文件系统中的物理路径。typescript
编译器可以通过用户配置的 tsconfig.json
的 paths
配置项来解析这些路径,因此会成功编译。但如果尝试使用 node
(或 ts-node
)执行 typescript
编译后的 js
文件,则并不会尊重 tsconfig.json
中的 paths
配置项,而是会查找 node_modules
文件夹直至文件系统根目录。
tsconfig-paths/register
模块会引导 node
(或 ts-node
)从 tsconfig.json
或 jsconfig.json
读取路径,并将其转换为实例的物理文件路径。
ts-node -r tsconfig-paths/register main.ts
不过这需要额外安装 ts-node
和 tsconfig-paths
包,并且需要手动执行 ts-node -r tsconfig-paths/register main.ts
指令就显得有些麻烦了。
tsx
解决了上述的痛点,不需要额外安装其他的依赖包,在运行时通过重写 就支持路径重写,同时还借助 esbuild
的 transform api
来快速转译 ts
文件,提高的执行效率。