Vscode-eslint: Do not always run eslint from the project's root directory

Created on 1 Feb 2017  路  22Comments  路  Source: microsoft/vscode-eslint

First off, thanks for all the great work you've been doing so far! 馃憤

I just ran into an issue:

I'm working on a project with a structure like this:

project
|- server-app
|- web-app-1
|- web-app-2

when I open vscode for a web-app via code /path/tp/project/web-app-1 vscode-eslint works as expected.

If I open the whole project via code /path/tp/project however I get plenty of linting errors on files that worked before. Errors look like:

Resolve error: ENOENT: no such file or directory, open /path/tp/project/package.json'  import/no-unresolved

and indeed, there's no package.json in the project root. It's in /path/tp/project/web-app-1/package.json

The output is the very same as if I did

cd /path/tp/project
node web-app-1/node_modules/eslint/bin/eslint.js web-app-1/src/path/to/file

So I assume vscode-eslint calls eslint from the project root, rather than from the web-app's root which causes issues with e.g. eslint-plugin-import.

Is there a way to fix this? Maybe by looking for the root package.json for each .js file and calling eslint from its directory?

feature-request help wanted

Most helpful comment

I couldn't get it to work either. I did the following enhancement. The workingDirectories take an object literal as well which allows you to tell ESLint to change the process.cwd as well. Changing this has to be used with care and is therefore off by default. A config looks like this:

{
    "eslint.workingDirectories": [
        { 
            "directory": "web-app", 
            "changeProcessCWD": true
        }
    ]
}

All 22 comments

@danielberndt the eslint extension runs basically a eslint server to speed up validation time and to save battery. The eslint server process is kept alive as long as VS Code is alive for that project. The server is started on the same directory than VS Code. It does support reading multiple eslint library version however it can't support multiple cwd and changing the cwd on the fly might not be a good idea.

Due to its design I currently don't have a good idea how to fix it. Does someone else have ?

Thanks for the quick reply, @dbaeumer!

From my perspective the simplest approach seems to be to spin up one server per web-app. This would probably also make it quite straight forward to support various eslint versions and rules that might be present in each of the different web-apps.

And rather than guessing where to locate the web-apps, I personally would be fine with an option within the settings:

eslint.roots: ["."] //default
eslint.roots: ["./web-app-1". "./web-app-2"] // for the use case explained above

As a bonus the servers could be spun up lazily. I.e. if you're not touching any file within web-app-2 its server is not started.

Good idea. The support for various eslint version and configuration is already present today since node can load n versions of the same library.

@danielberndt would you be willing to work on a PR for this.

@danielberndt I think I found an easier way to fix this. The ESLint library allows to set a cwd for every lint run. I change the code in ESLint and will publish a new version beginning of next week. Can you check if this fixes your problem?

Ah great! And yeah, just let me know once it's out and I'll check it as soon as it's out :)

Published 1.2.5. However I need to make this a configuration options along the lines you proposed since always taking the files directory as a cwd breaks other use cases.

That's good news :)

I just updated the plugin to v1.2.5, and updated the workspace settings to

"eslint.workingDirectories": [
    "./web-app"
  ]

and restarted vscode. The error still seems to persist however. I still get the same message as before:

[eslint] Resolve error: ENOENT: no such file or directory, open 'path/to/project-root/package.json' (import/no-absolute-path)

(the package.json is located at 'path/to/project-root/web-app/package.json)

I'm using these dependencies:

"babel-eslint": "^7.1.1",
"eslint": "^3.14.1",
"eslint-plugin-import": "^2.2.0",

and my eslintrc looks like:

{
  "parser": "babel-eslint",
  "extends": [
    "plugin:import/errors",
    "plugin:import/warnings"
  ]
}

anything else that would help you analysing the issue?

Ah also: I'm on Win 10 and VSCode 1.9

@danielberndt I guess that you need to install eslint into the web-app directory as well.

Can I clone your project from a GitHub repository. Then I can look into why this is not working ?

I just sent out an invite. The sub-folder in question is the ./web-app one.

Accepted the invite.

@danielberndt I could not reproduce this. Here is what I did:

  • cloned the repository
  • switch to web-app directory
  • ran npm install
  • opened VS Code on the root directory
  • added a setting workspace setting:
{
    "eslint.workingDirectories": [
        "web-app"
    ]
}
  • opened a JS file.

Here is what I see:

capture

Any additional steps?

I'm referring to all the red markers you can see on the screenshot in the upper right. Around the import statements.
These only show up if I open the project in the root directory but not if I open it in the sub-folder.

I am a little bit puzzled. In the original post you set you are seeing exception which I don't see

Resolve error: ENOENT: no such file or directory, open /path/tp/project/package.json'  import/no-unresolved

I will see what makes the difference when opening on the folder

OK. Now I see. The eslint error message is Resolve error: ENOENT: no such file or directory, open /path/tp/project/package.json' import/no-unresolved

I though it was a message on the console.

Actually running it from the terminal prints the same set of problem when in the root folder

 1:1   error    Resolve error: ENOENT: no such file or directory, open 'P:\mseng\VSCode\Playgrounds\bugs\es-196\package.json'  import/extensions
  1:1   error    Resolve error: ENOENT: no such file or directory, open 'P:\mseng\VSCode\Playgrounds\bugs\es-196\package.json'  import/namespace
....

I have to admit I even don't know why eslint is trying to open the package.json. Very lilkey one of the eslint plugins.

Yeah it's most likely the eslint-plugin-import package (which seems to be quite popular given its download numbers on npm) causing this issue. Here's a section of their README discussing something thats probably related.

I investigates a little more and this is only a problem on startup. Somehow one of the plugins you are using needs a package.json file and doesn't respect the cwd setting of ESLint. As soon as the plugin is loaded you can validate any file from the web-app sub directory without problem. @danielberndt do you know which of your ESLint plugins need / read the package.json file during first use.

This error seems only to show up if I include the settings for eslint-import-resolver-webpack in the eslintrc.

And indeed its source shows some references to package.json

Looks like they have some sort of config setting options (from reading the code). Have you tried to set this?

yeah I'm pointing it to the correct webpack config file. But even using an absolute path doesn't help here. Issue stays the same.

I couldn't get it to work either. I did the following enhancement. The workingDirectories take an object literal as well which allows you to tell ESLint to change the process.cwd as well. Changing this has to be used with care and is therefore off by default. A config looks like this:

{
    "eslint.workingDirectories": [
        { 
            "directory": "web-app", 
            "changeProcessCWD": true
        }
    ]
}
Was this page helpful?
0 / 5 - 0 ratings