As a developer, I'm all too familiar with things not working as planned, and bugs popping up anywhere and everywhere. I'm also all too familiar with the frustration that comes with it.
But finding / creating bugs while coding is just par for the course, so it's nothing new. It's just part of the job. And I've learned to accept it.
What really frustrates me though, is when I bootstrap a new project, and there are errors right from the get-go! π‘
The Project
Enter this new project I started. I'm using NextJS and Yarn 3, and I bootstrapped it using Next's create-next-app
with Yarn, as such:
yarn create next-app
β Would you like to use TypeScript? β¦ [Yes]
β Would you like to use ESLint? β¦ [Yes]
β Would you like to use Tailwind CSS? β¦ [Yes]
β Would you like to use `src/` directory? β¦ [No]
β Would you like to use App Router? (recommended) β¦ [No]
β Would you like to customize the default import alias (@/*)? β¦ [No]
Pretty straight forward and simple no?
- TypeScript ... check
- ESLint ... check
- Tailwind CSS ... check
Certainly, nothing really out of the ordinary here. That said, I am using Yarn 3 (Yarn Berry), which uses it's "Zero Installs" plug and play system, and means that there's no node_modules
folder. As I've experienced before, the missing node_modules
folder can cause issues sometimes.
The Problem
So I opened Visual Studio Code and checked out the tailwind.config.js
file, and I was greeted with this succulent error:
Cannot find module 'tailwindcss' or its corresponding type declarations
I thought it seemed strange, because I selected Tailwind in the create-next-app
options. Create-next-app surely would have installed what was needed right? So I checked my package.json
and sure enough, the tailwindcss dependency was there, along with the React dependencies and types.
"dependencies": {
"next": "14.0.2",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"eslint": "^8",
"eslint-config-next": "14.0.2",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"typescript": "^5"
}
In any case, I decided to check the index.tsx
file, and it was even worse, spitting out '... Cannot find module ...' and '... no interface exists ...' errors all over the file! π±
Cannot find module 'next/image' or its corresponding type declarations.
JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
First Attempts to Fix the Issue
Being relatively new to TypeScript and working with it, I vaguely remembered having issues with TypeScript imports before in Visual Studio Code, but thought I had taken care of the issue globally previously. Apparently not. π€¨
VS Code SDK & TypeScript Version
So I ran the steps I thought I did last time this happened, which was to install the VS Code SDK package from the CLI ...
yarn dlx @yarnpkg/sdks vscode
and then select the workspace TypeScript version, and finally restart the TypeScript server.
But ... it didn't work this time. I was still getting the same damn errors. π
So, I rolled up my sleeves, prayed to the Google-fu gods, and started searching for a solution.
Opting Out of Yarn PnP
I found a few posts on Stack Overflow, but most of the "solutions" were to simply opt-out of Yarn PnP, which was exactly what I wanted to avoid. This post on Stack Overflow for example had several people talking about setting the Yarn version to classic or adding the nodeLinker: node-modules option in .yarnrc.yml
to downgrade Yarn and create the node_modules
folder.
Uhh, no thanks... I'm not going back to the old node_modules
mess!
Installing the Dependencies with npm
Others in the same thread suggested to use npm to install the dependencies, and then re-run Yarn. But, that's completely pointless, and ... then why use Yarn at all in the first place? π€
Explicitly Installing Types
I figured I might as well try installing the types explicitly, despite assuming they'd already be there (not in package.json
, but in the main code), so I ran:
yarn add -D @types/next @types/tailwindcss
But that also did nothing as I figured, and it should also be noted that these packages have been deprecated per npmjs.org:
So, time to put on my thinking cap and figure this out the right way...
The Actual Solution
I went back over what I did last time, and noticed I had also explicitly set the Yarn version to berry last time, which I hadn't done this time.
So I tried that again, and thankfully, finally, it got things working! π
I had originally mistakenly assumed that because I bootstrapped the project with Yarn Berry, that it would have already been set to berry by default, but it seems that isn't the case.
Explicitly setting it to berry added a "packageManager": "yarn@4.0.1" to package.json
, and then running yarn again after caused Yarn to pull in any updated dependencies, including those for TypeScript.
Step-by-Step Instructions
So here's what I had to do to fix the issue while keeping Yarn PnP, step-by-step:
-
From the CLI:
yarn set version berry && yarn yarn dlx @yarnpkg/sdks vscode
-
Then in Visual Studio Code:
- Set the TypeScript version to the workspace version:
- Open a TypeScript file, and open the command palette:
- on a Mac, press β + Shift + p
- on a PC, press Ctrl + Shift + p
- Choose Select TypeScript Version.
- And then select Use Workspace Version.
- Open a TypeScript file, and open the command palette:
- Restart the TypeScript server:
- Go back into the command palette:
- on a Mac, press β + Shift + p
- on a PC, press Ctrl + Shift + p
- Choose TypeScript: Restart TS server.
- Go back into the command palette:
- Set the TypeScript version to the workspace version:
Note: Yarn also recommends installing the ZipFS extension for VS Code, so you may need to get that as well if you don't already have it installed.
And that's it - super simple!
The errors disappeared in all of the files, and I was able to get back to work without having to resort to downgrading Yarn and opting out of PnP.
So if you're experiencing any issues like I was, whether:
Cannot find module '...' or its corresponding type declarations
Or
JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
... and you don't want to revert back to the old node_modules
mess, then try the steps above to see if they fix your issue(s).
Did this help you out? Let me know in the comments below!