VIM version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Jun 15 2019 16:41:15)
Parches incluidos: 1-875, 878, 884, 948, 1046, 1365-1368, 1382, 1401
Operating System: Debian Buster 10.2
Hi, for some time I've been using yarn v2 or yarn with pnp (depending the ptoject), eslint is installed as a devDependency, so to use eslint I must execute yarn run eslint, to solve this with ALE I've set this variables:
let g:ale_javascript_eslint_executable = 'yarn'
let g:ale_javascript_eslint_options = 'run eslint'
No problem for a long time, few days ago I updated ALE, through vim-plug and the linter stop working, after doing some search in the source core and :AleInfo, I realized now Ale search for the node_modules path to execute eslint, but for me it doesn't work because I don't have node_modules directory.
I don't know if there is a way con configure ale to work with yarn pnp but if one sets a executable for eslint, ALE shouldn't search for node_modules, neither change the path before eslint execution.
For now I just commented the l:cd_command in the return from function! ale#handlers#eslint#GetCommand(buffer) abort
The root directory is ~jcmunoz/DropBox/Develop/node.js/tests
mkdir ale_test
cd ale_test
yarn init -y
yarn --pnp
yarn -D add eslint eslint-plugin-prettier prettier
add package.json config for eslint:
"eslintConfig": {
"root": true,
"env": {
"node": true,
"es2017": true,
"commonjs": true
},
"plugins": [
"prettier"
],
"extends": [
"eslint:recommended"
],
"rules": {
"no-console": 0,
"max-len": [
"error",
{
"code": 120,
"ignoreComments": true
}
],
"prettier/prettier": [
"warn",
{
"printWidth": 120,
"tabWidth": 2,
"bracketSpacing": false
}
]
},
"parserOptions": {
"ecmaVersion": 2018,
"ecmaFeatures": {
"jsx": true,
"es6": true
},
"sourceType": "script"
}
}
edit a new file test.js
vim test.js
add simple code:
"use strict";
let test = 1;
Current Filetype: javascript
Available Linters: ['eslint', 'fecs', 'flow', 'flow-language-server', 'jscs', 'jshint', 'standard', 'tsserver', 'xo']
Enabled Linters: ['eslint', 'fecs', 'flow', 'flow-language-server', 'jscs', 'jshint', 'standard', 'tsserver', 'xo']
Suggested Fixers:
'eslint' - Apply eslint --fix to a file.
'fecs' - Apply fecs format to a file.
'importjs' - automatic imports for javascript
'prettier' - Apply prettier to a file.
'prettier_eslint', 'prettier-eslint' - Apply prettier-eslint to a file.
'prettier_standard', 'prettier-standard' - Apply prettier-standard to a file.
'remove_trailing_lines' - Remove all blank lines at the end of a file.
'standard' - Fix JavaScript files using standard --fix
'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
'xo' - Fix JavaScript/TypeScript files using xo --fix.
Linter Variables:
let g:ale_javascript_eslint_executable = 'yarn'
let g:ale_javascript_eslint_options = 'run eslint'
let g:ale_javascript_eslint_suppress_eslintignore = 0
let g:ale_javascript_eslint_suppress_missing_config = 0
let g:ale_javascript_eslint_use_global = 0
let g:ale_javascript_fecs_executable = 'fecs'
let g:ale_javascript_fecs_use_global = 0
let g:ale_javascript_flow_executable = 'flow'
let g:ale_javascript_flow_ls_executable = 'flow'
let g:ale_javascript_flow_ls_use_global = 0
let g:ale_javascript_flow_use_global = 0
let g:ale_javascript_flow_use_home_config = 0
let g:ale_javascript_flow_use_respect_pragma = 1
let g:ale_javascript_jscs_executable = 'jscs'
let g:ale_javascript_jscs_use_global = 0
let g:ale_javascript_jshint_executable = 'jshint'
let g:ale_javascript_jshint_use_global = 0
let g:ale_javascript_prettier_options = '--tab-width=2'
let g:ale_javascript_prettier_use_local_config = 1
let g:ale_javascript_standard_executable = 'standard'
let g:ale_javascript_standard_options = ''
let g:ale_javascript_standard_use_global = 0
let g:ale_javascript_tsserver_config_path = ''
let g:ale_javascript_tsserver_executable = 'tsserver'
let g:ale_javascript_tsserver_use_global = 0
let g:ale_javascript_xo_executable = 'xo'
let g:ale_javascript_xo_options = ''
let g:ale_javascript_xo_use_global = 0
Global Variables:
let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {'json5': ['prettier'], 'vue': ['eslint'], 'json': ['prettier'], 'html': ['prettier'], 'javascript': ['eslint']}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 1
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_info = '--'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
let g:ale_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
Command History:
(executable check - success) yarn
(finished - exit code 1) ['/bin/bash', '-c', 'cd ''/home/jcmunoz/Dropbox/Develop/node.js'' && ''yarn'' run eslint -f json --stdin --stdin-filename ''/home/jcmunoz/Dropbox/Develop/node.js/tests/ale_test/test.js'' < ''/tmp/vShsxKu/4/test.js''']
<<
(executable check - failure) fecs
(executable check - failure) jscs
(executable check - failure) jshint
(executable check - failure) standard
(executable check - failure) tsserver
(executable check - failure) xo
A note on timeliness here: this is probably not affecting many users at the moment, but will be a much larger issue when the next version of yarn drops. That's currently scheduled for February 1st, and I'd expect an influx of this bug to be reported as soon as devs start updating yarn after that date.
As far as I can tell, there's a few things that can help:
yarn bin lists all the bin commands from packages. It is slow, but according to @arcanis it's the only reliable way to know which bin command is available..vscode/pnpify directory (https://github.com/yarnpkg/berry/pull/783) when running yarn pnpify --sdk See docyarn unplug pkg-name it is possible to uncompress a module in .yarn/unplugged/pkg-name.node_modules directory is constantly cleared#!/usr/bin/env bash
# naming this file `tsserver` for instance will run `tsserver` binary
COMMAND="${BASH_SOURCE[0]##*/}"
yarn run "$COMMAND" "$@"
There's still something I miss on the ALE side, as I'm forcing the b:javascript_prettier_executable (and others) but ALE still fails to check for executables.
I managed to fix this by also setting use_global:
g:ale_javascript_eslint_use_global = 1
g:ale_javascript_eslint_executable = 'yarn'
g:ale_javascript_eslint_options = 'run eslint'
This overrides ALE's node_modules path searching logic and simply use the executable setting. See https://github.com/dense-analysis/ale/blob/v2.6.0/autoload/ale/node.vim#L11
EDIT: This assumes all your JavaScript projects use a local per-project installation of yarn as detailed in https://yarnpkg.com/getting-started/install
Thanks... it's a workaround...
Regards.
I was able to work around this even easier (although somewhat less ideal) by just creating an empty node_modules/ This just prevents ale from cding out of my project directory and works great because yarn run eslint works as expected.
Maybe ALE could just check for .pnp.js or something?
@chumager Could we please reopen this? Here's a PR that finds .pnp.js if it can't find node_modules. https://github.com/dense-analysis/ale/pull/3024
The stale bot closed that pull request, and it didn't have any tests associated with it. If anyone can submit a pull request with tests, I'll have a look at it.
fwiw, this affects all Node.js utilities, not just eslint.
Something very similar happens when using pnpm. pnpm creates a hidden directory in node_modules and links things up to node_modules
config/release-config-logdna/node_modules/
โโโ @eslint
โย ย โโโ eslintrc -> ../.pnpm/@eslint/[email protected]/node_modules/@eslint/eslintrc
โโโ eslint -> .pnpm/[email protected]/node_modules/eslint
โโโ eslint-config-logdna -> .pnpm/[email protected][email protected]/node_modules/eslint-config-logdna
โโโ eslint-plugin-es -> .pnpm/[email protected][email protected]/node_modules/eslint-plugin-es
โโโ eslint-plugin-logdna -> .pnpm/[email protected]/node_modules/eslint-plugin-logdna
โโโ eslint-plugin-node -> .pnpm/[email protected][email protected]/node_modules/eslint-plugin-node
โโโ eslint-plugin-sensible -> .pnpm/[email protected]/node_modules/eslint-plugin-sensible
โโโ eslint-scope -> .pnpm/[email protected]/node_modules/eslint-scope
โโโ eslint-utils -> .pnpm/[email protected]/node_modules/eslint-utils
โโโ eslint-visitor-keys -> .pnpm/[email protected]/node_modules/eslint-visitor-keys
โโโ tap -> .pnpm/[email protected]/node_modules/tap
Seems like ale is following the link and this is setting the root context that is passed to plugins as the resolved path
Command History:
(executable check - success) /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/bin/eslint.js
(finished - exit code 2) ['/bin/bash', '-c', 'cd ''/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]'' && ''/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filen
ame ''/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/index.js'' < ''/tmp/nvimCg4oSz/3/index.js''']
<<<OUTPUT STARTS>>>
Oops! Something went wrong! :(
ESLint: 7.16.0
Error: Error while loading rule 'sensible/check-require': Cannot find module '/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/package.json'
Require stack:
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint-plugin-sensible/lib/rules/check-require.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/requireindex/index.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint-plugin-sensible/lib/index.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/@eslint/[email protected]/node_modules/@eslint/eslintrc/lib/config-array-factory.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/@eslint/[email protected]/node_modules/@eslint/eslintrc/lib/index.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/cli-engine/cli-engine.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/eslint/eslint.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/eslint/index.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/cli.js
- /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/bin/eslint.js
Occurred while linting /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/index.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)
at Function.Module._load (internal/modules/cjs/loader.js:841:27)
at Module.require (internal/modules/cjs/loader.js:1025:19)
at require (/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
at Object.create (/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint-plugin-sensible/lib/rules/check-require.js:59:23)
at createRuleListeners (/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:761:21)
at /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:931:31
at Array.forEach (<anonymous>)
at runRules (/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:876:34)
at Linter._verifyWithoutProcessors (/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:1173:31)
<<<OUTPUT ENDS>>>
'/bin/bash', '-c', 'cd ''/home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/.pnpm/[email protected]''
Rather than cd to /home/esatterwhite/dev/js/logdna/tooling-semantic-release/config/release-config-logdna/node_modules/eslint
It may be a weird behavior in some of the plugins trying to resolve package.json as well, but it works as expected outside of ALE by just running npm run eslint