prettier-vscode: Plugin has a conflict with the built-in organize imports

As soon as VScode was updated to 1.31.0, it appears that this prettier extensions conflicts with the the built-in organize imports setting, when organize imports on save is enabled.

prettier: "prettier": "^1.16.4", (was initially on 1.13.7, tried to update) vscode: Version 1.31.0 (1.31.0) extension: 1.8.0

I first opened a ticket with vscode core, but was referred to the extension as the source of the problem: https://github.com/Microsoft/vscode/issues/68193

Steps to reproduce

  1. Add setting for editor.codeActionsOnSave.source.organizeImports = true (see below for example json)
  2. Ensure prettier is configured to format on save
  3. create a ts file (may also work with js) that has an import that exceeds the configured line length, which should be turned into a multi-line import
  4. Save file

Expected behavior:

  1. imports should be organized
  2. imports should be formatted to multi-line import
  3. file should be saved

Actual behavior:

  1. imports are organized
  2. imports remain on a single line
  3. file remains “dirty” - with the little white dot in the tab-bar

Note: I can format the document manually using the command menu and the import is correctly formatted, but then on save it is unformatted and the file shows as modified by the file system.

"editor.codeActionsOnSave": {
    "source.organizeImports": true
},

Initial file

image

Format file manually, just to show that it works

image

image

After Save (cmd+s)

image

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 69
  • Comments: 38 (6 by maintainers)

Most upvoted comments

After playing with some of the VSCode settings a bit more, you can make the editor behave in a REALLY strange way:

weird_formatting_conflicts

And look at what happens if you repeatedly save the file:

image

Yep, either Prettier or VSCode’s organizeImports breaks code - looks like a race condition. I’d stay away from organizeImports for now.

Can this be solved in some way? I would like to help if I can to implement this.

I disabled source.organizeImports and installed this prettier plugin:

https://github.com/simonhaenisch/prettier-plugin-organize-imports

The problem was fixed after a restart!

@ntotten I think this is a bug, not an enhancement. It means Prettier VSCode is totally incompatible with one of VSCode’s more useful features.

In the new VSCode v1.44.x, Explicit ordering for Code Actions on save was introduced. It looks like it might be the answer we’ve been searching for years. However, I tried playing with it but failed to get it to work.

What I tried was:

// settings.json
"editor.formatOnSave": false,
"editor.codeActionsOnSave": [
  "source.organizeImports",
  "editor.action.formatDocument" // does not work
],

The problem is, I don’t know what actions are available. I got the source.organizeImports from the examples in the docs, and got the editor.action.formatDocument from the keybinding UI, but apparently it won’t just work like that.

This happens to me frequently when my imports are long enough that Prettier needs to wrap them. I believe it’s also related to the fact that I’m running a large project so my CPU is usually pretty throttled on save. What typically happens is, I press save, the imports are organized, then Prettier runs and reformats them, but then the file is still marked “dirty” - I have to save it again (or maybe 2 or 3 more times) before the little asterisk in the tab is gone. It feels like there’s a race condition here that is exacerbated by the CPU demands of other TypeScript activities.

It seems weird that this is getting so little attention, considering it’s the 3rd most upvoted issue of prettier-vscode. @nikitavoloboev even offered to help. Couldn’t a member pick him up on that?

Question: isn’t the issue here the sequence of invocation? In other words, if one could make sure that the reshuffling of the imports always happened before the invocation of Prettier, we would be golden.

Playing around with this, one semi-workaround is to set prettier’s printWidth to 120. The VS Code sorter/formatter for imports appears to be hardcoded to 120 characters. There is an issue to make this setting customizable in VS Code (https://github.com/microsoft/TypeScript/issues/22991), if they did that I think setting the VS Code setting and prettier to the same length would remove the flicker.

Since Microsoft has closed the issue (https://github.com/microsoft/vscode/issues/87096) that would have enabled us to solve this and has indicated they are not going to fix it, this isn’t something that the extension can fix. As such I am closing this issue.

I found a workaround: a 6 core i7. No joke - my new macbook can run these two settings in tandem with no issues 🤔🙄

@janosh https://github.com/prettier/prettier-vscode/issues/716#issuecomment-515533849

I get that its an annoyance, but I am not even sure fixing it is possible. VS Code runes save actions that extensions provide, this extension doesn’t know anything about nor have any influence on the order imports.

Any member can chime in?

“Organize Imports” in VS Code works for both TS and JS and uses (afaik) the same implementation.

@janosh Could try this approach, https://github.com/prettier/prettier-vscode/issues/1277#issuecomment-621175180, but with organize-imports instead of eslint. This is similar to @ZYinMD approach above, but I could not get that to work.

Install this VSCode extension. https://github.com/rohit-gohri/vscode-format-code-action/

This registers a custom codeAction: source.fixAll.format, which we can use instead of formatOnSave. It’ll trigger “Format Document” with whatever default formatter you have setup.

These settings would run organizeImports first and then prettier on save:

  "editor.formatOnSave": false,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": [
	"source.organizeImports",
    "source.fixAll.format"
  ]

I need somebody to provide a github repo I can use to reproduce this. I do see the flicker where first the organize is applied, then prettier is applied, but I can’t get it to actually cause any problems like “corrupted” files.