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
pathsconfiguration item is only used to informtypescriptthat other tools will handle path rewriting at runtime or during the build phase. Fortypescriptitself, it mainly guidestypescriptto 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
typescriptdoes not rewrite import paths:The relationship between an import specifier and the actual file is defined by the host environment, and
typescriptis 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-aliasReferring 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.tsHowever, 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.