You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For those interested in tsx with ts-patch, I have it working with my transformers. The reason it doesn't "just work" is because tsx uses esbuild, which means it does not call the typescript compiler API's that ts-patch modifies.
The trick is to get it to load your transformer before tsx so the input to esbuild is the output from your transformer. To do this, you need to use the node cli and not tsx, since once it starts running it will go directly to esbuild and never call your transformer.
For example, with modern register-based transformers (and having previously used ts-patch install):
I am probably stupid but it doesn't work for me. after adding a simple console log into my transformer I can see that node --import @blaaaaa/fancy-transformer --import tsx scripts/execute-job.ts successfully loads my transformer. however the default function in that transformer which should patch my code is never being called?
I don't recall the details well, as I just played around until I got it to work (I'm no expert in this). One that sticks out is your comment "however the default function (is not) being called". If the transformer exports a default function that likely means it's a "loader" based transformer. Perhaps try --loader (though I'll bet you already tried that). Register-based loaders I believe have named exports.
Given I use a register-based export, I don't know if this will help, but I figure more information is better than less?!
In my package.json I start with something like this (FYI, this is for the @wessberg/DI dependency injection tool.
This registers the transformed loader. You can likely skip all the path munging - it's just to help make the path resolution work since @wessberg/di-compiler wouldn't work because the di-register-loader package doesn't have mappings to resolve @wessberg. You likely can use only the register call with a regular path.
Now my usage is based on register style transformer loader. See here for the source of the loader I'm using, but for reference here is it pulled together post-packing as a single file:
importTS__defaultfrom'typescript';importpathfrom'path';importfsfrom'fs/promises';importurlModulefrom'url';import{resolveOptions,ALLOWED_EXTENSIONS,transform}from'./common/common.js';consttransformOptions=resolveOptions(TS__default);constload=async(url,context,nextLoad)=>{var_a;if(ALLOWED_EXTENSIONS.has(path.extname(url))){constfileName=urlModule.fileURLToPath(url);constrawSource=awaitfs.readFile(fileName,"utf-8");if(rawSource!=null){const{code: source}=transform(rawSource.toString(),fileName,{
...transformOptions,typescript: TS__default});return{format: (_a=context.format)!==null&&_a!==void0 ? _a : "module",shortCircuit: true,
source
};}}// Defer to the next hook in the chain.returnnextLoad(url,context);};
Not a lot to learn here, unless you need to write your own register loader. Maybe your transformer has a register-based loader that you can use? If not then perhaps the above might help you write one (assuming you can't get a loader-based transformer working with --loader or some other trick).
I wish I could be more prescriptive in fixing your problem, but I don't fully understand it either. Hope something here helps you find a solution. Good luck!
ok I get it. this is much more complicated than anticipated 😱 I am transforming some macros and I just inject the macro calls as functions using a loader now. thanks for the details though!
Activity
[-][How To] Use with tsx[/-][+][How To] Use with tsx runner[/+][-][How To] Use with tsx runner[/-][+][How To] Use with `tsx` runner[/+]cmidgley commentedon Jul 16, 2024
For those interested in
tsxwithts-patch, I have it working with my transformers. The reason it doesn't "just work" is becausetsxusesesbuild, which means it does not call the typescript compiler API's thatts-patchmodifies.The trick is to get it to load your transformer before
tsxso the input toesbuildis the output from your transformer. To do this, you need to use thenodecli and nottsx, since once it starts running it will go directly toesbuildand never call your transformer.For example, with modern register-based transformers (and having previously used
ts-patch install):or this for legacy loader-based transformers:
This will cause your transformer to load before
tsx, allowing the files to be processed by it before sending on totsxandesbuild.Also, if you have custom
tsconfig.jsonfile, you can specify that with the environment variableTSX_CONFIG_PATHI have this all working with node 22.3.0, ts-patch 3.2.1, typescript 5.5.3 and tsx 4.16.2.
m0ppers commentedon Jan 10, 2025
I am probably stupid but it doesn't work for me. after adding a simple console log into my transformer I can see that
node --import @blaaaaa/fancy-transformer --import tsx scripts/execute-job.tssuccessfully loads my transformer. however the default function in that transformer which should patch my code is never being called?what am I missing?
cmidgley commentedon Jan 10, 2025
I don't recall the details well, as I just played around until I got it to work (I'm no expert in this). One that sticks out is your comment "however the default function (is not) being called". If the transformer exports a default function that likely means it's a "loader" based transformer. Perhaps try
--loader(though I'll bet you already tried that). Register-based loaders I believe have named exports.Given I use a register-based export, I don't know if this will help, but I figure more information is better than less?!
In my
package.jsonI start with something like this (FYI, this is for the @wessberg/DI dependency injection tool.The
di-register-loaderis a private package that has a singleindex.mjsfile:This registers the transformed loader. You can likely skip all the path munging - it's just to help make the path resolution work since
@wessberg/di-compilerwouldn't work because thedi-register-loaderpackage doesn't have mappings to resolve@wessberg. You likely can use only theregistercall with a regular path.Now my usage is based on register style transformer loader. See here for the source of the loader I'm using, but for reference here is it pulled together post-packing as a single file:
Not a lot to learn here, unless you need to write your own register loader. Maybe your transformer has a register-based loader that you can use? If not then perhaps the above might help you write one (assuming you can't get a loader-based transformer working with
--loaderor some other trick).I wish I could be more prescriptive in fixing your problem, but I don't fully understand it either. Hope something here helps you find a solution. Good luck!
m0ppers commentedon Jan 15, 2025
ok I get it. this is much more complicated than anticipated 😱 I am transforming some macros and I just inject the macro calls as functions using a loader now. thanks for the details though!