If you're using yarn berry and prettier in Visual Studio Code, you could be stuck on using prettier plugins.
module.exports = {
// β It's not working!
plugins: ['prettier-plugin-organize-imports'],
}
I used these version for the explanation:
- prettier: v3.0.3
- prettier-vscode: v10.1.0
- yarn: v3.6.4
Note that the solution can't work if major version is different.
TL;DR
1. Unplug your plugins
First, unplug your plugins. You can do it with this command:
$ yarn unplug <your-plugin>
For example, let's unplug prettier-plugin-organize-imports
.
$ yarn unplug prettier-plugin-organize-imports
You can find more information about yarn unplug
here
2. Edit .prettierrc.js
π¨ To use plugin, your prettier config file must be a JS file (.prettierrc.js
).
Because we're going to use require.resolve
- it's very important!
/** @type {import("prettier").Options} */
module.exports = {
plugins: [require.resolve('your-plugin')]
}
Using prettier-plugin-organize-imports
, config file can be like this:
/** @type {import("prettier").Options} */
module.exports = {
semi: false,
singleQuote: true,
trailingComma: 'all',
organizeImportsSkipDestructiveCodeActions: true,
plugins: [require.resolve('prettier-plugin-organize-imports')],
}
3. Reload Window
Finnaly, reload VSCode to restart prettier-vscode.
Press F1
to open command prompt, type 'reload window' and run "Developer: Reload Window".
You can also close VSCode and open it again - it's the same thing.
π Now it's done! π
Okay, so what was the problem?
Basically, yarn berry was the problem. Let me explain.
If you pass plugin name as a plain string (like me), you would face the issue.
module.exports = {
// β doesn't work
plugins: ['prettier-plugin-organize-imports'],
}
When a plugin is specified as a string, prettier-vscode attempts to load it on its own. However, due to our usage of yarn PnP, it cannot handle this properly.
["ERROR" - 11:43:14 PM] Error resolve node module 'prettier-plugin-organize-imports'
Error: Error resolve node module 'prettier-plugin-organize-imports'
The next approach is to provide an absolute path directly using require.resolve
. If the plugins are passed with an absolute path, prettier-vscode uses the value as it is.
Unfortunately, it still didn't work. This is the error log I got:
Cannot find module '(~).yarn/__virtual__/prettier-plugin-organize-imports-virtual-9cbb536fbb/0/cache/prettier-plugin-organize-imports-npm-3.2.3-7f40e110b3-e97dd707ce.zip/node_modules/prettier-plugin-organize-imports/index.js' imported from (~).yarn/unplugged/prettier-npm-3.0.3-fced695dae/node_modules/prettier/index.mjs
Did you mean to import (~).yarn/__virtual__/prettier-plugin-organize-imports-virtual-9cbb536fbb/0/cache/prettier-plugin-organize-imports-npm-3.2.3-7f40e110b3-e97dd707ce.zip/node_modules/prettier-plugin-organize-imports/index.js?
π§ Hmm.. I had to think why prettier-vscode couldn't import even with an absolute path.
I finally figured it out.
When you open .yarn/cache
, you will see it's full of zip files. This is why prettier-vscode can't load the module by the path. The extension can't load the plugin because it doesn't use .pnp.cjs
If you want to avoid managing specific packages as zip files, you can unpack them using yarn unplug
.
$ yarn unplug prettier-plugin-organize-imports
Eventually! We made it!
Conclusion
The problem was yarn PnP. If you still not solved the problem, feel free to let me know about your problem :)
Top comments (1)
Hi Javien thanks for sharing. To make this work with Yarn Berry 4, I had to do a couple extra steps
Then in the plugin, I also had to do:
Note that it is NOT just the module, but a specific "standalone" file in the module.
It took a ridiculous amount of effort to find these undocumented tricks. Using very careful search through public code on GitHub.
github.com/fulldecent/github-pages...
^ Here is a blank template implementing this approach for GitHub Actions, VS Code editing and command line usage for Prettier linting including plugins. It is targeted for people that want to publish a site on GitHub Pages, but the concepts should hold for other languages.