TSX
The easiest way to run TypeScript
in Node.js
.
Background
Neither Typescript
's editor tsc
nor esbuild
's transform
API performs path rewriting operations after transpilation.
The reason why tsc
does not perform rewriting paths
From the explanation of
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.
The
paths
configuration item is only used to informtypescript
that other tools will handle path rewriting at runtime or during the build phase. Fortypescript
itself, it mainly guidestypescript
to perform correct type checking and ensures that the editor does not report type errors.From 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.
This explains the fundamental reason why
typescript
does not rewrite import paths:The relationship between an import specifier and the actual file is defined by the host environment, and
typescript
is not the host environment. This is not a defect, but a well-considered design decision. Appropriate build tools should be used to handle path rewriting requirements.
The reason why esbuild
's transform
API does not perform rewriting paths
From the official documentation:
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
's path resolution feature is only executed during the build phase, and path rewriting is not performed during the transpilation phase.
Existing Solutions
tsc-alias
tsc-alias
checks the generated js
modules after tsc
transpiles ts
to js
modules, and then replaces alias paths according to the rules in the complier.paths
configuration item in tsconfig.json
.
Execution command:
npx tsc && npx tsc-alias
Referring to issue #81
, it can be seen that tsc-alias
is executed in steps and does not support runtime usage.
tsconfig-paths
Supports runtime loading and API loading. typescript
by default mimics node.js
runtime module resolution strategy. The difference is that typescript
also supports using path mapping, allowing specification of arbitrary module paths (not starting with "/"
or "."
) and mapping them to physical paths in the file system. The typescript
compiler can resolve these paths through the paths
configuration item in the user-configured tsconfig.json
, thus compiling successfully. However, if you try to execute the js
files compiled by typescript
using node
(or ts-node
), it will not respect the paths
configuration item in tsconfig.json
, but will search the node_modules
folder up to the file system root.
The tsconfig-paths/register
module guides node
(or ts-node
) to read paths from tsconfig.json
or jsconfig.json
and convert them to physical file paths of the instance.
ts-node -r tsconfig-paths/register main.ts
However, this requires additional installation of ts-node
and tsconfig-paths
packages, and manually executing the ts-node -r tsconfig-paths/register main.ts
command seems somewhat cumbersome.
tsx
solves the above pain points. It doesn't require additional dependencies, supports path rewriting at runtime through rewriting, and also uses esbuild
's transform api
to quickly transpile ts
files, improving execution efficiency.