npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-patch

v3.3.0

Published

Patch typescript to support custom transformers in tsconfig.json

Downloads

986,141

Readme

npm version NPM Downloads Build Status

ts-patch

Patch typescript to allow custom transformers (plugins) during build.

Plugins are specified in tsconfig.json, or provided programmatically in CompilerOptions.

Migrating from ttypescript is easy! See: Method 1: Live Compiler

Features

  • Patch typescript installation via on-the-fly, in-memory patching or as a persistent patch
  • Can patch individual libraries (see ts-patch /?)
  • Hook build process by transforming the Program (see: Transforming Program)
  • Add, remove, or modify diagnostics (see: Altering Diagnostics)
  • Fully compatible with legacy ttypescript projects
  • (new) Experimental support for ES Module based transformers

Table of Contents

Installation

  1. Install package
<yarn|npm|pnpm> add -D ts-patch

Usage

Method 1: Live Compiler

The live compiler patches on-the-fly, each time it is run.

Via commandline: Simply use tspc (instead of tsc)

With tools such as ts-node, webpack, ts-jest, etc: specify the compiler as ts-patch/compiler

Method 2: Persistent Patch

Persistent patch modifies the typescript installation within the node_modules path. It requires additional configuration to remain persisted, but it carries less load time and complexity compared to the live compiler.

  1. Install the patch
# For advanced options, see: ts-patch /?
ts-patch install
  1. Add prepare script (keeps patch persisted after npm install)

package.json

{
 /* ... */
 "scripts": {
   "prepare": "ts-patch install -s"
 }
}

Configuration

tsconfig.json: Add transformers to compilerOptions in plugins array.

Examples

{
    "compilerOptions": {
        "plugins": [
            // Source Transformers
            { "transform": "transformer-module" },
            { "transform": "transformer2", "extraOption": 123 },
            { "transform": "trans-with-mapping", "resolvePathAliases": true },
            { "transform": "esm-transformer", "isEsm": true },

            // Program Transformer
            { "transform": "transformer-module5", "transformProgram": true }
        ]
    }
}

Plugin Options

| Option | Type | Description | |--------------------|---------|:--------------------------------------------------------------------------------------------------------------| | transform | string | Module name or path to transformer (*.ts or *.js) | | after | boolean | Apply transformer after stock TS transformers | | afterDeclarations | boolean | Apply transformer to declaration (*.d.ts) files | | transformProgram | boolean | Transform Program during ts.createProgram() (see: Program Transformers) | | isEsm | boolean | Transformer is ES Module (note: experimental — requires esm) | | resolvePathAliases | boolean | Resolve path aliases in transformer (requires tsconfig-paths) | | type | string | See: Source Transformer Entry Point (default: 'program') | | import | string | Name of exported transformer function (defaults to default export) | | tsConfig | string | tsconfig.json file for transformer (allows specifying compileOptions, path mapping support, etc) | | ... | | Provide your own custom options, which will be passed to the transformer |

Note: Required options are bold

Writing Transformers

For an overview of the typescript compiler (such as what a SourceFile and Program is) see: Typescript Compiler Notes.

Source Transformers

Source Transformers will transform the AST of SourceFiles during compilation, allowing you to alter the output of the JS or declarations files.

Source Transformer Entry Point

(program: ts.Program, config: PluginConfig, extras: TransformerExtras) => ts.TransformerFactory

PluginConfig: Type Declaration
TransformerExtras: Type Declaration
ts.TransformerFactory: (context: ts.TransformationContext) => (sourceFile: ts.SourceFile) => ts.SourceFile

Note: Additional legacy signatures are supported, but it is not recommended to develop a new transformer using them.

Source Transformer Example

Transformers can be written in JS or TS.

import type * as ts from 'typescript';
import type { TransformerExtras, PluginConfig } from 'ts-patch';

/** Changes string literal 'before' to 'after' */
export default function (program: ts.Program, pluginConfig: PluginConfig, { ts: tsInstance }: TransformerExtras) {
  return (ctx: ts.TransformationContext) => {
    const { factory } = ctx;
    
    return (sourceFile: ts.SourceFile) => {
      function visit(node: ts.Node): ts.Node {
        if (tsInstance.isStringLiteral(node) && node.text === 'before') {
          return factory.createStringLiteral('after');
        }
        return tsInstance.visitEachChild(node, visit, ctx);
      }
      return tsInstance.visitNode(sourceFile, visit);
    };
  };
}

Live Examples:

{ transform: "typescript-transform-paths" }

{ transform: "typescript-is/lib/transform-inline/transformer" }

{ transform: "typia/lib/transform" } (💻playground)

{ transform: "@nestia/core/lib/transform" }

Altering Diagnostics

Diagnostics can be altered in a Source Transformer.

To alter diagnostics you can use the following, provided from the TransformerExtras parameter:

| property | description | |--------------------|-----------------------------------------------------| | diagnostics | Reference to Diagnostic array |
| addDiagnostic() | Safely add Diagnostic to diagnostics array | | removeDiagnostic() | Safely remove Diagnostic from diagnostics array |

Note

This alters diagnostics during emit only. If you want to alter diagnostics in your IDE as well, you'll need to create a LanguageService plugin to accompany your source transformer

Program Transformers

Sometimes you want to do more than just transform source code. For example you may want to:

  • TypeCheck code after it's been transformed
  • Generate code and add it to the program
  • Add or remove emit files during transformation

For this, we've introduced what we call a Program Transformer. The transform action takes place during ts.createProgram, and allows re-creating the Program instance that typescript uses.

Program Transformer Entry Point

(program: ts.Program, host: ts.CompilerHost | undefined, options: PluginConfig, extras: ProgramTransformerExtras) => ts.Program

ProgramTransformerExtras >>> Type Declaration

Configuring Program Transformers

To configure a Program Transformer, supply "transformProgram": true in the config transformer entry.

Note: The before, after, and afterDeclarations options do not apply to a Program Transformer and will be ignored

See Config Example

Program Transformer Example

/** 
 * Add a file to Program
 */
import * as path from 'path';
import type * as ts from 'typescript';
import type { ProgramTransformerExtras, PluginConfig } from 'ts-patch';

export const newFile = path.resolve(__dirname, 'added-file.ts');

export default function (
  program: ts.Program, 
  host: ts.CompilerHost | undefined, 
  options: PluginConfig, 
  { ts: tsInstance }: ProgramTransformerExtras
) {
  return tsInstance.createProgram(
    /* rootNames */ program.getRootFileNames().concat([ newFile ]),
    program.getCompilerOptions(),
    host,
    /* oldProgram */ program
  );
}

Note: For a more complete example, see Transforming Program with additional AST transformations

Live Examples:

{ transform: "@typescript-virtual-barrel/compiler-plugin", transformProgram: true }

{ transform: "ts-overrides-plugin", transformProgram: true }

Plugin Package Configuration

The plugin package configuration allows you to specify custom options for your TypeScript plugin. This configuration is defined in the package.json of your plugin under the tsp property.

An example use case is enabling parseAllJsDoc if you require full JSDoc parsing in tsc for your transformer in TS v5.3+. (see: 5.3 JSDoc parsing changes)

For all available options, see the PluginPackageConfig type in plugin-types.ts

Example

{
  "name": "your-plugin-name",
  "version": "1.0.0",
  "tsp": {
    "tscOptions": {
      "parseAllJsDoc": true
    }
  }
}

Resources

Recommended Reading

Recommended Tools

| Tool | Type | Description | |----------------------------------------------------------------------|-------------|---------------------------------------------------------------------------------------------| | TS AST Viewer | Web App | Allows you to see the Node structure and other TS properties of your source code. | | ts-expose-internals | NPM Package | Exposes internal types and methods of the TS compiler API |

Discussion

Advanced Options

(env) TSP_SKIP_CACHE

Skips patch cache when patching via cli or live compiler.

(env) TSP_COMPILER_TS_PATH

Specify typescript library path to use for ts-patch/compiler (defaults to require.resolve('typescript'))

(env) TSP_CACHE_DIR

Override patch cache directory

(cli) ts-patch clear-cache

Cleans patch cache & lockfiles

Maintainers

Help Wanted

If you're interested in helping and are knowledgeable with the TS compiler codebase, feel free to reach out!

License

This project is licensed under the MIT License, as described in LICENSE.md