no-unused-expressions error in package.json - eslint

I am adding a linter to my big existing project. I have enabled "error" for no-unused-expressions. I am using lint-staged to run the linter upon git committing.
my .lintstagedrc.js:
module.exports = {
'*': ['eslint --ext .js,.jsx,.ts,.tsx,.graphql --fix .', 'npx prettier --ignore-path .eslintignore --write'],
}
When trying to git commit (staging includes changes to package.json)
I get:
/Users/myuser/myproject/package.json
1:1 error Expected an assignment or function call and instead saw an expression no-unused-expressions
And my normal-looking package.json:
{
"name": "myproject",
"private": true,
"description": "myproject description",
...
Since json is such a tightly defined format, I have a high degree of confidence it is formatted properly. This leads me to believe it is an eslint setting of some sort. I can't even really be sure why this no-unused-expressions rule would be looking at a json file.
Not sure where to begin diagnosing this one.

The '*' in your .lintstagedrc.js means all files will be checked by eslint, regardless of extension. What you probably want to do is this:
module.exports = {
'*.{js, jsx, ts, tsx, graphql}': ['eslint --fix', 'prettier --ignore-path .eslintignore --write'],
}
By calling eslint on package.json you interpret it as a JavaScript/TypeScript file (based on your configuration). Any JSON file is also a valid JavaScript file that contains a single value that is not assigned to anything, which is called an unused expression and should not normally occur in your code.

Related

Can't enable no-console using eslint cli

I'm using eslint, and in my configuration file I have "no-console": "off".
I want to turn it on for my CI system, so I've been using the command line (vue cli syntax):
vue-cli-service lint --rule '"no-console": "error"'
This doesn't work.
However, if I invert things (set error in the configuration, and pass off as a flag) it does work.
Anyone know why?
EDIT: it should probably look like vue-cli-service --rule 'no-console: 2'
PS: "error" may be working too I guess.
You can make a config in a lot of places but the usual one is probably .eslintrc.js in which you can write
module.exports = {
[...]
// add your custom rules here
rules: {
"no-console": "off",
},
}
As shown here: https://eslint.org/docs/rules/no-console
This one should work but it always depend on how your project is setup too.

ESLint Vue plugin showing false positives for vue/comment-directive

After migrating from VueCLI to Vite, I have to do the linting "manually" as far as I understand; correct me if I'm wrong.
As I only want to lint my .ts and .html files (I separate them even for components), I have this script in my package json:
"lint": "eslint --ext .ts --ext .html src/"
It found some issues like missing :key in loops, but it also shows me this error for each template:
error clear vue/comment-directive
And this is always the closing tag of any root elements within my template.html
If there is only one root element I get one warning for the file, if there are multiple root elements I get a warning for each closing tag.
I don't understand what this rule complains as, according its documentation, it is there for the eslint-disable comments, which I don't have in my templates.
I had the same issue but in nuxt with eslint, i just needed to update eslint-config and eslint-module:
"#nuxtjs/eslint-config": "^5.0.0",
"#nuxtjs/eslint-module": "^3.0.1",
source: https://github.com/nuxt/eslint-plugin-nuxt/issues/121
I've just updated my npm dependencies and I have the same error.
I was reading the eslint documentation and finally I've realized that you can remove the false error if you setup the rule in the .eslintrc.js config file.
this is my .eslintrc.js config file:
module.exports = {
root: true,
env: {
browser: true,
node: true
},
parserOptions: {
parser: 'babel-eslint'
},
extends: [
'#nuxtjs',
'prettier',
'prettier/vue',
'plugin:prettier/recommended',
'plugin:nuxt/recommended'
],
plugins: [
'prettier'
],
// add your custom rules here
rules: {
"vue/comment-directive": 0
}
}
add the rule "vue/comment-directive": 0 and that is!, the error message is removed!.
the possible values are:
0 means disabled
1 means warning
2 means error
Try to change it in your IDE to how it works
(In my case I've had to stop the server and re-run it every time that I've changed a value in this config file.)
I have the same error.
I was taught how to fix this error.
https://qiita.com/tashinoso/items/a72741ca8e2fd928ca77#comment-3e6cd674353056ecbb3a
module.exports = {
...
overrides: [
{
files: ["*.vue"],
processor: "vue/.vue"
}
]
}
Set this snippet on .eslintrc.js
"vue/comment-directive": ["error", {
"reportUnusedDisableDirectives": false
}]
Solve my issue, i wonder why. Solution from documentation
Node v12.20.0
This is a kind of a temporary fix that worked for me and I think it will work for you as well.
vue/comment-directive
This rule is included in all of "plugin:vue/base", "plugin:vue/essential", "plugin:vue/vue3-essential", "plugin:vue/strongly-recommended", "plugin:vue/vue3-strongly-recommended", "plugin:vue/recommended" and "plugin:vue/vue3-recommended".
ESLint doesn't provide any API to enhance eslint-disable functionality and ESLint rules cannot affect other rules. But ESLint provides processors API.
This rule sends all eslint-disable-like comments as errors to the post-process of the .vue file processor, then the post-process removes all vue/comment-directive errors and the reported errors in disabled areas.
All you need to do is add
eslint-disable-next-line vue/component-tags-order
this line as comment above anywhere you using comments within tags in each block you need to specify if comments are added.
For more information please visit:- https://eslint.vuejs.org/rules/comment-directive.html

Can't use JSX after npm run eject

I was following this tutorial and it's been a week I tried to resolve the issue:
SyntaxError: TestComponent.js: Unexpected token (5:6)
3 | render() {
4 | return (
> 5 | <div>
| ^
6 | { this.props.children }
7 | </div>
8 | )
Currently, we have #babel/preset-env, #babel/preset-react, #babel/cli in 2019 rather than the tutorial pointing to babel-preset-es2015 babel-preset-stage-0 babel-preset-react babel-cli.
So, using them in package.json doesn't solve the issue:
"babel": {
"presets": [
"#babel/env",
"#babel/react"
]
}
I have tried several ways but nothing stopping the error. I hope someone has resolved the issue and can provide a solution.
Greatly appreciated!
TLDR: Detailed step by step guide
A couple things have changed since the writing of the tutorial namely the following are the breaking changes, unless listed otherwise the other steps in the tutorial are the same:
You will need to download and use the babel-cli in order to get your custom "lib" script command to work:
npm install --save-dev #babel/cli
You will also need to download and use the #babel/plugin-transform-react-jsx plugin within your custom "lib" script command to compile and transform your React code since Babel 6 and up no longer have any native transforms for React. This is necessary for when you want to share your custom component with only native JavaScript on npmjs for others.
npm install --save-dev #babel/plugin-transform-react-jsx
Update your "lib" script command to use the babel's JSX transforming plugin listed in step 2:
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"lib": "babel --plugins #babel/transform-react-jsx src/node_modules --out-dir lib --copy-files",
"test": "node scripts/test.js"
},
Note: You also don't need the .babelrc file listed in the tutorial as we will edit the webpack.config.js file to properly transpile JSX later on.
Steps 1 - 3 will allow you to publish and share your component with others, but you will still have to make adjustments for your local development and I will describe those steps below:
For your custom component's package.json remove the .js extension for the "main" entry point as this will cause the following issue. For example, here is my custom component's package.json:
{
"private": true,
"name": "YourComponent",
"main": "./YourComponent"
}
Now if you try to compile and run your application locally, using your custom component, it will throw an error complaining about your custom component's JSX syntax:
SyntaxError: YourComponent.js: Unexpected token (6:6)
3 | render() {
4 | return (
> 5 | <div>
| ^
6 | { this.props.children }
7 | </div>
8 | )
This is because you need to edit your webpack.config.js file to use the #babel/preset-env and #babel/preset-react babel presets. So you want to add this line:
presets: ['#babel/preset-env', '#babel/preset-react'], to your babel loader for your application's code.
For reference, here is the relevant section of my code (starts on line 329):
...
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
presets: ['#babel/preset-env', '#babel/preset-react'],
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '#svgr/webpack?-svgo,+ref![path]',
},
},
},
],
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
cacheCompression: isEnvProduction,
compact: isEnvProduction,
},
},
...
Now if you run locally it should work: npm run start
Those were the major steps that helped fix my JSX complaint for running locally as well as sharing my custom component with others on npmjs. I created a public git repo with my code and a detailed step by step guide to help others, it can be found here.
Hopefully that helps!
Looking at the tutorial and noticing it's using both " and ” (different styles of quotations marks, I don't know the correct language to reference them both properly).
There is a very subtle difference in looks between the two but only one of them will be interpreted correctly, the other will cause an error. The .babelrc in the tutorial is using the wrong style of quotation marks.
If you copied and pasted from the article, check to ensure you are using the correct style of quotes which should be the one closest to the Enter key on your keyboard.

Is there a way to ignore test files for eslint-plugin-security?

With a node.js project, I've added eslint-plugin-security and it is giving a lot of warnings for code in my test/spec files (using mochajs). Since the test code won't be running in production, these don't seem as useful as they do in the project's actual code. (A lot of Generic Object Injection Sink warnings )
Is there a way to have the security plugin ignore certain files other than putting /* eslint-disable */ at the top of every spec file?
The best way I found to deal with this case is based on this answer.
You can override parts of your eslint file in a subfolder. In my case I'm disabling problematic rules from a jest plugin inside my e2e tests folder. Example .eslintrc.js in /e2e-tests/ :
module.exports = {
overrides: [
{
files: ["*.spec.js"],
rules: {
"jest/valid-expect": 0
}
}
]
};
There is three way to ignore files or folders:
1. Creating a .eslintignore on your project root folder with the thing you want to ignore:
**/*.js
2. Using eslint cli & the --ignore-path to specify another file where your ignore rules will be located
eslint --ignore-path .jshintignore file.js
3. Using your package.json
{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"env": {
"browser": true,
"node": true
}
},
"eslintIgnore": ["*.spec.ts", "world.js"]
}
Official Documentation
On my side, I had issue with Intellij IDEA where eslint was checking files in a folder only dedicated to Typescript (+tslint) which was a pain, so I've picked solution 3.

how to silence warnings about ignored files in eslint

After setting up eslint and adding some files in the ignore list, every time that eslint is run it produces warnings about files that are ignored:
/path/to/file/name.min.js
0:0 warning File ignored because of a matching ignore pattern. Use "--no-ignore" to override
How can this warning be silenced?
One workaround I know at the moment is --quiet option, which suppresses all warnings. Of course that doesn't make sense if you have "warn" rules in your config.
Another way not to show that warning is to use dir names: eslint src instead of globbing patterns: eslint src/*.
Check if you're running eslint with an unquoted glob argument.
If so, put the glob in quotes.
eslint src/** ❌ Bad (no quotes = OS will expand into many args)
eslint "src/**" ✔️ Good (quotes = a single string argument)
Why?
If you call eslint using a cli glob pattern not in quotes, e.g. eslint src/**, that glob gets expanded into all matching files and passed to eslint as a gigantic list of cli arguments. e.g. eslint path/to/file/name.min.js src/foo.js src/bar.js src/manymore.js .....
So when eslint ignores a file due to your ignore pattern, yet that file was explicitly passed as a command line argument, eslint is warning us
eslint speaking:
"Um, I ignored /path/to/file/name.min.js because of an ignore pattern, but you explicitly passed it to me to lint, so this must not be what you wanted, right?"
But when you pass the glob in quotes, e.g. eslint "src/**", the glob is not expanded to many arguments; rather, it's just a single string argument, and eslint is the one who knows it's a glob but since it takes care of figuring out which files to match it can do so while respecting eslintignore. So there's nothing weird going on that eslint thinks it should warn you about.
You can't and they don't plan on fixing it since they don't consider it a bug. So if you pass in a file that's being ignored them it will tell you it didn't process linting rules because it's ignored: https://github.com/eslint/eslint/issues/5623
We run pre-commit hooks to lint code before committing, so ended up needing to write some additional code to differentiate between actual Warnings and File ignored warnings and only fail linting if an actual warning or error is thrown.
The solution for Lint Staged & Husky errors
// lint-staged.config.js
const { ESLint } = require("eslint");
const removeIgnoredFiles = async (files) => {
const eslint = new ESLint();
const ignoredFiles = await Promise.all(files.map((file) => eslint.isPathIgnored(file)));
const filteredFiles = files.filter((_, i) => !ignoredFiles[i]);
return filteredFiles.join(" ");
};
module.exports = {
"*.{js,ts}": async (files) => {
const filesToLint = await removeIgnoredFiles(files);
return [`eslint --max-warnings=0 ${filesToLint}`];
},
};
If the file is ignored by ESLint (i.e. in .eslintignore), this snippet filters the file and does not pass it through the ESLint CLI.
ref: Testing Library - Aug 2022
I found the REAL answer here:
https://github.com/eslint/eslint/issues/5623
The problem in my case was in the way I called eslint. I used eslint src/* but it should be eslint src/. (Or in your case it might be eslint . instead of eslint *)
The reason why you get the warning is that by using the star, you are telling the eslint that you want to lint EVERY single file which does not make sense if you ignore some files. So by omiting the star you are making the eslint to decide what to lint and it will skip the ignored files without any warning.
Eslint throws this warning on telling it to lint a file, at the same time as having the file ignored. src/* is actually passing every file single file uniquely, while only passing src would let eslint ignore the files without warnings
If you are using lint-staged, it will pass every single staged file that matches the lint-staged regex. If matching, and you put it inside ignore, eslint gets confused and outputs a warning
"lint-staged": {
"*.{ts,tsx,js}": [ // <-- this regex needs to be changed to not match your files
"eslint --fix --max-warnings 0 --ignore-path '.eslintignore' --plugin tsc --rule 'tsc/config: [2, {configFile: \"./tsconfig.json\"}]'",
"prettier --ignore-path .eslintignore --write"
],
"*.js": "eslint --cache --fix",
"*.{js,css,md}": "prettier --write"
},
For me, I just wanted to exclude some js files, so I just removed the js matching inside "*.{ts,tsx,js}"
try with --ext. In my case, I replaced matching from:
eslint modules/**/*{js,vue}
to:
eslint --ext .js,.vue .
Warnings with File ignored because... are gone, but others warnings remain.
My solution for Next.js next lint and a .lintstagedrc.js file. This removes the files that have that warning from the final string of files to lint.
// .lintstagedrc.js
const path = require("path");
const ignorePaths = ["types/global.d.ts", ".lintstagedrc.js"];
const buildEslintCommand = (filenames) => {
return `next lint --fix --max-warnings=0 --file ${filenames
.reduce((files, file) => {
const pathToFile = path.relative(process.cwd(), file);
if (!ignorePaths.includes(pathToFile)) files.push(pathToFile);
return files;
}, [])
.join(" --file ")}`;
};
module.exports = {
"*.{ts,tsx,js,jsx}": [buildEslintCommand],
"*.{ts,tsx,js,jsx,css,scss,md}": "prettier --write",
};

Resources