[How To] Use with yarn2 #60
Copy link
Copy link
Closed
Labels
questionFurther information is requestedFurther information is requested
Description
When installing ts-patch with Yarn 2 (pnp) I get errors regarding undeclared dependencies for glob and resolve:
Error: ts-patch tried to access glob, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.
When I resolve these dependencies using my .yarnrc.yaml file in this way:
packageExtensions:
"ts-patch@*":
"dependencies":
"glob": "*"
"resolve": "*"
I get the following error:
[!] [BackupError]: Error backing up tsc.js - Couldn't create backup directory. EROFS: read-only filesystem, mkdir '/node_modules/typescript/lib-backup'
Is there a way to support Yarn 2 with ts-patch?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
questionFurther information is requestedFurther information is requested
Activity
[-]Support for Yarn 2/pnp[/-][+][How To] Use with yarn2[/+]nonara commentedon Aug 27, 2021
I investigated this a bit today and ended up fighting for awhile with odd issues. It seems that yarn2 patching is a little temperamental right now, so if you have any problems, let me know. This should work.
These instructions are for yarn v3.
package.json{ "dependencies": { "ts-patch": "^1.4.4", // You need to use >=1.4.4. I fixed the missing deps issue + another relevant issue "typescript": "4.4.2" } }Install steps
Native Support via CLI
I don't have the bandwidth right now to add this into v1, but if someone wants to do a PR, it should be pretty straight-forward to implement.
--yarn2flag tots-patchto enable itelby22 commentedon Aug 30, 2021
Thanks @nonara. I was also able to accomplish this by using
typescriptas an unplugged dependency. I might take a crack at a PR if we decide to use that approach.jasonkuhrt commentedon Oct 6, 2021
For others: I am using Yarn 2 in Yarn 1 compat mode (meaning node_modules node linker).
I had to use
postinstallhook in addition topreparescript.jekozyra commentedon Nov 11, 2021
@jasonkuhrt Could you explain more about the
postinstallhook?finnmerlett commentedon Nov 18, 2021
@nonara @elby22 I was super excited to read this, I've been really wanting to use the custom transformer typescript-is with my yarn3 create-react-app project. I followed your steps exactly, using the exact same versions of ts-patch and typescript under dependancies, and it all appeared to work. The only indication that something might not be right was the following message on yarn install following the patch-commit, where it stated
Cannot apply hunk #1:The test with
yarn run ts-patch cgave the correct output so I was hopeful. Yet when I started the dev serverreact-scripts startI was met with an endless stream of errors reported on the console (literally it would not stop scrolling at lightning speed, even as I was mashing ctrl-c), seemingly reporting an error on every single line of my code! I think it was that typescript (as patched) was unable to find any modules at all.I tried unplugging the typescript module before patching, but this had no effect. I tried the latest version of ts-patch and typescript and that failed too, in exactly the same way.
I did notice that when running
yarn why typescriptthat the typescript was patched already - I think it was mentioned on another thread here, that it was due to modifying for pnp support? If so, my guess would be that the built-in patch was applied second and failed. This checks out, as theCannot apply hunk #1warning appeared after the only patch report line that containedbuiltin<compat/typescript>, the signifier for the the internal pnp patch. This would explain why typescript wasn't able to find any of the modules - without the pnp patch it would probably be looking for them in the non-existent node_modules.Anyway, if you have any advice on how to fix this, I would love to hear it. Getting those sweet sweet run-time type-checks up and running would be an absolute dream.
nonara commentedon Nov 18, 2021
@finnmerlett if you can put together a quick reproduction repo, I'll have a look and see if I can help you get it going!
finnmerlett commentedon Nov 30, 2021
@nonara Thank you so much for such a speedy reply, and sorry I took a while to get back to you - I've been quite busy with work. Anyway, I've set it up here https://github.com/finnmerlett/ts-patch-cra-test. Running
yarn startworks just fine, but following your steps above to the letter produces thatCannot apply hunk #1warning, and thenyarn startgives many compile errors. VSCode also highlights the errors, it appears that it cannot find any of the modules.You can check through the commits on the repo to see how I set it up, but essentially I've just done a create-react-app using their latest alpha build, then set up Yarn 3 with P'n'P. Many thanks in advance!
finnmerlett commentedon Jan 2, 2022
@nonara Did you find any leads with this?
nonara commentedon Jan 10, 2022
@finnmerlett Sorry. Was swamped and this fell through the cracks. I'll take a look tomorrow and let you know!
nonara commentedon Jan 10, 2022
@finnmerlett Ok. I cloned it and had a look. No errors applying hunk for me, but I do see the issue of it not resolving modules.
From what I understand, yarn 2 actually modifies common libraries in order to add support. If I recall correctly, it does do this for typescript automatically, as well.
As an aside, this seemed, to me, like a terrible route to attempt to solve the issue. I think a better route would be to use a loader to hook filesystem bindings (like we do with
mock-fs) or better yet, to just submit a PR for node which provides zip support (allowing ability to treat a zip like a directory).Anyway, that's more info than you need. My best guess on this is that some sort of compatibility modification made somewhere is broken. Maybe React is doing a CRC check on TS to add yarn support and it fails because it's modified (??) Hard to say. It's odd that this works outside of React.
In my opinion, yarn2's core ideas are excellent and necessary advancements for the node ecosystem. That said, not to be unkind to the developers, but their approach to implementing the ideas have been poorly thought out.
In any event, I'm sorry that it didn't work for you. I would recommend trying what other users have reported working for them using node_modules linker / unplugged dependency.
Best of luck to you!
AlCalzone commentedon Jan 11, 2022
Since it might interest some readers here... After suffering through the ecosystem implications by yarn PnP, I switched to the new
pnpmcompatible linker they added in v3.1 and haven't looked back. Roughly the installation speed of PnP, but without any of these hacks necessary.finnmerlett commentedon Jan 11, 2022
Thanks @nonara for looking into it (and no worries about the delay - I'm getting your time for free so I'm not complaining!). And ooo @AlCalzone that sounds super interesting. Will investigate further
finnmerlett commentedon Jan 12, 2022
Oh boy did I come close. Maybe. I switched to using the
pnpmcompatible linker, and all the modules unresolved errors vanished. I checked the yarn install after applying the patch though, and was still getting the hunk failed error. Yarn was still patching typescript before ts-patch was, despite thepnpmlinker, and after a bit of research I found that yarn always patches pnp support into typescript (and some other key modules) in order to maintain compatibility with the other linkers (and avoid changing the .cache when swapping linkers). I found this comment yarnpkg/berry#2384 (comment) that described how to replace the yarnplugin-compat(the plugin that I believe patches in pnp support for key modules) with a dummy script. After doing that, and following the ts-patch process (described at the top of this thread) again, I could see that the pnp-compat patch was successfully skipped and the ts-patch applied with no errors! Runningyarn run ts-patch cgave a positive confirmation, everything built and loaded successfully and I was super excited to start using the typescript plugins...Until I tried them out and they weren't working. Their errors suggested that the transformer plugins weren't being applied at all. I can't think what I could be missing, but it feels like something obvious. I have updated the test repo to include the latest changes I made, and the test scripts in App.tsx (they console log their success or errors). The last commit to the repo is the (at first glance apparently successful) applying of ts-patch, so if you want to re-do that yourself just pull the repo and undo the last commit.
@nonara is this something you might have time to consider looking further into? It feels like it should work now, we have modules in node_modules as standard, no extra patches applied to typescript and the ts-patch test coming back positive. I'm at a dead end as to what I could be missing! Thanks again for your help.
PS. I am still using typescript 4.4.2 and ts-patch 1.x.x in the test repo since those were what you specified in the original instructions, but I want to note that I've also tried it with ts 4.4.4 and ts-patch 2, with the same unsuccessful outcome.
PPS. I just had a thought that perhaps react-scripts is somehow finding and using a non-patched typescript package. I don't know where or how though, since running
yarn why typescriptshows only one version being used, and that is the version I thought I successfully patched. Is there any way to check for the successful application of the ts-patch using the ts object? If so a testing step could be to console log inside react-scripts' files on the ts object it fetches.PPPS. I console logged the ts path that react-scripts is using and it matches the ts path that ts-patch confirms it has successfully applied to. This makes me think it might be an issue with ts-patch not applying correctly?
nonara commentedon Jan 12, 2022
I would debug and step through, but if your source files are in zips, it's going to be more difficult. Still doable, though. You can insert
debuggerstatements into files.First thing I'd do is create a local empty plugin and inspect the arguments that it passes. Use tsp v2. If it passes a ts instance, check that
ts.tspVersionis set.Example plugin:
Add the local file to your
tsconfig.jsonplugins and run with debugger. To make sure it works, try the setup in yarn1 first, in another dir. It should pause on that breakpoint. Once you get it with y1, try it with y2. If it hits the breakpoint, you'll know that plugins work.From what you've explained, I can think of a few possibilities
You'll need to find the code where it works with the compiler API. Set a breakpoint before and after the require. First, after the require, check if the instance has
tspVersion. If not, you know it's a different version. If that's the case, run again and step into therequirecall to see where it's getting the file.swcto compile and only using the compiler API for typecheckingPrograminstance (very unlikely)tsserverlibrary.jsto compile (also very unlikely)Let me know what you discover and I'll try to offer what ideas I can.
finnmerlett commentedon Jan 13, 2022
Hum. So it turns out create-react-app (CRA, the framework I'm using) does what is closest to item no.2 on your list. As I found out (painfully slowly) after stumbling about in the
react-scriptspackage and reading about this, this and finally this (which actually stated what I had started to suspect) it turns out CRA indeed usesbabel-loaderthrough webpack to do the compilation, and only uses typescript to carry out typechecking.Rightio, this all means ts-patch is out for me. The plugins were applied, but only for typechecking - @nonara thanks for your pointers in helping me figure this out.
If I want to get the typescript plugins I was eyeing up working, I need to swap out
babel-loaderforts-loaderin CRA's webpack.config.js (which will involve someyarn patching), add the plugin's transformers to thegetCustomTransformersoption onts-loader, and hope my compile-time refresh speed isn't unmanageably slow 😬nonara commentedon Jan 13, 2022
Ah. Good work tracking it down! Thanks for sharing the final details. I imagine that will be helpful for anyone facing the same issue. Good luck with it!
CarsonF commentedon Mar 11, 2022
I was able to make this work with pnpm linker & postinstall script (yarn 3.2.0), thanks above for that.
EDIT: I was also able to get it to work with pnp linker with typescript unplugged.
I think a custom yarn plugin would work to apply this patch while still being compatible with yarn's TS patch.
That could work for any linker & without a custom user script.