DEV Community

Javien Lee
Javien Lee

Posted on • Edited on

How to use Prettier plugins with Yarn PnP in VSCode?

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'],
}


Enter fullscreen mode Exit fullscreen mode

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>


Enter fullscreen mode Exit fullscreen mode

For example, let's unplug prettier-plugin-organize-imports.



$ yarn unplug prettier-plugin-organize-imports


Enter fullscreen mode Exit fullscreen mode

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')]
}


Enter fullscreen mode Exit fullscreen mode

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')],
}


Enter fullscreen mode Exit fullscreen mode

3. Reload Window

Finnaly, reload VSCode to restart prettier-vscode.

Press F1 to open command prompt, type 'reload window' and run "Developer: Reload Window".

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'],
}


Enter fullscreen mode Exit fullscreen mode

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'


Enter fullscreen mode Exit fullscreen mode

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?


Enter fullscreen mode Exit fullscreen mode

🧐 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


Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
fulldecent profile image
William Entriken

Hi Javien thanks for sharing. To make this work with Yarn Berry 4, I had to do a couple extra steps

{
  "license": "UNLICENSED",
  "devDependencies": {
    "@shopify/prettier-plugin-liquid": "^1.5.0",
    "prettier": "^3.3.3"
  },
  "scripts": {
    "postinstall": "yarn dlx @yarnpkg/sdks vscode"
  },
  "packageManager": "yarn@4.4.1+sha512.f825273d0689cc9ead3259c14998037662f1dcd06912637b21a450e8da7cfeb4b1965bbee73d16927baa1201054126bc385c6f43ff4aa705c8631d26e12460f1",
  "dependencies": {
    "xml2js": "^0.6.2"
  },
  "dependenciesMeta": {
    "@shopify/prettier-plugin-liquid@1.5.0": {
      "unplugged": true
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Then in the plugin, I also had to do:

/** @type {import("prettier").Options} */
module.exports = {
  printWidth: 120,
  plugins: [require.resolve("@shopify/prettier-plugin-liquid/standalone")],
};
Enter fullscreen mode Exit fullscreen mode

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.