Search code examples
reactjsexpresseslinteslintrc

Eslint for a express and react project in the same project


I have a project with both the API (expess.js) and the client (Reactjs) in it.

Project/
├─ client/           // All my reactjs files
├─ src/              // All my express.js files
├─ .eslintrc.json

I am trying to configure eslint, for the express.js part I don't any problem. But for the react part i have the following error:

/home/dev/project/client/index.js
  5:17  error  Parsing error: Unexpected token <

Here is my eslint configuration

{

    "env": {
      "node": true
    },
    "parserOptions": {
      "ecmaVersion": 2018,
      "sourceType": "module"
    },
  
    "rules": {
      "block-scoped-var":             ["error"],
      "callback-return":              ["error", ["done", "proceed", "next", "onwards", "callback", "cb"]],
      "comma-style":                  ["warn", "last"],
      "curly":                        ["warn"],
      "eqeqeq":                       ["error", "always"],
      "eol-last":                     ["warn"],
      "handle-callback-err":          ["error"],
      "indent":                       ["warn", 2, {
        "SwitchCase": 1,
        "MemberExpression": "off",
        "FunctionDeclaration": {"body":1, "parameters":"off"},
        "FunctionExpression": {"body":1, "parameters":"off"},
        "CallExpression": {"arguments":"off"},
        "ArrayExpression": 1,
        "ObjectExpression": 1,
        "ignoredNodes": ["ConditionalExpression"]
      }],
      "linebreak-style":              ["error", "unix"],
      "no-dupe-keys":                 ["error"],
      "no-duplicate-case":            ["error"],
      "no-extra-semi":                ["warn"],
      "no-labels":                    ["error"],
      "no-mixed-spaces-and-tabs":     [2, "smart-tabs"],
      "no-redeclare":                 ["warn"],
      "no-return-assign":             ["error", "always"],
      "no-sequences":                 ["error"],
      "no-trailing-spaces":           ["warn"],
      "no-undef":                     ["off"],
      "no-unexpected-multiline":      ["warn"],
      "no-unreachable":               ["warn"],
      "no-unused-vars":               ["warn", {"caughtErrors":"all", "caughtErrorsIgnorePattern": "^unused($|[A-Z].*$)", "argsIgnorePattern": "^unused($|[A-Z].*$)", "varsIgnorePattern": "^unused($|[A-Z].*$)" }],
      "no-use-before-define":         ["error", {"functions":false}],
      "one-var":                      ["warn", "never"],
      "prefer-arrow-callback":        ["warn", {"allowNamedFunctions":true}],
      "quotes":                       ["warn", "single", {"avoidEscape":false, "allowTemplateLiterals":true}],
      "semi":                         ["warn", "always"],
      "semi-spacing":                 ["warn", {"before":false, "after":true}],
      "semi-style":                   ["warn", "last"]
    }
  
  }
  

I tried to add theses lines:

"overrides": [
      {
        "files": [ "client/**/*.js" ],
        "parser": "@babel/eslint-parser",
        "parserOptions": {
          "requireConfigFile": false,
          "ecmaFeatures": {
            "jsx": true
          }
        },
        "extends": [
          "eslint:recommended",
          "plugin:react/recommended"
        ],
        "plugins": [
          "react"
        ]
      }
    ],

But I still have an error

/home/dev/project/client/index.js
  5:16  error  Parsing error: This experimental syntax requires enabling one of the following parser plugin(s): 'jsx, flow, typescript' (5:16)

What should I do to use eslint with both an express.js backend and a reactjs frontend in the same project ?


Solution

  • I finally found the solution, in the overrides lines that a used i changed the react plugin by jsx.

    For that i needed to install a new package

    npm install eslint-plugin-jsx@latest --save-dev
    

    Here is the override part:

    "overrides": [
      {
        "files": [ "client/**/*.js" ],
        "parser": "@babel/eslint-parser",
        "parserOptions": {
          "requireConfigFile": false,
          "ecmaFeatures": {
            "jsx": true
          },
          "babelOptions": {
            "presets": ["@babel/preset-react"]
         }
        },
        "extends": [
          "eslint:recommended",
          "plugin:react/recommended"
        ],
        "plugins": [
          "jsx"
        ]
      }
    ],
    

    Here is the complete .eslintrc.json

    {
    
        "env": {
          "node": true,
          "es6": true
        },
        "parserOptions": {
          "ecmaVersion": 2018,
          "sourceType": "module"
        },
        "overrides": [
          {
            "files": [ "client/**/*.js" ],
            "parser": "@babel/eslint-parser",
            "parserOptions": {
              "requireConfigFile": false,
              "ecmaFeatures": {
                "jsx": true
              },
              "babelOptions": {
                "presets": ["@babel/preset-react"]
             }
            },
            "extends": [
              "eslint:recommended",
              "plugin:react/recommended"
            ],
            "plugins": [
              "jsx"
            ]
          }
        ],
      
        "rules": {
          "block-scoped-var":             ["error"],
          "callback-return":              ["error", ["done", "proceed", "next", "onwards", "callback", "cb"]],
          "comma-style":                  ["warn", "last"],
          "curly":                        ["warn"],
          "eqeqeq":                       ["error", "always"],
          "eol-last":                     ["warn"],
          "handle-callback-err":          ["error"],
          "indent":                       ["warn", 2, {
            "SwitchCase": 1,
            "MemberExpression": "off",
            "FunctionDeclaration": {"body":1, "parameters":"off"},
            "FunctionExpression": {"body":1, "parameters":"off"},
            "CallExpression": {"arguments":"off"},
            "ArrayExpression": 1,
            "ObjectExpression": 1,
            "ignoredNodes": ["ConditionalExpression"]
          }],
          "linebreak-style":              ["error", "unix"],
          "no-dupe-keys":                 ["error"],
          "no-duplicate-case":            ["error"],
          "no-extra-semi":                ["warn"],
          "no-labels":                    ["error"],
          "no-mixed-spaces-and-tabs":     [2, "smart-tabs"],
          "no-redeclare":                 ["warn"],
          "no-return-assign":             ["error", "always"],
          "no-sequences":                 ["error"],
          "no-trailing-spaces":           ["warn"],
          "no-undef":                     ["off"],
          "no-unexpected-multiline":      ["warn"],
          "no-unreachable":               ["warn"],
          "no-unused-vars":               ["warn", {"caughtErrors":"all", "caughtErrorsIgnorePattern": "^unused($|[A-Z].*$)", "argsIgnorePattern": "^unused($|[A-Z].*$)", "varsIgnorePattern": "^unused($|[A-Z].*$)" }],
          "no-use-before-define":         ["error", {"functions":false}],
          "one-var":                      ["warn", "never"],
          "prefer-arrow-callback":        ["warn", {"allowNamedFunctions":true}],
          "quotes":                       ["warn", "single", {"avoidEscape":false, "allowTemplateLiterals":true}],
          "semi":                         ["warn", "always"],
          "semi-spacing":                 ["warn", {"before":false, "after":true}],
          "semi-style":                   ["warn", "last"]
        }
      
      }
    

    I found the solution on this article