prettier / prettier-vscode

Visual Studio Code extension for Prettier
https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
MIT License
5.14k stars 455 forks source link

Caching module-path causes incorrect Prettier version to be used #2370

Closed samestep closed 2 years ago

samestep commented 2 years ago

Summary

Currently this extension caches the path to Prettier for each file in a VS Code workspace:

https://github.com/prettier/prettier-vscode/blob/da5b5ebfc4858a96e4ee6bc877a4026107b0fcab/src/ModuleResolver.ts#L307-L312

Sometimes the correct Prettier path for a given file changes, such as when using Lerna and removing a dependency from a package in favor of using a repository-wide version of that dependency; see https://github.com/penrose/penrose/issues/847 for an example of this exact situation.

When this happens, this extension continues trying to find Prettier in the old location rather than re-running findUp.sync to get the correct location. This fails with an error that prints a stack trace in the logs, as a result of which the extension incorrectly defaults to using the bundled version of Prettier instead of the repository-local version.

Github Repository to Reproduce Issue

https://github.com/samestep/prettier-vscode-caching

Steps To Reproduce:

  1. Clone the repository linked above.
  2. Open the cloned repository in VS Code.
  3. Run yarn from the repository root.
  4. Open the file packages/foo/index.js.
  5. Run Format Document. The file should remain unchanged, and no errors should appear in the logs.
  6. Run git switch consolidate.
  7. Run rm -r packages/foo/node_modules/ from the repository root.
  8. Run yarn again.
  9. Run Developer: Reload Window.
  10. Run Format Document again on the same file.

Expected result

The file should remain unchanged at the last step. Switching to the consolidate branch removed prettier from the devDependencies of packages/foo/package.json, meaning that this extension should instead keep going up two more directories to find it in the devDependencies of package.json in the repository root, so it should use Prettier version 2.2.1. Indeed, this is exactly what happens if you checkout the consolidate branch first, before using VS Code to run Prettier on packages/foo/index.js from branch main, because at that point the cache has not yet been populated.

Actual result

An error appears in the logs (see below), and the file gets reformatted according to Prettier 2.5.1 bundled with this extension (which happens to give the same result as Prettier 2.3.0 in this case).

Additional information

VS Code Version: 1.63.2 (Universal)

Prettier Extension Version: 9.1.0

OS and version: macOS Big Sur 11.6.2

Prettier Log Output

["INFO" - 5:14:53 PM] Extension Name: esbenp.prettier-vscode.
["INFO" - 5:14:53 PM] Extension Version: 9.1.0.
["DEBUG" - 5:14:53 PM] Enabling Prettier globally
{
  "languageSelector": [
    {
      "language": "javascript"
    },
    {
      "language": "mongo"
    },
    {
      "language": "javascriptreact"
    },
    {
      "language": "typescript"
    },
    {
      "language": "typescriptreact"
    },
    {
      "language": "json"
    },
    {
      "language": "jsonc"
    },
    {
      "language": "json5"
    },
    {
      "language": "css"
    },
    {
      "language": "postcss"
    },
    {
      "language": "less"
    },
    {
      "language": "scss"
    },
    {
      "language": "handlebars"
    },
    {
      "language": "graphql"
    },
    {
      "language": "markdown"
    },
    {
      "language": "mdx"
    },
    {
      "language": "html"
    },
    {
      "language": "vue"
    },
    {
      "language": "yaml"
    },
    {
      "language": "ansible"
    },
    {
      "language": "home-assistant"
    },
    {
      "language": "jsonc",
      "scheme": "vscode-userdata"
    }
  ],
  "rangeLanguageSelector": [
    {
      "language": "javascript"
    },
    {
      "language": "javascriptreact"
    },
    {
      "language": "typescript"
    },
    {
      "language": "typescriptreact"
    },
    {
      "language": "json"
    },
    {
      "language": "graphql"
    },
    {
      "language": "handlebars"
    }
  ]
}
["DEBUG" - 5:14:53 PM] Enabling Prettier for Workspace /Users/samueles/github/samestep/prettier-vscode-caching
{
  "languageSelector": [
    {
      "pattern": "/Users/samueles/github/samestep/prettier-vscode-caching/**/*.{js,_js,bones,cjs,es,es6,frag,gs,jake,jsb,jscad,jsfl,jsm,jss,mjs,njs,pac,sjs,ssjs,xsjs,xsjslib,wxs,js.flow,jsx,ts,mts,cts,tsx,json,avsc,geojson,gltf,har,ice,JSON-tmLanguage,mcmeta,tfstate,tfstate.backup,topojson,webapp,webmanifest,yy,yyp,jsonc,sublime-build,sublime-commands,sublime-completions,sublime-keymap,sublime-macro,sublime-menu,sublime-mousemap,sublime-project,sublime-settings,sublime-theme,sublime-workspace,sublime_metrics,sublime_session,json5,css,wxss,pcss,postcss,less,scss,handlebars,hbs,graphql,gql,graphqls,md,markdown,mdown,mdwn,mkd,mkdn,mkdown,ronn,scd,workbook,mdx,component.html,html,htm,html.hl,inc,xht,xhtml,mjml,vue,yml,mir,reek,rviz,sublime-syntax,syntax,yaml,yaml-tmlanguage,yaml.sed,yml.mysql,st}",
      "scheme": "file"
    },
    {
      "language": "javascript"
    },
    {
      "language": "mongo"
    },
    {
      "language": "javascriptreact"
    },
    {
      "language": "typescript"
    },
    {
      "language": "typescriptreact"
    },
    {
      "language": "json"
    },
    {
      "language": "jsonc"
    },
    {
      "language": "json5"
    },
    {
      "language": "css"
    },
    {
      "language": "postcss"
    },
    {
      "language": "less"
    },
    {
      "language": "scss"
    },
    {
      "language": "handlebars"
    },
    {
      "language": "graphql"
    },
    {
      "language": "markdown"
    },
    {
      "language": "mdx"
    },
    {
      "language": "html"
    },
    {
      "language": "vue"
    },
    {
      "language": "yaml"
    },
    {
      "language": "ansible"
    },
    {
      "language": "home-assistant"
    },
    {
      "language": "jsonc",
      "scheme": "vscode-userdata"
    }
  ],
  "rangeLanguageSelector": [
    {
      "language": "javascript"
    },
    {
      "language": "javascriptreact"
    },
    {
      "language": "typescript"
    },
    {
      "language": "typescriptreact"
    },
    {
      "language": "json"
    },
    {
      "language": "graphql"
    },
    {
      "language": "handlebars"
    }
  ]
}
["INFO" - 5:15:08 PM] Formatting file:///Users/samueles/github/samestep/prettier-vscode-caching/packages/foo/index.js
["ERROR" - 5:15:08 PM] Error loading node module '/Users/samueles/github/samestep/prettier-vscode-caching/packages/foo/node_modules/prettier/index.js'
["ERROR" - 5:15:08 PM] Cannot find module '/Users/samueles/github/samestep/prettier-vscode-caching/packages/foo/node_modules/prettier/index.js'
Require stack:
- /Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/loader.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-amd.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-fork.js
Error: Cannot find module '/Users/samueles/github/samestep/prettier-vscode-caching/packages/foo/node_modules/prettier/index.js'
Require stack:
- /Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/loader.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-amd.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-fork.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:934:15)
    at Module._load (internal/modules/cjs/loader.js:779:27)
    at Function.f._load (electron/js2c/asar_bundle.js:5:12913)
    at Function.t._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:114:32222)
    at Function.p._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:114:28887)
    at Function.f._load (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:104:61699)
    at Module.require (internal/modules/cjs/loader.js:1006:19)
    at Module.require (/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/microsoft-authentication/dist/extension.js:1:38461)
    at h (/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/loader.js:4:699)
    at t.ModuleResolver.loadNodeModule (/Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js:1:6025)
    at t.ModuleResolver.<anonymous> (/Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js:1:4256)
    at Generator.next (<anonymous>)
    at /Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js:1:2825
    at new Promise (<anonymous>)
    at n (/Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js:1:2570)
    at t.ModuleResolver.getPrettierInstance (/Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js:1:3383)
    at t.default.<anonymous> (/Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js:1:13515)
    at Generator.next (<anonymous>)
    at s (/Users/samueles/.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js:1:7872)
["DEBUG" - 5:15:08 PM] Using bundled version of prettier.
["INFO" - 5:15:08 PM] Using ignore file (if present) at /Users/samueles/github/samestep/prettier-vscode-caching/.prettierignore
["INFO" - 5:15:08 PM] File Info:
{
  "ignored": false,
  "inferredParser": "babel"
}
["INFO" - 5:15:08 PM] No local configuration (i.e. .prettierrc or .editorconfig) detected, falling back to VS Code configuration
["INFO" - 5:15:08 PM] Prettier Options:
{
  "arrowParens": "always",
  "bracketSpacing": true,
  "endOfLine": "lf",
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 80,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": false,
  "vueIndentScriptAndStyle": false,
  "filepath": "/Users/samueles/github/samestep/prettier-vscode-caching/packages/foo/index.js",
  "parser": "babel"
}
["INFO" - 5:15:08 PM] Formatting completed in 0.042ms.
samestep commented 2 years ago

I'm guessing that the cache is there for a reason, so I want to make a pull request that changes the cache from being persistent to being session-scoped, so for instance, it could be cleared by Developer: Reload Window. However, I'm not sure how to write a test for this; I was going to put it alongside the existing getPrettierInstance test suite, but I'm guessing that those all take place within a single VS Code instance session. For now I'll just make a pull request without an automated test.

samestep commented 2 years ago

It seems like this could be resolved by simply reverting 03b65aa632eda7ad9ac714f2709daa7b1d8819fe?

github-actions[bot] commented 2 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.