ts-node

repository·main·Indexed 11 days ago

https://github.com/typestrong/ts-node

TypeScript 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.

Tokens
28.2K
Snippets
108
Records
156
Agent score
95%

What's inside ts-node

  1. What is ts-node?

    main
    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.
  2. Overview of ts-node

    main

    ts-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.json parsing
    • 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
  3. Understand the purpose of the dist-raw directory

    main

    The dist-raw directory 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.

  4. Understand Yarn PnP interop requirements

    main
    To achieve interoperability with Yarn Plug'n'Play (PnP), ts-node relies on a specific division of labor: Yarn PnP is responsible only for mapping unqualified import specifiers (non-relative, non-absolute dependencies like libfoo or @scope/libfoo) to their unqualified disk locations via resolveToUnqualified. 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.
  5. Configure file scoping and ignored files

    main

    ts-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 from node_modules, use the --skipIgnore flag or the TS_NODE_SKIP_IGNORE environment variable.
    • Skipping pre-compiled TypeScript: If a .js file exists with the same name as a .ts file, ts-node will import the .js file by default. Use --preferTsExts to force the use of TypeScript source.
    • Scope by directory: Use the scope or scopeDir options to limit transformation to specific directories.
    • Ignore by regexp: Use the ignore option 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, node may fail to resolve it or attempt to execute it as vanilla JavaScript, leading to syntax errors.

  6. How ts-node works internally

    main

    ts-node enables TypeScript execution in Node.js by registering hooks for .ts, .tsx, .js, and .jsx file extensions.

    When a file is requested, the ts-node hook intercepts the loading process. It transforms the TypeScript code into JavaScript in memory, respecting your project's tsconfig.json settings (simulating the behavior of tsc), and then passes the resulting JavaScript to the vanilla node engine for execution.

    Additionally, ts-node registers hooks to:

    • Apply sourcemaps to stack traces for easier debugging.
    • Remap .js imports to their corresponding .ts files to allow seamless TypeScript module resolution.
  7. How ts-node works

    main
    ts-node works by registering hooks for .ts, .tsx, .js, and/or .jsx extensions. When node attempts to load these files, the ts-node hook intercepts the process, transforms the TypeScript code into JavaScript (respecting your tsconfig.json), and passes the result back to node for execution. It also applies sourcemaps to stack traces and remaps .js imports to .ts files.
  8. Key features of ts-node

    main

    ts-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.
  9. Understand the raw directory and naming conventions

    main

    The raw directory contains unmodified copies of Node.js source files used for diffing against the modified files in dist-raw.

    Naming Convention

    Files follow a pattern derived from their path within Node's lib/ directory, replacing slashes with hyphens: node-<directory>(...-<directory>)-<filename>.js

    Example: node-internal-errors.js corresponds to lib/internal/errors.js in 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.
    • stripped suffix: Files with a -stripped suffix 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 in dist-raw.
  10. Write your own transpiler plugin

    main

    To create a custom transpiler plugin, you must create a module that exports a create function conforming to the TranspilerModule interface.

    ts-node will require() your module at startup and invoke the create function 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.

  11. Use experimental ESM features

    main

    For advanced ESM handling, ts-node provides experimental features:

    • experimentalResolver: Enables hooks to re-map imports (e.g., mapping .js imports to .ts files). This can be enabled via tsconfig.json or the API.
    • experimentalSpecifierResolution: Mimics Node's specifier resolution algorithm. Requires --esm to be enabled. (Default: explicit)
  12. Why ts-node does not support paths natively

    main

    The paths property in tsconfig.json is 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 paths are intended to describe mappings that a build tool or runtime already performs, ts-node does not modify node's native module resolution behavior to implement them. To use them at runtime with ts-node, you must use an external helper like tsconfig-paths.