timocov / ts-transformer-properties-rename

TypeScript custom transformer to rename properties
MIT License
70 stars 3 forks source link

[feature] Lazily resolve TS Program #17

Open meDavid opened 3 years ago

meDavid commented 3 years ago

Currently the transformer factory requires a ts.Program as a parameter, but this might not be available yet. I would like it to accept an method that would return the ts.Program instance when needed.

Usecase When I manipulate the Angular webpack compiler configuration to include this transformer it might not yet have created the ts.Program instance. If it would accept a lazy resolver method, this is not longer an issue:

propertiesRenameTransformer(() => angularCompilerPlugin._getTsProgram(), { entrySourceFiles: angularCompilerPlugin._rootNames })

I can create a PR that would accept both an instance or a method that would return an instance if that would be appreciated.

timocov commented 3 years ago

propertiesRenameTransformer(() => angularCompilerPlugin._getTsProgram(), { entrySourceFiles: angularCompilerPlugin._rootNames })

Where that transformer is passed afterwards? I mean, it seems that the default behaviour of typescript compiler is to pass a transformer on emit phase where the program is known.

meDavid commented 3 years ago

The transformer is passed to the AngularCompilerPlugin, which is is a webpack plugin. I use the ngx-build-plus builder to extend the interal webpack configuration of the Angular CLI. The plugin owns the ts.Program and all the their code transformation plugins use lazy resolving. See for example https://github.com/angular/angular-cli/blob/51d0178d244ed3fb6feee280d02cf284ceed1b85/packages/ngtools/webpack/src/transformers/remove_decorators.ts

timocov commented 3 years ago

angularCompilerPlugin._getTsProgram()

And this one doesn't exist at propertiesRenameTransformer call, right?

I mean, at what moment we're sure that we can get a program safely? If we can't do that at init time, then we need to create exports tree later and cache it somehow somewhen to avoid re-creating it every time (because it might take some time on huge codebase - see https://github.com/cevek/ttypescript/issues/106)

meDavid commented 3 years ago

angularCompilerPlugin._getTsProgram()

And this one doesn't exist at propertiesRenameTransformer call, right?

Yes indeed.

I currently have the initialization of the exportsSymbolTree inside the transformer itself, while keeping the scope inside the factory and only when it is not already initialized.

timocov commented 3 years ago

Yeah, let's add it as you described above. Feel free to make a PR.

timocov commented 3 years ago

Hey @meDavid, do you have any updates on this?

timocov commented 3 years ago

Hi @meDavid, just checking whether you have an update for that :)

meDavid commented 3 years ago

@timocov Sorry for the delay. I wanted to add some tests as well, but didn't have the time yet. I'll push what I have in a PR this week.

timocov commented 3 years ago

@timocov Sorry for the delay. I wanted to add some tests as well, but didn't have the time yet. I'll push what I have in a PR this week.

No problem at all, just push what works for you and I'll finish tests for you if you'd like.