Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't get eslint working #526

Closed
karolyi opened this issue Feb 27, 2019 · 22 comments
Closed

can't get eslint working #526

karolyi opened this issue Feb 27, 2019 · 22 comments

Comments

@karolyi
Copy link

karolyi commented Feb 27, 2019

Hey,

I am trying to get the eslint server working, but to no avail. I have tried the vscode-eslint server as seen in an example config (although vscode-eslint is not on npm), and I have tried several versions of the eslint server that takes the --stdin value.

The server is started, but my code doesn't seem to output the eslint errors that I have configured to display with running eslint manually.

  • OS and language server: I've tried it both on OSX and Linux (WSL).
  • How you installed LSP (Package Control or from git?): LSP was installed in sublime from package control
  • Minimal reproduction steps: Just try to get eslint working ... you can't

an example config for eslint-server:

			"eslint":
			{
				"enabled": true,
				"command":
				[
					"node",
					"/home/karolyi/Work/private/project/node_modules/eslint-server/lib/index.js",
					"--stdio"
				],
			},
  • Log
LSP: global configs ['reason=False', 'lsp-tsserver=False', 'rls=False', 'pyls=True', 'cquery=False', 'polymer-ide=False', 'clangd=False', 'haskell-ide-engine=False', 'jdtls=False', 'ocaml=False', 'golsp=False', 'eslint=False', 'typescript-language-server=False', 'javascript-typescript-langserver=False', 'phpls=False']
LSP: window 2 has override for pyls {'command': ['/home/karolyi/Work/private/project/venv/bin/pyls'], 'languageId': 'python', 'syntaxes': ['Packages/Python/Python.sublime-syntax', 'Packages/Djaneiro/Syntaxes/Python Django.tmLanguage'], 'enabled': True, 'scopes': ['source.python']}
LSP: window 2 has override for eslint {'command': ['node', '/home/karolyi/Work/private/project/node_modules/eslint-server/lib/index.js', '--stdio'], 'enabled': True}
LSP: window 2 starting 1 initial views
LSP: window 2 requests eslint for /home/karolyi/Work/private/project/frontend/src/js/shop/sign-up.js
LSP: starting in /home/karolyi/Work/private/project
LSP: starting ['node', '/home/karolyi/Work/private/project/node_modules/eslint-server/lib/index.js', '--stdio']
LSP:  --> initialize
LSP: window 2 added session eslint
LSP:      {'capabilities': {'codeActionProvider': True, 'textDocumentSync': {'change': 1, 'willSaveWaitUntil': True, 'openClose': True, 'save': {'includeText': False}}, 'executeCommandProvider': {'commands': ['eslint.applySingleFix', 'eslint.applySameFixes', 'eslint.applyAllFixes', 'eslint.applyAutoFix']}}}
LSP:  --> initialized
LSP:  --> textDocument/didOpen
LSP: <--  client/registerCapability
LSP:      {'registrations': [{'id': 'c697f786-6386-45a0-8503-adc31f5422bc', 'registerOptions': {}, 'method': 'workspace/didChangeConfiguration'}]}
LSP: Unhandled request client/registerCapability
LSP: <--  workspace/configuration
LSP:      {'items': [{'scopeUri': 'file:///home/karolyi/Work/private/project/frontend/src/js/shop/sign-up.js', 'section': ''}]}
LSP: Unhandled request workspace/configuration
LSP:  --> textDocument/didSave

Would there be a way for you to integrate https://github.com/tbodt/js-langserver ? It uses tern and eslint the same time, which would be perfect.

@rwols
Copy link
Member

rwols commented Feb 27, 2019

It might be because eslint sends the workspace/configuration request, to which we don't have a response.

See: https://microsoft.github.io/language-server-protocol/specification#workspace_configuration

Could you figure out what VSCode does in case it receives a workspace/configuration request from eslint?

@karolyi
Copy link
Author

karolyi commented Feb 27, 2019

Hey,

thanks for getting back to me this quick. Unfortunately I don't use vscode, and I'm totally a newcomer to LSP. I started out installing it only yesterday.

Eslint in itself is not that important if I can get the above mentioned js-langserver working, as it supposedly does JS and linting in one.

@rwols
Copy link
Member

rwols commented Feb 27, 2019

I'm not a JS user, so if you could give me precise instructions on how to install this js-langserver I could give it a try on getting it to work.

@karolyi
Copy link
Author

karolyi commented Feb 27, 2019

With pleasure :)

You install it with npm i --save-dev js-langserver, and then here's the config snippet I tried out with it, using eslint (but I suppose any driver should do):

			"eslint":
			{
				"enabled": true,
				"command":
				[
					"/home/karolyi/Work/private/project/node_modules/.bin/js-langserver",
					"--stdio"
				],
			},

You can also start it manually with the above command line to see if it works. Thanks for your efforts!

@rwols
Copy link
Member

rwols commented Feb 27, 2019

This seems to be working for me:

		"js-langserver":
		{
			// npm i --save-dev js-langserver
			"enabled": true,
			"command":
			[
				"node",
				"/home/raoul/Documents/js-langserver-installed/node_modules/.bin/js-langserver",
				"--stdio",
			],
			"scopes": ["source.js"],
			"syntaxes": ["Packages/Javascript/Javascript.sublime-syntax"],
			"languageId": "js"
		}

But I don't know how to actually test if eslint does its thing with this server.

@karolyi
Copy link
Author

karolyi commented Feb 27, 2019

Um, where does js-langserver as a section come from? Or can one use arbitrary section names? I put this configuration in my project config, and it does not seem to do anything. When I switch over to the JS file, it says in the console:

LSP: no config found or enabled for view /home/karolyi/Work/private/project/frontend/src/js/shop/sign-up.js

I guess it's not recognizing that it should use this server for it?

@karolyi
Copy link
Author

karolyi commented Feb 27, 2019

I'm still just scratching the surface, but I added a default_client section for it in the global LSP config and it got recognized.

However after starting, I still get this debug from LSP:

LSP: starting ['/home/karolyi/Work/private/project/node_modules/.bin/js-langserver', '--stdio']
LSP:  --> initialize
LSP: window 2 added session js-langserver
LSP:      None
LSP: Request initialize failed with message: Cannot convert undefined or null to object

@rwols
Copy link
Member

rwols commented Feb 27, 2019

That js-langserver section goes into the clients dict of your user preferences.

Click to see my complete personal preferences
{
    "clients":
    {
        "pyls":
        {
            "enabled": true
        },
        "clangd":
        {
            "command": ["clangd-8", "-log=error", "-header-insertion-decorators=0"],
            "enabled": true
        },
        "ccls":
        {
            "command":
            [
                "/home/raoul/Documents/ccls/build/ccls"
            ],
            "enabled": false,
            "initializationOptions":
            {
                "cacheDirectory": "/tmp/ccls"
            },
            "languages":
            [
                {
                    "languageId": "c",
                    "scopes":
                    [
                        "source.c"
                    ],
                    "syntaxes":
                    [
                        "Packages/C++/C.sublime-syntax"
                    ]
                },
                {
                    "languageId": "cpp",
                    "scopes":
                    [
                        "source.c++"
                    ],
                    "syntaxes":
                    [
                        "Packages/C++/C++.sublime-syntax"
                    ]
                },
                {
                    "languageId": "objective-c",
                    "scopes":
                    [
                        "source.objc"
                    ],
                    "syntaxes":
                    [
                        "Packages/Objective-C/Objective-C.sublime-syntax"
                    ]
                },
                {
                    "languageId": "objective-cpp",
                    "scopes":
                    [
                        "source.objc++"
                    ],
                    "syntaxes":
                    [
                        "Packages/Objective-C/Objective-C++.sublime-syntax"
                    ]
                }
            ]
        },
        "intelephense-ls":
        {
            // npm i -g intelephense
            "enabled": false,
            "command":
            [
                "node",
                "/usr/local/lib/node_modules/intelephense/lib/intelephense.js",
                "--stdio",
            ],
            "scopes": ["source.php", "embedding.php"],
            "syntaxes": ["Packages/PHP/PHP.sublime-syntax"],
            "languageId": "php",
            "initializationOptions": {
                "storagePath": "/tmp/intelephense-ls",
            },
        },
        "js-langserver":
        {
            // npm i --save-dev js-langserver
            "enabled": true,
            "command":
            [
                "node",
                "/home/raoul/Documents/js-langserver-installed/node_modules/.bin/js-langserver",
                "--stdio",
            ],
            "scopes": ["source.js"],
            "syntaxes": ["Packages/Javascript/Javascript.sublime-syntax"],
            "languageId": "js"
        }
    },
    "complete_using_text_edit": true,
    "auto_show_diagnostics_panel": false,
    "log_debug": true,
    "log_server": false,
    "log_stderr": false,
    "log_payloads": true
}

@rwols
Copy link
Member

rwols commented Feb 27, 2019

By the way, do not override default_clients! Doing so will disable all other pre-configured language servers. Instead, override clients in your user preferences (see my personal config as an example).

@karolyi
Copy link
Author

karolyi commented Feb 27, 2019

Yep, I did that now, and started initializing. Yet, the error message is the same as above in #526 (comment)

@predragnikolic
Copy link
Member

I got the same message

LSP: starting ['node', '/home/predrag/.npm-global/bin/js-langserver', '--stdio']
LSP:  --> initialize
LSP: window 2 added session js-langserver
LSP: Request initialize failed with message: Cannot convert undefined or null to object

With the following config

{
	"clients":
	{
		"js-langserver":
		{
			// npm i --save-dev js-langserver
			"enabled": true,
			"command":
			[
				"node",
				"/home/predrag/.npm-global/bin/js-langserver",
				"--stdio",
			],
			"scopes": 	[
				"source.js",
				"source.jsx",
				"source.ts",
				"source.tsx"
			],
			"syntaxes": [				
				"Packages/User/JS Custom/Syntaxes/React.sublime-syntax",
				"Packages/JavaScript/JavaScript.sublime-syntax",
				"Packages/Babel/JavaScript (Babel).sublime-syntax",
				"Packages/TypeScript Syntax/TypeScript.tmLanguage",
				"Packages/TypeScript Syntax/TypeScriptReact.tmLanguage"
			],
			"languageId": "js"
		},
                ...

And I don't know why :)

@rchl
Copy link
Member

rchl commented Feb 27, 2019

Topic changed from eslint-server to js-langserver but I'll go back to initial problem and question:

Could you figure out what VSCode does in case it receives a workspace/configuration request from eslint?

I've checked that:


[Trace - 10:29:36 PM] Received request 'workspace/configuration - (2)'.
Params: {
    "items": [
        {
            "scopeUri": "file:///Users/foo/workspace/dynamodb-admin/lib/actions/purgeTable.js",
            "section": ""
        }
    ]
}


[Trace - 10:29:36 PM] Sending response 'workspace/configuration - (2)'. Processing request took 2ms
Result: [
    {
        "validate": true,
        "packageManager": "npm",
        "autoFix": true,
        "autoFixOnSave": false,
        "options": {},
        "run": "onType",
        "nodePath": null,
        "workspaceFolder": {
            "name": "dynamodb-admin",
            "uri": "file:///Users/foo/workspace/dynamodb-admin"
        },
        "codeAction": {
            "disableRuleComment": {
                "enable": true,
                "location": "newLine"
            },
            "showDocumentation": {
                "enable": true
            }
        }
    }
]

Here is the code that sends the response: https://github.com/Microsoft/vscode-eslint/blob/ff75d429be69ec09237ee859343739768f6c4a6d/client/src/extension.ts#L470

And here is, I think, the code that validates response: https://github.com/Microsoft/vscode-eslint/blob/ff75d429be69ec09237ee859343739768f6c4a6d/server/src/eslintServer.ts#L416

It seems that LSP would need to send pretty much the same response for server not to break but I haven't verified if that's all that is needed.

(It would probably be best to split this discussion into two bugs, one for each LS.)

@rwols
Copy link
Member

rwols commented Feb 27, 2019

Hi @rchl, this seems useful information. Also notice that the response type of workspace/configuration is an any[], so it seems hopeless to create a general-purpose solution. Perhaps we may need an LSP-eslint plugin: #508

I don't understand the js-langserver error, and I also cannot find that particular error message (or part of it) in the python code, so I am somewhat at a loss where that error comes from.

@mwilliammyers
Copy link

I think the error is coming from js-langserver? See: tbodt/js-langserver#1 (comment)

@mwilliammyers
Copy link

This will be fixed once tbodt/js-langserver#5 is merged.

@tomv564
Copy link
Contributor

tomv564 commented Aug 26, 2019

I'll close this issue as js-langserver should be a working alternative for now. Created #699 if we want to support the workspace/configuration request for eslint.

@tomv564 tomv564 closed this as completed Aug 26, 2019
@tsujp
Copy link

tsujp commented Sep 18, 2019

Am I correct in deducing that this issue was/is about code-completion as well as just linting? For instance, I have LSP setup using "typescript-language-server" which gives me intellisense-esque features, but what about linting with some rules like barebones ESLint would do? I'd like to have both in LSP such that I get the code completion and the linting instead of having to wrangle plugins together, right now I can see "js-langserver" responding in the console but it's not linting according to my tsconfig.json and .eslintrc.js files.

@rchl
Copy link
Member

rchl commented Sep 18, 2019

@tsujp If you want eslint to lint your code, you need eslint language server. There is one at https://github.com/Microsoft/vscode-eslint but it doesn't work currently in LSP due to missing feature #699.

If you are really desperate to use it, you could use my hacked version that removes use of workspace/configuration message. For all intents and purposes it should work the same (it just doesn't support file-specific editor overrides but that's not really very useful feature IMO -- you can still have per-file overrides in your eslint config).

(EDIT: I see that js-langserver is also supposed to run eslint. I think I've tried it before but something did work as expected for me. Not sure what now.)

@tsujp
Copy link

tsujp commented Sep 18, 2019

I'll give those a shot later, also I've been doing some digging and I've found these:

typescript-language-server/typescript-language-server#58
typescript-language-server/typescript-language-server#73

So apparently we can use plugins in tsconfig.json using a known working server that LSP already has a configuration for, now I just need to discover what plugin I'd pass in tsconfig.json to get it to lint according to my configuration.

So, I'll be trying what I've just mentioned and your suggestions @rchl

EDIT I found a repo that works https://github.com/Quramy/typescript-eslint-language-service

Just add this into your tsconfig.json after installing and BOOM you have linting AND contextual awareness, YES. I am so happy right now.

"plugins": [
  {
    "name": "typescript-eslint-language-service"
  }
]

@predragnikolic
Copy link
Member

predragnikolic commented Oct 6, 2019

@tsujp hello can you please tell me how you got theia-ide/typescript-language-server work with https://github.com/Quramy/typescript-eslint-language-service?

Because I just don't seem to get it working... :D
Can you tell me exactly what you installed, and how your configuration looks?

@tsujp
Copy link

tsujp commented Oct 7, 2019

@predragnikolic

Sure thing mate, here are my configs, I've included literally everything I can think of for this. Let me know how you go.

Sublime Text packages:

Babel v8.6.3
LSP v0.9.0
TypeScript Syntax v0.0.29

Directory structure:

$ pwd
/path/to/some_node_project
$ tree -L 1
├── babel.config.js
├── node_modules
├── package-lock.json
├── package.json
├── index.ts
└── tsconfig.json

Global NPM install

$ npm list -g --depth=0
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

tsconfig.json

{
  "compilerOptions": {
    "rootDir": "./",
    "baseUrl": "./",
    "target": "es6",
    "module": "commonjs",
    "lib": [
      "es2018",
      "esnext.asynciterable",
      "esnext.array"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "plugins": [
      {
        "name": "typescript-eslint-language-service"
      }
    ]
  },
  "include": [
    "**/**/**.ts",
    "**/*.d.ts"
  ],
  "typeRoots": [
    "**/*.d.ts"
  ],
  "exclude": [
    "node_modules",
    "**/node_modules/**",
    "**/*.spec.ts",
    "dist"
  ]
}

.eslintrc.js

module.exports = {
  env: {
    browser: false,                                               // make true if react
    node: true
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.ts', '.js']                                // add '.tsx' if react
      }
    }
  },
  parser: '@typescript-eslint/parser',                            // you could use... 'babel-eslint'... but nah
  parserOptions: {
    ecmaVersion: 2018,                                            // modern features
    sourceType: 'module',                                         // allow use of node modules `import` and `export`
    project: './tsconfig.json',                                   // typescript rule settings
    tsconfigRootDir: __dirname,
    createDefaultProgram: true
  },
  extends: [
    'plugin:@typescript-eslint/recommended',                      // ootb eslint recommends
    'standard'                                                    // ootb standardjs
    // 'standard-jsx'                                                // ootb standardjs-jsx
  ],
  plugins: [
    '@typescript-eslint'                                          // allows override via rules below
    // 'react-hooks'
  ],
  rules: {
    // 'react-hooks/rules-of-hooks': 'error',
    // 'react-hooks/exhaustive-deps': 'warn',
    '@typescript-eslint/no-use-before-define': ['error', {        // hoist functions (not variables)
      "functions": false
    }],
    '@typescript-eslint/no-explicit-any': 'off',                  // sometimes we need to jerry-rig
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/interface-name-prefix': 'off',            // use our own prefix
    '@typescript-eslint/member-delimiter-style': ['error', {      // no delimiters for interfaces
      multiline: {
        'delimiter': 'none',
        'requireLast': false
      },
      singleline: {
        'delimiter': 'comma',
        'requireLast': false
      }
    }],
    '@typescript-eslint/indent': 'off',                           // standardjs is doing this instead
    'camelcase': 'off',                                           // & 3 below, graphql calls to postgres require snake_case
    '@typescript-eslint/camelcase': ['error', {                   // as it's postgres' convention.
      'ignoreDestructuring': true
    }],
    'no-unused-vars': 'off',
    'node/no-unsupported-features/es-syntax': 'off'               // allows use of `import` and `export`
  }
}

LSP settings, user

{
  "auto_show_diagnostics_panel_level": 3,
  "clients":
  {
    "bashls":
    {
      "enabled": false
    },
    "js-ls": {
      "enabled": true,
      "command": [
        "typescript-language-server",
        "--stdio"
      ],
      "languageId": "javascript",
      "scopes": [
        "source.js"
      ],
      "syntaxes": [
        "Packages/Babel/JavaScript (Babel).sublime-syntax",
      ]
    },
    "ts-ls":
    {
      "enabled": true,
      "command": [
        "typescript-language-server",
        "--stdio"
      ],
      "languageId": [
        "typescript",
        "typescriptreact"
      ],
      "scopes": [
        "source.ts",
        "source.tsx"
      ],
      "syntaxes": [
        "Packages/TypeScript Syntax/TypeScript.tmLanguage",
        "Packages/TypeScript Syntax/TypeScriptReact.tmLanguage"
      ]
    },
    "vscode-css":
    {
      "enabled": true
    }
  },
  "completion_hint_type": "kind",
  "log_debug": true,
  "log_server": true,
  "log_payloads": false,
  "only_show_lsp_completions": true,
  "show_diagnostics_count_in_view_status": true,
  "show_diagnostics_phantoms": false,
  "show_references_in_quick_panel": true,
  "show_view_status": true
}

babel.config.js

module.exports = (api) => {
  api.cache(false)

  const presets = ['@babel/preset-env']
  const plugins = [
    ["@babel/plugin-transform-runtime",
      {
        "regenerator": true
      }
    ]
  ]

  return {
    presets,
    plugins
  }
}

Package.json

{
  "name": "thing",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/runtime": "^7.6.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.5.0",
    "@babel/core": "^7.5.0",
    "@babel/node": "^7.6.1",
    "@babel/plugin-transform-runtime": "^7.6.0",
    "@babel/preset-env": "^7.5.0",
    "@types/node": "^12.7.2",
    "@typescript-eslint/eslint-plugin": "^2.0.0",
    "@typescript-eslint/parser": "2.0.0",
    "eslint": "^6.4.0",
    "eslint-config-standard": "^13.0.1",
    "eslint-plugin-import": "^2.18.2",
    "eslint-plugin-node": "^9.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "ts-node": "^8.4.1",
    "typescript": "^3.5.3",
    "typescript-eslint-language-service": "^1.4.0"
  }
}

@predragnikolic
Copy link
Member

A big thank you!
You don't know how many times I tried to set eslint as a plugin and failed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants