152

I've installed eslint-config-airbnb that is supposed to pre configure ESLINT for React:

Our default export contains all of our ESLint rules, including ECMAScript 6+ and React. It requires eslint, eslint-plugin-import, eslint-plugin-react, and eslint-plugin-jsx-a11y.

My .eslintrc extending its configuration:

{ "extends": "eslint-config-airbnb",
  "env": {
    "browser": true,
    "node": true,
    "mocha": true
  },
  "rules": {
    "new-cap": [2, { "capIsNewExceptions": ["List", "Map", "Set"] }],
    "react/no-multi-comp": 0,
    "import/default": 0,
    "import/no-duplicates": 0,
    "import/named": 0,
    "import/namespace": 0,
    "import/no-unresolved": 0,
    "import/no-named-as-default": 2,
    "comma-dangle": 0,  // not sure why airbnb turned this on. gross!
    "indent": [2, 2, {"SwitchCase": 1}],
    "no-console": 0,
    "no-alert": 0,
    "linebreak-style": 0
  },
  "plugins": [
    "react", "import"
  ],
  "settings": {
    "import/parser": "babel-eslint",
    "import/resolve": {
      "moduleDirectory": ["node_modules", "src"]
    }
  },
  "globals": {
    "__DEVELOPMENT__": true,
    "__CLIENT__": true,
    "__SERVER__": true,
    "__DISABLE_SSR__": true,
    "__DEVTOOLS__": true,
    "socket": true,
    "webpackIsomorphicTools": true
  }
}

Unfortunatelly I'm getting the following error when linting a .js file with React JSX code inside it:

 error  JSX not allowed in files with extension '.js'              react/jsx-filename-extension

Wasn't eslint-config-airbnb configured react to support JSX already, as stated ?

What should be done to remove that error ?

kas
  • 857
  • 1
  • 15
  • 21
Mendes
  • 17,489
  • 35
  • 150
  • 263

8 Answers8

309

Either change your file extensions to .jsx as mentioned or disable the jsx-filename-extension rule. You can add the following to your config to allow .js extensions for JSX.

"rules": {
  "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
}
Martin Mihaylov
  • 3,491
  • 1
  • 15
  • 10
  • 2
    If you don't want to change your filename extension or disable the rule, see [this answer](https://stackoverflow.com/a/51896943/182875) – M Falanga Aug 21 '18 at 13:07
  • 2
    This accepted answer does not disable the rule. It just simply allows .js files to contain JSX and what you've linked seems to create too much chaos in very large scale projects. – JanithaR Apr 09 '19 at 05:20
  • 2
    The second "jsx" element in the array is unnecessary. The "js" element is sufficient since the rule already references the "jsx" scope. – Wachaga Mwaura Mar 10 '20 at 10:44
  • Where is config file ? – Iman Marashi Sep 14 '20 at 03:39
29

It's work for me. hope to help you.

  1. disable jsx-filename-extension in .eslintrc:

    "rules": { "react/jsx-filename-extension": [0] }

  2. in webpack.config.js:

    resolve: { extensions: ['.js', '.jsx'] },

Willard
  • 369
  • 4
  • 6
19

Call me a dummy if it does not work for you

    "rules": {
        "react/jsx-filename-extension": [0],
        "import/extensions": "off"
    }
droid
  • 581
  • 7
  • 16
6

If you don't want to change your file extension, you can export a function that returns jsx, and then import and call that function in your js file.

// greeter.jsx

import React from 'react';

export default name => (
  <div>
    {`Hello, ${name}!`}
  </div>
);

and then

// index.js

import ReactDOM from 'react-dom';
import greeter from './components/greeter';

const main = document.getElementsByTagName('main')[0];

ReactDOM.render(greeter('World'), main);
M Falanga
  • 1,897
  • 17
  • 21
  • I don't understand the downvote. Can somebody explain so I can be a better contributor? – M Falanga Sep 17 '18 at 14:31
  • 9
    maybe it's because while this fix "works", it is, at best, a workaround. And including a workaround in multiple JS files throughout your project seems kinda hacky and unprofessional. – mkvlrn Sep 18 '18 at 10:54
  • I agree that this technique isn't idiomatic React. However I have only come across this problem with my entrypoint. I would not recommend doing this across all files, as it would create awkward code. If that's your use case, then just modify the linter rules as suggested in the accepted answer. – M Falanga Jan 26 '19 at 16:55
4

Following React documentation:

Each JSX element is just syntactic sugar for calling React.createElement(component, props, ...children).

Following Airbnb's style guide:

Do not use React.createElement unless you’re initializing the app from a file that is not JSX.

You could do this:

    //index.js
    const app = React.createElement(App);
    ReactDOM.render(app, document.getElementById('root'));
fjplaurr
  • 1,818
  • 3
  • 19
  • 36
2

To expound on Martin's answer, it seems that it is not possible, currently, to use JSX in React Native. A PR was created but reverted due to concerns about fragmentation and unknown consequences of having things like index.ios.jsx. I'm not sure how AirBnb works around this or if they do, but I have used basically the same rules block as Martin.

jacefarm
  • 6,747
  • 6
  • 36
  • 46
0

For future readers who want to write jsx in .js files:

  1. Install npm i react react-dom even if you think you're not writing react.
  2. Install npm i -D @babel/preset-react
  3. In babel config: plugins: ['@babel/plugin-transform-react-jsx']
  4. you should setup module.rules for /\.jsx?$/ files with babel-loader (so you will need to install npm i -D babel-loader too)
NeoZoom.lua
  • 2,269
  • 4
  • 30
  • 64
0

If you are facing this problem on VsCode then it might be for ESLint this extension, remove ESLint this extension to solve this line error issue.