Getting started with Yarn 2 and TypeScript
A headache for newcomers, a saving grace for longtime Yarn fans.
Update
This article only covers the early days of Yarn 2, which past this article had actually gone on to change almost every week but still remained close to this article. However, Yarn 3 is now out, and I’d recommend reading my updated article Getting Started with Yarn 3 and TypeScript which also has a redone format compared to this one, also the Yarnberry Cookbook sadly went nowhere because of my personal life. 😢
Yarn 2, aka Berry (and also Modern), completely changes how Yarn functions as a whole, with limited support and templates, I created the Yarnberry Cookbook to home every “recipe ” I came up with, silly maybe but still unique.
The Basics
Getting started with Yarn 2 isn’t as straightforward as Yarn Classic or npm. It’s a headache for newcomers. You can read the getting started and features to get a good idea of how things work.
One of the best things about Yarn 2 is that it started using available resources instead of forcing you to adapt to new ones. Such as, not requiring .msi installations and Chocolately. They expect the bare minimum, and having installed Node.js 10+ which ships with npm! I personally prefer Node 12 LTS.
PS C:\…> npm -g install yarn
PS C:\…> mkdir <your-project>
PS C:\…> cd <your-project>
PS C:\…> yarn init
... Package information ...PS C:\…\your-project> yarn set version berry
Resolving berry to a url…
Downloading https://.../berry-cli/bin/berry.js…
Saving it into C:\...\yarnberry-seed\.yarn\releases\yarn-berry.js…
Updating C:\...\yarnberry-seed/.yarnrc.yml…
Done!
And just like that, you’re ready to get started. It couldn’t be simpler! I would use screenshots, but my path names are a bit long and I like things to be as simple as possible.
Dependency Management
Here’s where things get tricky, but once you’re used to it, it’s all game.
Once you install your first dependency you’ll notice one of the things that makes Yarn Modern awesome, no more heavy node_modules
directory! Now dependencies live across 3 points,
yarn.lock
is your YAML-based lockfile.pnp.js
is your Plug’n’Play module resolver.yarn/cache
is where all of your dependencies are nicely packed and zipped
All three of these points remain synced every time you install a dependency. A caveat? When using TypeScript, you’ll notice a severe lack of “Go To Definition” functionality in Visual Studio Code or lack thereof for now. At first, I saw this as a huge no for me, but then I realized I didn’t need that functionality much, we’ll revisit this topic.
Back to those zipped dependencies, there’s an error you’ll run across occasionally when first starting out relative to checksum mismatches, specifically, YN0018, of which I now remember by heart because it burdened me for days. The fix? Easy. The cause? Depends, for me, it was because in my .gitattributes
I auto-commit all files with an * text eol=lf
, or End of Line = Unix-style.
# .gitattributes
* text=auto
* text eol=lf
*.zip binary
# GitHub Linguist Override
.yarn/* linguist-vendored
.pnp.js linguist-vendored
That’s all it takes to fix YN0018. What about that “Github Linguist Override?” Well, it’s optional, but it helps GitHub determine the true language stats for your repository. If you’re unfamiliar, GitHub Linguist is the library that reports the stats for those pretty colors on the bar under your stats bar. I don’t know the name for that navbar.
In short, if you don’t add those last two lines, the entire repository shows as 99% JavaScript, which isn’t true because that 99% isn’t your code, its just PnP and yarn-release code.
Ignorables
This one is pretty straightforward, ignore everything except a few folders. Never include install-state.gz
, .yarn/unplugged/
, or buildstate.json
. These are not only platform-specific artifacts, but including unplugged gets heavy depending on your dependencies, puppeteer
ships with Chromium which then means you have to add *.exe
and *.dll
as Git LFS files, which even then you only have 1 GB of free LFS storage. Just… not worth it.
# Yarn 2
.yarn/*
!.yarn/cache/
!.yarn/releases/
!.yarn/plugins/
!.yarn/versions/
!.yarn/sdks/
TypeScript
So, back on the topic of TypeScript support, this is where two things come into play… in Plug’n’Play… anyway, you’re going to want to import the typescript plugin and make sure your integrations are updated. TypeScript, VS Code, etc.
PS C:\…> yarn add typescript — dev
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed in 0.25s
➤ YN0000: ┌ Fetch step
➤ YN0013: │ …
➤ YN0013: │ … “can’t be found and will be fetched etc…”
➤ YN0013: │ …
➤ YN0000: └ Completed in 0.22s
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: Done in 0.54s
PS C:\…> yarn plugin import typescript
➤ YN0000: Downloading https://.../plugin-typescript.js
➤ YN0000: Saving the new plugin in .yarn/plugins/@yarnpkg/plugin-typescript.cjs
➤ YN0000: Done in 0.67sDid I mention Yarn Modern is fast?
This just installs typescript, of course, but also adds the TypeScript plugin! Which, is the best thing to happen in the history of TypeScript, as it literally fetches your type definitions for you 😍!!! No more add
then add — dev @types/…
blah, blah, repetitive nonsense!
So you’ve got that going, but then you load up VS Code and make your first module and BAM “Cannot find module ‘fs’ or its corresponding type declarations. ts(2307).” What a pain! Right? Not really! Because here’s the issue, we’ve zipped those dependencies, stored them in a folder that TypeScript knows nothing about, and expected it to just… work. Well lucky you, it actually does just work with a simple fix!
PS C:\…> yarn add @yarnpkg/pnpify --dev
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed in 1.45s
➤ YN0000: ┌ Fetch step
➤ YN0013: │ …
➤ YN0013: │ … “can’t be found and will be fetched etc…”
➤ YN0013: │ …
➤ YN0000: └ Completed in 1.44s
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: Done in 3.26s
PS C:\…> yarn pnpify --sdk vscode
➤ YN0000: ┌ Generating SDKs inside .yarn/sdks
➤ YN0000: │ ✓ Typescript
➤ YN0000: │ • 5 SDKs were skipped based on your root dependencies
➤ YN0000: └ Completed
➤ YN0000: ┌ Generating settings
➤ YN0000: │ ✓ Vscode (new ✨)
➤ YN0000: └ Completed
You install @yarnpkg/pnpify
and then pnpify
to get going! It’s that simple. Of course, you can also run yarn pnpify --sdk vim
. I personally use Visual Studio Code. Either way, this gets your workspace up and running! So what about those “5 SDKs were skipped?” Well, you can also install ESLint and Prettier and run yarn pnpify --sdk base
to install support for those too!
Here’s another caveat, .yarn/sdks
is actually new — that sounds good but I’ve had to support 3 separate solutions. Another downside about “bleeding-edge” is how much it changes. .yarn/sdks
was previously .yarn/pnpify
and before that, it was .vscode/pnpify
and just yarn pnpify --sdk
instead of adding “base”. These changes were all in 2 weeks. So you’ll want to either keep up-to-date about those changes or come back to ye ol’ Grim and keep using my up-to-date templates 😁… Shameless plug?
Also, remember to actually use the workspace version of TypeScript, 3.9.5-pnpify
for example. Otherwise, you’ll bang your head wondering why @types/node
didn’t resolve even though you’ve installed it 5 times. I’ve been there.
And finally, a painful caveat is that you may need to Reload the TypeScript Language Server, sometimes it bugs out or freezes completely. And other times, Yarn will say it can’t remove a module, just close and reopen VS Code I did a LOT of digging and a Node.js process hangs onto a file under Yarn 2 sometimes but it’s hidden under VS Code. Just a weird quirk but it happens when Code is under heavy load or you’re using a weaker laptop and the CPU is running hot. Weird quirks.
What about running Node.js scripts?
Yarn 2 runs with its own Node instance. So yarn node <file>.js
will solve those pesky issues. If you want to resolve that, use a bundler like Webpack. The same goes for binaries too, yarn add — dev webpack-cli
then yarn webpack-cli
you get the idea.
Tooling
I’ll be making a few more recipes for tooling, linting, webpack, etc. Webpack, React, ESLint, and Prettier are already in a recipe together called Reaxpress in the Cookbook, so feel free to use that. Otherwise, I think that sums everything up!
If you want to go ahead and get started with Yarn 2 and TypeScript without the hassle, the repository can be found here, and you can easily get started by using that link to generate a project from the template. Everything in the Cookbook is a template, so it’s hassle-free.
I’ve done the research so you can get to play, have fun!