cevek / ttypescript

Over TypeScript tool to use custom transformers in the tsconfig.json
1.53k stars 56 forks source link

Use together with "noEmit" #89

Closed Danielku15 closed 4 years ago

Danielku15 commented 4 years ago

I would like to do some custom file writing within my transformer instead of doing actual typescript > javascritpt emitting. For this I tried to set "noEmit": true on my tsconfig but due to this also no transformers are called.

Is there a way, or can you add a way that the transformers are called with noEmit set? I also tried to return a null node in the transformer in the hope that this would indicate not to emit anything for this file.

nonara commented 4 years ago

@Danielku15 That would require altering the way that TS works in a significant way and would likely get complicated or potentially not be possible without rewriting internal TS routines, which ttypescript doesn't do, currently. Which is not to say that it isn't possible. That would be up to cevek, the author.

There is an easier way to accomplish what you'd like to do, however! The way that this sort of thing is handled within the internal TS compiler code and elsewhere is to provide a custom writeFile function to the emit host. You could write a separate piece of code which manually runs emit with a custom writeFile, but there is actually a way you can accomplish the same thing during transform.

Here's an example:

export = function (program: Program) {
  return (ctx: TransformationContext) => {
    ctx.getEmitHost().writeFile = () => {}; // Replace writeFile with an empty function (no files will emit)
    return (srcFile: SourceFile) => {
      // Transformer logic here
    }
  }
}
Danielku15 commented 4 years ago

Awesome. I knew about the internal "host" system of typescript where you can modify certain system interaction behaviors but I didn't think of just stipping out the writeFile.

I temporarily had bootstrapped a custom "tsc" command using the raw compiler API to do my custom transpiling. But with your solution I might get all the fancy features back like watch. I will definitly give it a shot, thanks a lot.

nonara commented 4 years ago

@Danielku15 Not a problem! I actually just came across it, myself. I needed the ability to add JSDoc comments and tags, which TS still frustratingly does not support. I ended up doing the main transforms, printing the the source text and splicing in the comment ranges, then instead of outputting the node in the transformer, my hooked writeFile supplies the new text for the modified files.

Danielku15 commented 4 years ago

Due to some other new needs in my compilation pipeline I decided to stay with my current setup of setting up the compiler on my own and not going for a transformer. Thanks for the assistance 😃

nonara commented 4 years ago

@Danielku15 Np! You might find the recent version of ts-patch useful! I've added 'beforeEmit' option which lets you alter Program before calling emit. It should allow you to integrate your process into tsc.

bradennapier commented 4 years ago

It is worth noting the following @nonara : https://github.com/microsoft/TypeScript/pull/39122

nonara commented 4 years ago

@bradennapier Hmm. I'm not seeing how that applies here. Transformation is not called when noEmit flag is specified.

rdsedmundo commented 3 years ago

I was also looking for that because I'm only interested in doing a transformation for type-checking purposes.

The workaround of hijacking the writeFile works for me.

Is this limitation of not transforming stuff with the noEmit flag coming from ttypescript or typescript itself?

nonara commented 3 years ago

Is this limitation of not transforming stuff with the noEmit flag coming from ttypescript or typescript itself?

The typescript compiler doesn't run tranforms at all if it's not intended to emit. The reason for this is that it would generally be unnecessary added work, and tsc wants to be as efficient as possible.

If you use ts-patch you could create a program transformer and put the emit file override code into that. This would allow you to use regular tsc. There is a thorough program transformer example up now which would show you how to use both program and regular transformers.