microsoft / rushstack

Monorepo for tools developed by the Rush Stack community
https://rushstack.io/
Other
5.82k stars 594 forks source link

[heft] Add an option for loading TypeScript transformers #2683

Open octogonz opened 3 years ago

octogonz commented 3 years ago

Summary

In this Zulip thread, @d-corler wants to use a TypeScript transformer from nestjs/swagger to implement mapped types. "Transformers" are compiler plugins that customize how code is generated. I think Heft should support this.

Details

This article explains how transformers are authored. And here is a list of useful transformers that are available.

The TypeScript compiler itself does not officially expose a config option for loading transformers. The ttypescript wrapper applies them by patching the createProgram() API.

The popular ts-loader plugin for Webpack also supports transformers. Its setting looks like this:

{
  test: /\.(ts|tsx)$/,
  loader: require.resolve('awesome-typescript-loader'),
  // or
  loader: require.resolve('ts-loader'),
  options: {
      compiler: 'ttypescript' // recommended, allows you to define transformers in tsconfig.json
      // or
      getCustomTransformers: program => {
        before: [yourBeforeTransformer(program, { customConfig: true })],
        after: [yourAfterTransformer(program, { customConfig: true })],
      }
  }
}

My opinion is that transformers have similar downsides as ECMAScript decorators -- they can alter the semantics of the language, they can impact performance, they can make code less portable, etc. But if people find them useful, and if we want to position Heft as a replacement for ts-loader, then I think it would make sense for Heft to support this feature. It should be pretty easy to implement.

iclanton commented 3 years ago

Sounds useful to me. We should go for it.

dmichon-msft commented 3 years ago

We're already touching the transformer pipeline, just not doing anything with it, so straightforward enough to support once we add the necessary hooks to load plugins inside of the TypeScript subprocess.