I'm trying to run a global installation of ESLint against a single file, using a specified path to the configuration file:
eslint FileToCheck.jsx --config "../path/to/config/.eslintrc.js"
but I'm getting the error
ESLint couldn't find the plugin "eslint-plugin-jsx-a11y". This can happen for a couple different reasons:
If ESLint is installed globally, then make sure eslint-plugin-jsx-a11y is also installed globally. A globally-installed ESLint cannot find a locally-installed plugin.
If ESLint is installed locally, then it's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
npm i eslint-plugin-jsx-a11y#latest --save-dev
So it seems like #1 is applicable and I need to install eslint-plugin-jsx-a11y globally. I try to do this with
yarn global add eslint-plugin-jsx-a11y
and rerun the original ESLint command, but it fails with the same error. I noticed during the yarn global add that some of the output said
"eslint-plugin-jsx-a11y#6.0.2" has no binaries
Indeed, when I check ~/AppData/Local/Yarn/bin I do not find any binaries for that plugin (though I do for ESLint).
How can I make ESLint run globally with this plugin? A good answer will not tell me just to install it locally, but will actually answer the question given - how this can be accomplished with globally installed ESLint and plugins.
Packages I have installed globally with yarn:
eslint
babel-core
babel-eslint
eslint-plugin-import
eslint-plugin-react
eslint-plugin-jsx-a11y
eslint-config-airbnb
Here is my .eslintrc.js, which may or may not be relevant:
module.exports = {
'extends': 'airbnb',
'plugins': [
'react',
'jsx-a11y',
'import'
],
'env': {
'browser': true
},
'parser': 'babel-eslint',
'rules': {
'prefer-template': 'error',
'comma-dangle': ['error', 'always-multiline'],
'import/no-extraneous-dependencies': 'off',
'react/prop-types': 'off',
'react/jsx-no-bind': 'off',
'jsx-a11y/no-static-element-interactions': 'off',
'jsx-a11y/no-noninteractive-element-interactions': 'off',
'jsx-a11y/alt-text': 'off',
'jsx-a11y/no-autofocus': 'off',
'eqeqeq': ['error', 'always', { 'null': 'ignore' }],
'no-use-before-define': ['error', { 'functions': false }],
'func-style': ['error', 'declaration', { 'allowArrowFunctions': true }],
'no-console': 'off',
'no-alert': 'off',
'no-continue': 'off',
'no-param-reassign': ['error', { 'props': false }],
'no-plusplus': ['error', { 'allowForLoopAfterthoughts': true }],
'one-var-declaration-per-line': ['error', 'initializations'],
'one-var': 'off', // Not needed because of one-var-declaration-per-line
'indent': ['error', 2, {
'FunctionDeclaration': { 'parameters': 'first' },
'SwitchCase': 1
}],
'no-restricted-syntax': [
'error',
{
selector: 'ForInStatement',
message: 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
},
{
selector: 'LabeledStatement',
message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
},
{
selector: 'WithStatement',
message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
},
],
}
};
if (process.env.FEATURE_FLAGS) {
const flags = Object.keys(JSON.parse(process.env.FEATURE_FLAGS));
module.exports.globals = flags.reduce(function (flagConfig, flag) {
flagConfig[flag] = false;
return flagConfig;
}, {});
}
This issue is caused by the changes to the way ESLint loads packages between versions 5 and 6. See here for details.
Plugins and shareable configs are no longer affected by ESLint’s location
Previously, ESLint loaded plugins relative to the location of the ESLint package itself. As a result, we suggested that users with global ESLint installations should also install plugins globally, and users with local ESLint installations should install plugins locally. However, due to a design bug, this strategy caused ESLint to randomly fail to load plugins and shareable configs under certain circumstances, particularly when using package management tools like lerna and Yarn Plug n’ Play.
As a rule of thumb: With ESLint v6, plugins should always be installed locally, even if ESLint was installed globally. More precisely, ESLint v6 resolves plugins relative to the end user’s project by default, and always resolves shareable configs and parsers relative to the location of the config file that imports them.
To address: If you use a global installation of ESLint (e.g. installed with npm install eslint --global) along with plugins, you should install those plugins locally in the projects where you run ESLint. If your config file extends shareable configs and/or parsers, you should ensure that those packages are installed as dependencies of the project containing the config file.
If you use a config file located outside of a local project (with the --config flag), consider installing the plugins as dependencies of that config file, and setting the --resolve-plugins-relative-to flag to the location of the config file.
There's a fair bit of discussion around this, but the current state of affairs (late 2019) seems to be that there are no good solutions at this point other that rolling back to eslint#5.x :( Watch this issue for more details.
Related
I'm building a react app with parcel. I have an eslint config set up that I like, and use VSCode tools to catch eslint errors and fix them as I code. The app builds correctly as of now. So all that is fine.
However, as an added precaution, I would like to set up parcel to run eslint, using my config, and to halt the build process and output an error when I havent followed the eslint rules, either when running dev server or building for production.
I'm aware of this npm package from googling, but the package doesnt have a readme, and i can't find setup instructions in the parcel docs: https://www.npmjs.com/package/#parcel/validator-eslint
For reference I am using parcel 1.12.3 but would be open to changing to parcel 2.x.x if that is neccesary.
Thanks!
In parcel v2, you can use the #parcel/validator-eslint plugin to accomplish this. Here's how:
Install eslint and #parcel/validator-eslint in your project. Note that this plugin will currently only work with eslint v7 or earlier due to this bug (which hopefully we can fix soon ;-))
yarn add -D eslint#7 #parcel/validator-eslint
Add an .eslintrc.json file to your project with your configuration. It's best to use a static config file (like .json or .yaml) rather than a dynamic one (like .js) if you can, because that helps parcel's caching be more efficient and faster (see docs). Here's a basic file example that works, but you can extend this to suit your needs by checking out the eslint docs:
{
"env": {
"browser": true
},
"extends": [
"eslint:recommended"
],
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
}
}
Tell configure parcel to use the plugin for javascript files by adding a .parcelrc file at the root of your project (or modify your existing .parcelrc file to include the "validators" entry below):
{
"extends": "#parcel/config-default",
"validators": {
"*.{js,mjs,jsm,jsx,es6,cjs,ts,tsx}": [
"#parcel/validator-eslint"
]
}
}
Now, if you have an eslint error, it should bubble up through parcel like this:
🚨 Build failed.
#parcel/validator-eslint: ESLint found 1 errors and 0 warnings.
C:\Users\ansteg\Projects\parcel-eslint-example\src\index.js:2:7
1 | // This unused variable should trigger an ESLint error.
> 2 | const unusedVar = "Hello!";
> | ^^^^^^^^^^ 'unusedVar' is assigned a value but never used.
3 |
See this github repo for a working example.
ESLint is throwing a Parsing error: Unexpected token = error when I try to lint my Es6 classes. What configuration parameter am I missing to enable fat arrow class methods in eslint?
Sample class:
class App extends React.Component{
...
handleClick = (evt) => {
...
}
}
.eslint
{
"ecmaFeatures": {
"jsx": true,
"modules":true,
"arrowFunctions":true,
"classes":true,
"spread":true,
},
"env": {
"browser": true,
"node": true,
"es6": true
},
"rules": {
"strict": 0,
"no-underscore-dangle": 0,
"quotes": [
2,
"single"
],
}
}
If you want to use experimental features (such as arrows as class methods) you need to use babel-eslint as a parser. Default parser (Espree) doesn't support experimental features.
First install babel-eslint:
npm i -D babel-eslint
Then add the following to your .eslintrc.json file:
"parser": "babel-eslint"
First install these plugins:
npm i -D babel-eslint eslint-plugin-babel
Then add these settings to your ESLint config file:
{
"plugins": [ "babel" ],
"parser": "babel-eslint",
"rules": {
"no-invalid-this": 0,
"babel/no-invalid-this": 1,
}
}
This way you can use fat arrow class methods plus you will not get any no-invalid-this errors from ESLint.
From what I read in the error message Parsing error: Unexpected token = it looks like more a parser error than linter one.
Assuming you are using Babel as your JavaScript compiler/transpiler and babel-eslint as your ESLint parser, chances are that it is Babel complaining about the syntax, not ESLint.
The issue is not about the arrow functions but something more experimental (ES7??) that I think it is called property initializer or class instance field (or both :) ).
If you want to use this new syntax/feature you need to enable preset-stage-1 in Babel. This preset includes the syntax-class-properties plugin that allows that syntax.
Summing up:
Install babel preset:
npm install babel-preset-stage-1
Add this preset to the list of your presets (I suppose you are already using es2015 and react presets), either in your .babelrc or in your babel-loader query field if you are using webpack.
"presets": ["es2015", "stage-1", "react"]
I came across the same problem today
and #dreyescat 's answer works for me.
By default, babel uses 3 presets: es2015, react, stage-2
Screenshot with "Parsing error: Unexpected token ="
Then if you also select the stage-1preset, the error is gone
Screenshot with no error
You can test it on the bebeljs.io site yourself
2021 Update: Be sure you're using #babel/eslint-parser and not the deprecated babel-eslint
Remove the old package if necessary: yarn remove babel-eslint or npm uninstall babel-eslint
yarn add --dev #babel/eslint-parser or npm install --save-dev #babel/eslint-parser
In .eslintrc add "parser": "#babel/eslint-parser"
Optionally, this answer suggests including "requireConfigFile": false in .eslintrc to prevent eslint from searching for unnecessary config files:
{
...
"parserOptions": {
...
"requireConfigFile": false,
}
}
If this still doesn't work, try checking whether your system is using a globally installed eslint (and removing it).
My other problem was eslint was using a globally installed version instead of my local version, and the global eslint can't access my locally installed babel-eslint parser. Further, since my globally installed eslint was installed on a different version of node, removing it was non-trivial.
Checking if your system is using global versus local eslint.
Install babel-eslint following #spencer.sm's answer for your local eslint.
From the terminal, check if you get different output from running eslint . and npx eslint .. If you get different output it's likely that it's your global eslint running that can't access babel-eslint.
Uninstalling the global eslint
For most people, the following commands should uninstall eslint with npm (uninstall global package with npm) and yarn (uninstall global package with yarn):
# npm
npm uninstall -g eslint
npm uninstall eslint
# yarn
yarn global remove eslint
Next, run npx eslint . to see if things work. If it doesn't, which it didn't for me, you need to take an extra step to remove the globally installed eslint.
From this answer, I learned that I had installed eslint on a system version of Node instead of my current version of Node (I use nvm). Follow these simple steps to remove the global eslint and you should be good to go!
Your sample isn't valid ES6, so there's no way to configure eslint to allow it
I can't seem to get my eslint to work.
I have the eslint extenstion on vscode. I created a new node project and npm installed eslint as a dev dependency. I chose the Air-BNB style and then went to check if it worked. Whenever I open a file I get a notification saying there is an error with eslint.
Vscode notification error message
ESlint stack trace error output
Some things I did:
I installed eslint locally.
At one point I found out that I had eslint installed globally so I
removed it and stuck with the local install per project basis.
Ive disabled and enabled vscode eslint (Extension ESlint 2.1.8).
My Config File:
module.exports = {
env: {
browser: true,
commonjs: true,
es2020: true,
},
extends: [
'airbnb-base',
],
parserOptions: {
ecmaVersion: 11,
},
rules: {
},
};
Here are my dev dependencies:
"devDependencies": {
"eslint": "^7.7.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-require": "0.0.1"
}
The problem is right their in the error message, you have two different versions of eslint-plugin-import in your node-modules tree. You just need to make sure you only have one version.
I expect you tried to add a newer version than the one used by CRA.
With a VueJS project created by Vue CLI 4, you get Babel configured with this handy preset in babel.config.js:
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset',
],
};
I'm trying to use babel-plugin-transform-remove-console to remove console.* from the built JS files.
Installed the plugin as a dev dependency by: npm i -D babel-plugin-transform-remove-console
Then modified babel.config.js:
module.exports = (api) => {
var env = api.cache(() => process.env.NODE_ENV);
var plugins = [];
// Change to 'production' when configs are working
if (env === 'development') {
plugins.push(['transform-remove-console', { exclude: ['error', 'warn'] }]);
}
return {
presets: ['#vue/cli-plugin-babel/preset'],
// plugins,
// Doesn't work even when always on?
plugins: ['transform-remove-console'],
};
};
This should work by running npm run serve -- --reset-cache, and I've also tried building the app many times with different environments, but the console loggings are still showing up in the browser's console?
Is Vue CLI's preset somehow mixing it up for not being able to set plugins via this configuration file?
UPDATE: Created a bug report to Vue CLI repo, and while creating a minimal bug reproduction repository, I found out this plugin is working with a new project.
However, I have no idea what is causing this as I've synced this application with the newest CLI bootstrapped template, and also tried nuking NPM cache by `npm cache clean --force.
I ran into the same problem. This did not work:
plugins: ['transform-remove-console']
But this worked:
plugins: [['transform-remove-console', { exclude: ['error', 'warn'] }]]
Hope this helps others who encounter the same issue.
It seems #Zydnar's suggestion of nuking node_modules folder may have helped, however, I also found out that my recent NPM packages upgrades had been interrupted and had not been fully successful. There was some Vue CLI plugins that had different versions.
After nuking node_modules and upgrading all the packages this Babel plugin started working!
Either I don't understand dependencies vs. devDependencies in node 100% yet or eslint is just wrong here (not capable of analyzing this correctly):
3:1 error 'chai' should be listed in the project's dependencies, not devDependencies import/no-extraneous-dependencies
4:1 error 'chai-enzyme' should be listed in the project's dependencies, not devDependencies import/no-extraneous-dependencies
5:1 error 'enzyme' should be listed in the project's dependencies, not devDependencies import/no-extraneous-dependencies
7:1 error 'sinon' should be listed in the project's dependencies, not devDependencies import/no-extraneous-dependencies
9:1 error 'redux-mock-store' should be listed in the project's dependencies, not devDependencies import/no-extraneous-dependencies
These are test dependencies, so why is it saying that they should be listed in dependencies?
Additional note: We're using Travis as our CI so I don't know if it makes a difference for that at all either.
Solved it with adding this to my .eslintrc:
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}]
[no-extraneous-dependencies] Add exceptions? #422
Based on this user's reply:
you could set the option devDependencies: true in an .eslintrc in your
test folder:
rules: import/no-extraneous-dependencies: [error, { devDependencies:
true }] Then you'll get reports of any packages referenced that are
not included dependencies or devDependencies. Then you get the
goodness of the rule, with no noise from the disable comments.
I think that might work for you? This is how I would use the rule, in
your case, since you have your test code separated into a test
directory.
Also this post was helpful to confirm I wasn't insane to not want some of these in my dependencies list: Sharable ESLint Config
If you want to allow imports of devDependencies in test files only you can use an array of globs, as the documentation of no-extraneous-dependencies states:
When using an array of globs, the setting will be set to true (no errors reported) if the name of the file being linted matches a single glob in the array, and false otherwise.
The following setting will disable the lint for test files only.
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/*.test.ts", "**/*.test.tsx"]}]
That way imports from devDependencies are still reported as errors.
I was able to solve it by adding the missing packages (in my case, Typescript and Storybook) to my plugins directory in .eslintrc.
I give the specifics in this post: ESLint error: '#storybook/react' should be listed in the project's dependencies, not devDependencies
I fixed it by using
'import/no-extraneous-dependencies': [
'error',
{
projectDependencies: false,
},
],