microsoft / vscode-eslint

VSCode extension to integrate eslint into VSCode
MIT License
1.75k stars 335 forks source link

Workspace-level "eslint.workingDirectories" option not being obeyed #1664

Closed ArcanoxDragon closed 11 months ago

ArcanoxDragon commented 1 year ago

I have a multi-project workspace (monorepo) set up for my organization for our Webpack-bundled code. I have ESLint configured to lint the entire monorepo all at once, which works fine when invoked from the CLI or from the Webpack plugin, but the ESLint extension doesn't seem to want to lint at the workspace level.

Here is an abridged description of our workspace layout:

The .code-workspace file lists the root directory and each project folder in folders:

{
    "folders": [
        {
            "path": "."
        },
        {
            "path": "projects/project1"
        },
        {
            "path": "projects/project2"
        },
        // ...
    ]
}

Our .eslintrc.yml file configures the tsconfig.json file as such:

parser: "@typescript-eslint/parser"
parserOptions:
  project: ./projects/tsconfig.json

I can run yarn eslint projects from the root Webpack folder and it will properly lint all project code using the correct settings and tsconfig.json file. However, if I open up any .ts/.tsx file within one of the project folders, an error is highlighted on the first line that says Parsing error: Cannot read file 'c:\<HIDDEN>\webpack\projects\project1\projects\tsconfig.json'.

It is clearly running eslint within the Webpack\projects\project1 directory and then attempting to resolve the relative ./projects/tsconfig.json path from there, which obviously doesn't work. I tried to add this to the .code-workspace file settings:

"settings": {
    "eslint.workingDirectories": [
        {
            "directory": "."
        }
    ],
    // ...
}

but that doesn't work either. I even tried replacing "." with the absolute path to the Webpack folder on my machine to see if it made a difference, and it did not.

The only way I'm able to get the plugin to run eslint in the correct working directory is to add a .vscode/settings.json file underneath every single project folder containing the eslint.workingDirectories setting from above (except using "../.." as the path). I'd really rather not have to do this...we have far more than two projects in the real workspace.

Why does the extension not respect the workspace-level eslint.workingDirectories setting if there are no folder-level settings overriding it? This seems like a bug.

dbaeumer commented 1 year ago

The setting from the code-workspace file is read and respected. However '.' simply keeps it on the workspace folder (which by the way is the default anyways in a multi folder setup).

I think what you want to achieve is to use the folder that contains the code-workspace file as the working directory. However this folder is not know inside the extension (not exposed in VS Code's API) since such a folder must not necessarily exist. A code-workspace file can bind arbitrary folders together without having a common root folder.

Since the default working directory for a workspace folder is the folder itself a value of '..' would move the working directory in our case to projects and '../..' to the code workspace folder. Have you tried using "../.." ?

The only other solution I can think of is to allow absolute paths (which are always hard when a project is shared) or variables in settings which need to be supported by VS Code itself (there is a work item for it).

ArcanoxDragon commented 1 year ago

I did try "../.." as well; it had the same error as with ".". That's what led me to believe the setting was not being respected at all. I will try again tomorrow just to be sure (it's possible I didn't wait long enough for the extension to pick up the change, or something).

Are absolute paths not supported at all right now? I expected that to work if nothing else did, but it did not. That's obviously not a solution I would want to use as more than just a temporary hold-over (or even commit into source control).

dbaeumer commented 1 year ago

An absolute path should be supported as long as it is a prefix to the path that is validated. You can't right now point to a path outside of the root workspace.

airtonix commented 1 year ago

I think what you want to achieve is to use the folder that contains the code-workspace file as the working directory. However this folder is not know inside the extension (not exposed in VS Code's API) since such a folder must not necessarily exist. A code-workspace file can bind arbitrary folders together without having a common root folder.

Actually it is.

We're supposed to be able to do this to get the folder of a workspace folder:


    "eslint.options": {
      "configFile": "${Repo:workspaceFolder}/eslint.config.js"
    },

and so if I do this:

project.code-workspace

{
  "folders": [
    {
      "name": "Repo",
      "path": "."
    },
    {
      "name": "SomeApp",
      "path": "./apps/someapp"
    }
  ],
  "settings": {
    ...
    "eslint.run": "onSave",
    "eslint.format.enable": true,
    "eslint.debug": true,
    "eslint.workingDirectories": [
      {
        "mode": "auto"
      }
    ],
    "eslint.validate": [
      "javascript",
      "javascriptreact",
      "typescript",
      "typescriptreact"
    ],
    "eslint.options": {
      "configFile": "${Repo:workspaceFolder}/eslint.config.js"
    },
    ...
  }
}

supposedly it will use the folder of Repo workspace.

However this extension only treats that eslint.options.configFile as a literal string without resolving it first.

https://code.visualstudio.com/docs/editor/multi-root-workspaces#_workspace-launch-configurations

edit: it's under "launch configurations", so I don't know if that means it's supported in .code-workspace or not, but can we check if this extension is properly using the multi workspace api?

related: https://github.com/microsoft/vscode/issues/2809

dbaeumer commented 1 year ago

@airtonix you are actually pointing to the right VS Code issute. The problem is that VS Code should offer a mechanism to resolve variables. IMO it doesn't make sense that every extension does this. In addition extensions doing this will result in different variable names sooner or later.

dbaeumer commented 11 months ago

I will close the issue. As pointed out the right solution will be variables in settings which should come from VS Code.