Prettier, React Router 6, useParams hook, unexpected token - reactjs

I've been smashing my face into this problem the entire morning.
I recently assembled a new project with React 18, React Router 6, TypeScript, Webpack 5, eslint, and prettier.
Things were going fine until I tried out the useParams hook, and now my linter keeps printing out the following error:
/.../index.tsx
9:41 error Parsing error: Unexpected token prettier/prettier
✖ 1 problem (1 error, 0 warnings)
I have been searching around on Google, but I have not found anything talking about this issue directly. I'm not sure what to do at this point other than remove prettier from the project.
Here's my eslintrc:
{
"root": true,
"parser": "#typescript-eslint/parser",
"plugins": [
"react",
"#typescript-eslint",
"prettier"
],
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:#typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"settings": {
"import/resolver": {
"alias": [
["components", "./src/components"],
["routes", "./src/routes"],
["views", "./src/views"]
]
},
"react": {
"version": "detect"
}
},
"env": {
"browser": true,
"es2021": true,
"node": true
}
}
Prettier config:
{
"arrowParens": "avoid",
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"bracketSameLine": false,
"jsxSingleQuote": true,
"parser": "babel",
"printWidth": 80,
"proseWrap": "preserve",
"requirePragma": false,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"endOfLine": "auto",
"useTabs": false
}
and the offending page:
import React from 'react';
import { useParams } from 'react-router-dom';
type ParamTypes = {
id: string
};
const Customer: React.FC = () => {
const { id } = useParams<ParamTypes>();
return <div>{id}</div>;
};
export default Customer;
According to Prettier, the offending character is the final parenthesis:
const { id } = useParams<ParamTypes>();
^

I figured it out.
The issue was in my prettier config: "parser": "babel". According to the docs, this does not need to be set, since Prettier can infer which parser it needs to use based on the file.
Removing this setting has briefly restored my sanity. Hooray.
Mystery solved.

Related

ESLINT Unexpected top-level property "import/order" error

I'm trying to create a rule to have a one empty line between internal and external imports.
.eslintrc.json:
{
"parser": "#typescript-eslint/parser",
"env": {
"es6": true,
"node": true,
"jest/globals": true,
"browser": true
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2019,
"project": "tsconfig.json",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"import/order": [
"error",
{
"groups": [["builtin", "external"]],
"newlines-between": "always"
}
]
}
}
I have the following error:
Compiled with problems:X
ERROR
ESLint configuration in .eslintrc.json is invalid:
- Unexpected top-level property "import/order".
I modified an existing project with a similar eslint config to use your rule. It is working nicely. I have a suspicion your issue is that you don't have an extends property that includes the import rules. Here's my eslint config:
module.exports = {
root: true,
env: {
node: true,
},
parser: '#typescript-eslint/parser',
plugins: ['#typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:#typescript-eslint/eslint-recommended',
'plugin:#typescript-eslint/recommended',
'plugin:import/warnings', // <--- note this inclusion here
],
rules: {
'import/order': [
'error',
{
groups: [['builtin', 'external']],
'newlines-between': 'always',
},
],
},
};
When I run the linter, I get the expected error you want:
13:1 error There should be at least one empty line between import groups import/order
I would try playing with your extends property. I have some stuff in there you may not need at all, and I dont have the jsx stuff for this particular project, but hopefully this will get you started.
Install this dependency: eslint-import-resolver-typescript
# npm
npm i -D eslint-plugin-import #typescript-eslint/parser eslint-import-resolver-typescript
# yarn
yarn add -D eslint-plugin-import #typescript-eslint/parser eslint-import-resolver-typescript
And add import to your plugins :
"plugins": ["import"],
eslint-import-resolver-typescript

prevent asking "Missing JSDoc comment" for standard react methods in typescript project

we have React project with Typescript.
We use TSDoc to standardize the doc comments used in TypeScript code
Our eslint.trc file as follow:
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"plugin:react/recommended",
"google",
"plugin:#typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"parser": "#typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react",
"#typescript-eslint/eslint-plugin",
"eslint-plugin-tsdoc"
],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"tsdoc/syntax": "warn",
"valid-jsdoc" : 0,
"#typescript-eslint/explicit-module-boundary-types": "off"
}
}
How to configure this configuration file, for not asking ESLINT about documenting standard react methods, like constructor(),static getDerivedStateFromProps(),render(),componentDidMount() and etc.
We can switch "require-jsdoc":"off", but it also will not ask out user defined methods in class.
I've resolved this problem with this plugin
https://www.npmjs.com/package/eslint-plugin-require-jsdoc-except?activeTab=readme
You can add your function names at ignore:
"ignore":[
"constructor", "render","componentDidUpdate","getDerivedStateFromProps","componentDidMount"
]
Add this to your .eslintrc.js rules:
rules: {
'require-jsdoc': [
'error',
{
require: {
FunctionDeclaration: false,
MethodDefinition: false,
ClassDeclaration: false,
ArrowFunctionExpression: false,
FunctionExpression: false,
},
},
],
},
Read more:
https://eslint.org/docs/latest/rules/require-jsdoc

.eslintrc.js for React 17 and JSX without import 'react'

in react 17 is not necessarily use
import React from 'react';
but if i don't have it, so eslint gave me error
'React' must be in scope when using JSX react/react-in-jsx-scope
any idea how modify .eslintrc.js
module.exports = {
parser: "babel-eslint",
env: {
browser: true,
node: true,
es6: true,
jest: true,
},
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:jsx-a11y/recommended"
],
plugins: [
"react",
"react-hooks",
"jsx-a11y",
],
rules: {
strict: 0,
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
},
settings: {
react: {
version: "detect"
}
}
}
for react 17?
Thank's a lot
You can read about it in React docs.
If you are using eslint-plugin-react, the react/jsx-uses-react and react/react-in-jsx-scope rules are no longer necessary and can be turned off or removed.
{
// ...
"rules": {
// ...
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off"
}
}
react-in-jsx-scope on github.
To make it work, you should add those rules to your eslint config, see Extending or replacing the default ESLint config for Create-React-App specifics, every framework should have related section in their docs.
You need to add plugin:react/jsx-runtime to extends in the .eslintrc.js file.
like is:
module.exports = {
extends: [
'plugin:react/recommended',
'airbnb',
'plugin:react/jsx-runtime',
]
}
Refer here

How to use eslint rule for no-multi-comp

I came across this style guide and trying to adopt some of its rules.
The first rule mentioned about
Only include one React component per file. However, multiple
Stateless, or Pure, Components are allowed per file. eslint:
react/no-multi-comp.
So in my .eslintrc
{
"parser": "babel-eslint",
"plugins": [
"react"
],
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"rules": {
"no-set-state": "off"
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true,
"modules": true
}
},
"globals": {
"localStorage": true,
"fetch": true
},
"settings": {
"react": {
"pragma": "React",
"version": "16.4.1"
}
}
}
I added this to rules
"rules": {
"no-set-state": "off",
"react/no-multi-comp": [true, { "ignoreStateless": true }]
},
Am I doing this correctly? Because when i read the docs, I saw a <enabled> I have no idea what that means.
<enabled> looks for value one of the 0,1,2 or one of the off,warn,error meaning:
From the docs:
"off" or 0 - turn the rule off
"warn" or 1 - turn the rule on as a warning (doesn’t affect exit code)
"error" or 2 - turn the rule on as an error (exit code is 1 when
triggered)
Using Visual Studio Code, and installing the ESLint plugin, you should be able to look under Output > ESLint
That the <enabled> is looking for 0, 1, or 2.
Change accordingly.

Set eslint rule for unused class methods in React component

I am trying to set an eslint rule for methods in class that are never used. Like in the following react component I have a method unUsedMethod which is never used, but eslint does not show an error for it.
class Sample extends Component {
unUsedMethod() {
console.log('I am never used');
}
render() {
return 'Hello!';
}
}
My eslint file looks like this
{
"parser": "babel-eslint",
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": ["eslint:recommended", "plugin:react/recommended"],
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true,
"sourceType": "module",
"allowImportExportEverywhere": false,
"codeFrame": false
},
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
"indent": [2, 4, {"SwitchCase": 1, "ObjectExpression": "first"}],
"linebreak-style": [
"error",
"unix"
],
"semi": [
"error",
"always"
],
"react/display-name": 0,
"react/prop-types": 0, // Temporary
"react/no-unescaped-entities": 0,
"no-trailing-spaces": 1
}
}
This plugin does what you are asking for. However a word of caution.
https://www.npmjs.com/package/eslint-plugin-no-unused-react-component-methods
Currently it is impossible to simply have a parser that would check for unused component properties, because component properties can be called dynamically.
For example:
class Sample extends Component {
// Plugin falsely flags this as unused.
unUsedMethod() {
console.log('I am used dynamically');
}
render() {
// No way to parse dynamic function calls reliably
this['unUsedMethod']();
return 'Hello!';
}
}
It also wouldn't work with react-onclickoutside package, as it requires a function to be attached to the component, that is called by wrapping the component in a HOC. https://www.npmjs.com/package/react-onclickoutside
Still the plugin helped me find a few unused functions, so it is worth a try in my opinion.
First install the package: npm i eslint-plugin-no-unused-react-component-methods --save-dev
Add "no-unused-react-component-methods" to your eslint configuration in the plugins section:
{
"plugins": [
"no-unused-react-component-methods"
],
}
And add into the rules section
{
"rules": {
"no-unused-react-component-methods/no-unused-react-component-methods": 2,
}
}
So your config would look like:
{
"parser": "babel-eslint",
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": ["eslint:recommended", "plugin:react/recommended"],
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true,
"sourceType": "module",
"allowImportExportEverywhere": false,
"codeFrame": false
},
"sourceType": "module"
},
"plugins": [
"react",
"no-unused-react-component-methods"
],
"rules": {
"no-unused-react-component-methods/no-unused-react-component-methods": 2,
"indent": [2, 4, { "SwitchCase": 1, "ObjectExpression": "first" }],
"linebreak-style": ["error", "unix"],
"semi": ["error", "always"],
"react/display-name": 0,
"react/prop-types": 0, // Temporary
"react/no-unescaped-entities": 0,
"no-trailing-spaces": 1
}
}
Now it should highlight any seemingly unused functions! Let me know if it works or not.

Resources