ts-node
repository·main·Indexed 11 days ago
https://github.com/typestrong/ts-nodeTypeScript execution environment and REPL for Node.js, version 11.0.0-beta.1. It provides JIT transformation of TypeScript into JavaScript for direct execution without manual pre-compilation, featuring automatic sourcemaps, tsconfig.json parsing, and native ESM loader support. Supports high-performance transpilation via SWC.
What's inside ts-node
- ts-node is a TypeScript execution engine and REPL for Node.js. It allows you to directly execute TypeScript files on Node.js without a manual pre-compilation step. It achieves this by hooking into Node.js module loading APIs, which enables seamless integration with existing Node.js tools, libraries, and workflows.
Overview of ts-node
maints-node is a TypeScript execution engine and REPL for Node.js. It JIT (Just-In-Time) transforms TypeScript into JavaScript, allowing you to execute TypeScript directly on Node.js without a separate pre-compilation step. It achieves this by hooking into Node's module loading APIs, making it compatible with other Node.js tools and libraries.
Key features include:
- Automatic sourcemaps in stack traces
- Automatic
tsconfig.jsonparsing - Automatic defaults matching your Node.js version
- Optional typechecking
- REPL (Read-Eval-Print Loop)
- Native ESM loader support
- Support for third-party transpilers and custom transformers
Understand the purpose of the dist-raw directory
mainThe
dist-rawdirectory contains JavaScript source files that are distributed verbatim. These files are not compiled or type-checked via TypeScript. They are used to implement ESM support by duplicating certain Node.js built-in functionalities that are not exposed via a public API.Note on Node.js versioning: Because these files are pulled from a specific version of Node.js, users running different versions of Node (e.g., Node 14) might experience behavior that mimics a different version (e.g., Node 18) due to these included sources.
Understand Yarn PnP interop requirements
mainTo achieve interoperability with Yarn Plug'n'Play (PnP),ts-noderelies on a specific division of labor: Yarn PnP is responsible only for mapping unqualified import specifiers (non-relative, non-absolute dependencies likelibfooor@scope/libfoo) to their unqualified disk locations viaresolveToUnqualified.ts-node(or the consumer) must then handle all subsequent resolution tasks, such as file extension resolution and path manipulation, using the path provided by PnP.Configure file scoping and ignored files
maints-node uses "scoping" to decide which files to transform. You can control this behavior using several options:
- Skipping
node_modules: By default, ts-node avoids compiling files in/node_modules/for performance and compatibility. To import uncompiled TypeScript fromnode_modules, use the--skipIgnoreflag or theTS_NODE_SKIP_IGNOREenvironment variable. - Skipping pre-compiled TypeScript: If a
.jsfile exists with the same name as a.tsfile, ts-node will import the.jsfile by default. Use--preferTsExtsto force the use of TypeScript source. - Scope by directory: Use the
scopeorscopeDiroptions to limit transformation to specific directories. - Ignore by regexp: Use the
ignoreoption to provide one or more regular expressions for files that should be skipped.
Warning: An ignored file is not prevented from execution; it is simply not transformed. If a file requires transformation but is ignored,
nodemay fail to resolve it or attempt to execute it as vanilla JavaScript, leading to syntax errors.- Skipping
How ts-node works internally
maints-node enables TypeScript execution in Node.js by registering hooks for
.ts,.tsx,.js, and.jsxfile extensions.When a file is requested, the
ts-nodehook intercepts the loading process. It transforms the TypeScript code into JavaScript in memory, respecting your project'stsconfig.jsonsettings (simulating the behavior oftsc), and then passes the resulting JavaScript to the vanillanodeengine for execution.Additionally,
ts-noderegisters hooks to:- Apply sourcemaps to stack traces for easier debugging.
- Remap
.jsimports to their corresponding.tsfiles to allow seamless TypeScript module resolution.
How ts-node works
maints-node works by registering hooks for.ts,.tsx,.js, and/or.jsxextensions. Whennodeattempts to load these files, the ts-node hook intercepts the process, transforms the TypeScript code into JavaScript (respecting yourtsconfig.json), and passes the result back tonodefor execution. It also applies sourcemaps to stack traces and remaps.jsimports to.tsfiles.Key features of ts-node
maints-node provides several features for TypeScript development in Node.js environments:
- Execution & Transformation: JIT transforms TypeScript to JavaScript; supports native ESM loaders; allows use of third-party transpilers and custom transformers.
- Developer Experience: Includes a REPL; provides automatic sourcemaps in stack traces; automatically parses
tsconfig.json. - Configuration: Automatically sets defaults to match your Node.js version; offers optional typechecking.
- Integration: Can be used to write standalone scripts; integrates with test runners, debuggers, and CLI tools; is compatible with pre-compilation workflows for production environments.
Understand the raw directory and naming conventions
mainThe
rawdirectory contains unmodified copies of Node.js source files used for diffing against the modified files indist-raw.Naming Convention
Files follow a pattern derived from their path within Node's
lib/directory, replacing slashes with hyphens:node-<directory>(...-<directory>)-<filename>.jsExample:
node-internal-errors.jscorresponds tolib/internal/errors.jsin the Node.js source.File Suffixes in the raw directory
- Version/Revision: Files are suffixed with the version or revision number they were downloaded from.
strippedsuffix: Files with a-strippedsuffix have large chunks of code deleted but no other modifications. These are intended to be used for easier diffing against the smaller, modified files found indist-raw.
Write your own transpiler plugin
mainTo create a custom transpiler plugin, you must create a module that exports a
createfunction conforming to theTranspilerModuleinterface.ts-nodewillrequire()your module at startup and invoke thecreatefunction to instantiate one or more transpiler instances. These instances are then responsible for transforming TypeScript source code into JavaScript.Your plugin can be a local script or a published npm module.
Use experimental ESM features
mainFor advanced ESM handling,
ts-nodeprovides experimental features:experimentalResolver: Enables hooks to re-map imports (e.g., mapping.jsimports to.tsfiles). This can be enabled viatsconfig.jsonor the API.experimentalSpecifierResolution: Mimics Node's specifier resolution algorithm. Requires--esmto be enabled. (Default:explicit)
Why ts-node does not support paths natively
mainThe
pathsproperty intsconfig.jsonis designed to inform the TypeScript compiler about transformations that are expected to happen during the build process. According to the TypeScript Handbook, the compiler uses this information to guide module resolution to definition files, but it does not perform the transformations itself.Because
pathsare intended to describe mappings that a build tool or runtime already performs,ts-nodedoes not modifynode's native module resolution behavior to implement them. To use them at runtime withts-node, you must use an external helper liketsconfig-paths.