Describe the bug
When using Prettier with plugins in a PNP environment, Prettier will not be able to find its plugins.
To Reproduce
We reproduced this on Discord with this repo:
https://github.com/oliversalzburg/prettier-plugin-pnp
Running yarn prettier src/index.ts will not remove the unused import, for which the prettier-plugin-organize-imports was installed.
Additional context
It was suggested that this is due to missing PNP functionality in the SDK wrapper. Enabling usePnpif in https://github.com/yarnpkg/berry/blob/master/packages/yarnpkg-pnpify/sources/generateSdk.ts#L119 should be a valid solution to the problem.
This should probably be enabled through a CLI flag in yarn pnpify to allow an adjusted SDK wrapper to be generated.
To actually fix the issue, I also need to supply the plugin search directory to Prettier manually. Otherwise it will search in a completely inapproriate location by default.
The merge was done in a branch (yarnpkg:larixer/prettier-pnpify) which does not exist anymore and was not done in master. When will this be present in @yarnpkg/pnpify?
@asfernandes After discussion we decided to enable pnpify runtime on a per-tool basis and not shift the decision to the users, because they don't know the tradeoffs involved. For prettier we will always enable pnpify runtime starting from the next @yarnpkg/pnpify version:
https://github.com/yarnpkg/berry/pull/1913
Hi folks! A Yarn 2 experimenter here š
It seems that I've ran @yarnpkg/pnpify with the discussed change (v 2.2.3), but my plugins still have not loaded. Any ideas what I should check? Here is the PR: https://github.com/kachkaev/njt/pull/29
It hasn't been released yet, but you can apply it manually by editing .yarn\sdks\prettier\index.js and changing it to
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve, dirname} = require(`path`);
const relPnpApiPath = "../../../.pnp.js";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require prettier/index.js
require(absPnpApiPath).setup();
}
const pnpifyResolution = require.resolve(`@yarnpkg/pnpify`, {paths: [dirname(absPnpApiPath)]});
if (typeof global[`__yarnpkg_sdk_is_using_pnpify__`] === `undefined`) {
Object.defineProperty(global, `__yarnpkg_sdk_is_using_pnpify__`, {configurable: true, value: true});
process.env.NODE_OPTIONS += ` -r ${pnpifyResolution}`;
// Apply PnPify to the current process
absRequire(pnpifyResolution).patchFs();
}
}
// Defer to the real prettier/index.js your application uses
module.exports = absRequire(`prettier/index.js`);
Thanks for the snippet @merceyz! I might try it next weekend if the new version of pnpify plugin is not yet released. Iām not in the rush with
It is possible that Prettier might support config ā plugins ā require.resolve at some point. See https://github.com/prettier/prettier/issues/7073#issuecomment-711420129. Iām still new to Yarn 2, so happy to be corrected if my suggestion does not lead to a working solution. The end goal is to enable this chain: prettier ā @my-company/prettier-config ā some-prettier-plugin. Installing all plugins into the project is quite inconvenient ā Iād like the config package to bring them on.
Turns out that config ā plugins ā require("some-plugin") is already supported by Prettier! This means that autodiscovery is not the only mechanism devs can rely on š Here is a short discussion: https://github.com/prettier/prettier/issues/7073#issuecomment-711954542
@asfernandes After discussion we decided to enable pnpify runtime on a per-tool basis and not shift the decision to the users, because they don't know the tradeoffs involved. For
prettierwe will always enable pnpify runtime starting from the next@yarnpkg/pnpifyversion:1913
Is there an ETA for @yarnpkg/pnpify next version including this?
@asfernandes Until it's released you can apply it manually, see https://github.com/yarnpkg/berry/issues/1903#issuecomment-711432671
@asfernandes Until it's released you can apply it manually, see #1903 (comment)
Unofrtunately, prettier still does not work for me in vscode. See the logs:
Error: Cannot find module '@yarnpkg/pnpify'
Require stack:
- /home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.yarn/sdks/prettier/internal.js
Require stack:
- /home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.yarn/sdks/prettier/index.js
- /home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js
- /snap/code/48/usr/share/code/resources/app/out/vs/loader.js
- /snap/code/48/usr/share/code/resources/app/out/bootstrap-amd.js
- /snap/code/48/usr/share/code/resources/app/out/bootstrap-fork.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:844:17)
at Function.external_module_.Module._resolveFilename (/home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.pnp.js:12954:46)
at callNativeResolution (/home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.pnp.js:13363:36)
at resolveToUnqualified (/home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.pnp.js:13569:24)
at resolveRequest (/home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.pnp.js:13821:29)
at Object.resolveRequest (/home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.pnp.js:13899:26)
at Function.external_module_.Module._resolveFilename (/home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.pnp.js:13003:34)
at Function.r.resolve (/snap/code/48/usr/share/code/resources/app/out/vs/loader.js:17:406)
at Object.<anonymous> (/home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.yarn/sdks/prettier/index.js:18:36)
at Module.i._compile (/snap/code/48/usr/share/code/resources/app/out/vs/loader.js:17:571)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1051:10)
at Module.load (internal/modules/cjs/loader.js:862:32)
at Module._load (internal/modules/cjs/loader.js:774:14)
at Module._load (electron/js2c/asar.js:769:28)
at t._load (/snap/code/48/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1057:776)
at i._load (/snap/code/48/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1027:486)
at n._load (/snap/code/48/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:1023:767)
at Function.external_module_.Module._load (/home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.pnp.js:12862:36)
at Module.require (internal/modules/cjs/loader.js:899:19)
at r (/snap/code/48/usr/share/code/resources/app/out/vs/loader.js:17:346)
at t.ModuleResolver.loadNodeModule (/home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js:1:30610)
at t.ModuleResolver.requireLocalPkg (/home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js:1:29738)
at t.ModuleResolver.getPrettierInstance (/home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js:1:28424)
at t.LanguageResolver.getSupportLanguages (/home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js:1:26531)
at t.LanguageResolver.getSupportedFileExtensions (/home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js:1:26367)
at t.default.selectors (/home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js:1:56123)
at t.default.registerFormatter (/home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js:1:55092)
at t.activate (/home/asfernandes/.vscode/extensions/esbenp.prettier-vscode-5.7.1/dist/extension.js:1:22370)
at Function._callActivateOptional (/snap/code/48/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:927:841)
at Function._callActivate (/snap/code/48/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:927:492)
at /snap/code/48/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:925:841
at processTicksAndRejections (internal/process/task_queues.js:94:5)
at async Promise.all (index 0)
The file /home/asfernandes/projects/github/node-fb/node-firebird-drivers.git/.yarn/sdks/prettier/internal.js does not exist.
You're missing @yarnpkg/pnpify as a dependency
You're missing
@yarnpkg/pnpifyas a dependency
I've it installed as described in the docs (as dependency - not devDependency)!
My project uses workspaces and to be sure, I've installed it in the root and all sub packages.
Please open a seperate issue with a reproduction
It hasn't been released yet, but you can apply it manually by editing
.yarn\sdks\prettier\index.jsand changing it to#!/usr/bin/env node const {existsSync} = require(`fs`); const {createRequire, createRequireFromPath} = require(`module`); const {resolve, dirname} = require(`path`); const relPnpApiPath = "../../../.pnp.js"; const absPnpApiPath = resolve(__dirname, relPnpApiPath); const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); if (existsSync(absPnpApiPath)) { if (!process.versions.pnp) { // Setup the environment to be able to require prettier/index.js require(absPnpApiPath).setup(); } const pnpifyResolution = require.resolve(`@yarnpkg/pnpify`, {paths: [dirname(absPnpApiPath)]}); if (typeof global[`__yarnpkg_sdk_is_using_pnpify__`] === `undefined`) { Object.defineProperty(global, `__yarnpkg_sdk_is_using_pnpify__`, {configurable: true, value: true}); process.env.NODE_OPTIONS += ` -r ${pnpifyResolution}`; // Apply PnPify to the current process absRequire(pnpifyResolution).patchFs(); } } // Defer to the real prettier/index.js your application uses module.exports = absRequire(`prettier/index.js`);
This is what my .yarn\sdks\prettier\index.js already looks like on the current version. I have @yarnpkg/pnpify installed as a dependency too.
Should we wait for new @yarnpkg/pnpify version or can you post a manual .yarn/sdks/prettier/index.js version so we can test?
I'll see if we can release a new version of @yarnpkg/pnpify, in the meantime here is the updated version
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire, createRequireFromPath} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../.pnp.js";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require prettier/index.js
require(absPnpApiPath).setup();
}
let pnpifyResolution;
try {
pnpifyResolution = absRequire.resolve(`@yarnpkg/pnpify`);
} catch (err) {}
if (pnpifyResolution) {
if (typeof global[`__yarnpkg_sdk_is_using_pnpify__`] === `undefined`) {
Object.defineProperty(global, `__yarnpkg_sdk_is_using_pnpify__`, {configurable: true, value: true});
process.env.NODE_OPTIONS += ` -r ${pnpifyResolution}`;
// Apply PnPify to the current process
absRequire(pnpifyResolution).patchFs();
}
}
}
// Defer to the real prettier/index.js your application uses
module.exports = absRequire(`prettier/index.js`);
nice, looks like @yarnpkg/pnpify doesn't have to be installed when using this .yarn/sdks/prettier/index.js
Most helpful comment
I'll see if we can release a new version of
@yarnpkg/pnpify, in the meantime here is the updated version