20

I've use js2-mode but it don't indent html in javascript properly. I've found this repo https://github.com/jsx/jsx-mode.el but it's not for react, it's for some other jsx.

What do you use for editing react application with jsx files?

6 Answers 6

19

Solution 1:

Step 1, Use https://github.com/felipeochoa/rjsx-mode

Step 2, Install Emacs 25+, see https://github.com/mooz/js2-mode/issues/291

Step 3, Patch rjsx-mode with below code

(defadvice js-jsx-indent-line (after js-jsx-indent-line-after-hack activate)
  "Workaround sgml-mode and follow airbnb component style."
  (save-excursion
    (beginning-of-line)
    (if (looking-at-p "^ +\/?> *$")
        (delete-char sgml-basic-offset))))

Please note there is still some indent issue if you use arrow function in component attribute. But this solution works fine in most cases.

The patch is still useful for current stable version rjsx-mode v0.4.0.

The bug was fixed on 2018-8-19 in unstable version, see https://github.com/felipeochoa/rjsx-mode/pull/75 for details.

The reason I stick to rjsx-mode is that it inherits from js2-mode so I can use imenu functions from js2-mode. It's very useful when writing es6 javascript.

Please note if you use js2-jsx-mode instead of rjsx-mode, you still need my patch.

Solution 2:

Use web-mode. I don't use web-mode but its recent release note claims jsx indentation can be handled properly. If you use web-mode, imenu from js2-mode is not available any more.

5
  • 2
    Didn't know that web-mode support jsx, I will use it then, the author is really responsive on github, if you find bugs in indentation.
    – jcubic
    Jun 15, 2017 at 8:06
  • 1
    The indentation problem in rjsx-mode seems to be fixed!
    – cgl
    Mar 16, 2018 at 12:25
  • It's fixed after applying my fix. I use rjsx-mode in both Emacs 25.2 and 25.3
    – chen bin
    Mar 18, 2018 at 5:03
  • The patch is a good idea, wish it was already merged into rjsx mode though!
    – user10000
    Nov 30, 2018 at 23:38
  • Can you add information about the patch being unnecessary with new versions of rjsx-mode or remove it entirely?
    – user12563
    Jan 26, 2019 at 11:23
18

In Emacs release 27 and later, JSX support is built into the default JavaScript mode for Emacs, js-mode.

screenshot of JSX highlighted in Emacs

If the use of JSX is anticipated, then JSX support will be automatically enabled in JavaScript buffers. The default criteria are:

  • file name ends in “.jsx”, or
  • import React from 'react' or var React = require('react') appears near the top of the file

You can customize the detection strategy by adding regexps to the variable js-jsx-regexps. To enable JSX unconditionally, you could also set js-jsx-syntax to t in an init file / .dir-locals.el / file variable, or call js-jsx-enable in js-mode-hook.

Once enabled, JSX will be highlighted and indented properly.

Users who were disappointed with the JSX indentation support available since version 25 may be pleasantly surprised to find that the indentation is far more accurate than before. For instance, JSX no longer needs to be wrapped in parenthesis in order to be indented properly. Indenting code with arrow functions also works much better now.

3

I use web-mode with the following configuration:

(require 'web-mode)
(add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))

;; (setq web-mode-enable-auto-pairing t)
(add-hook 'web-mode-hook
          (lambda ()
            ;; short circuit js mode and just do everything in jsx-mode
            (if (equal web-mode-content-type "javascript")
                (web-mode-set-content-type "jsx")
              (message "now set to: %s" web-mode-content-type))))
3
  • Not all of your configuration is relevant to JSX.
    – user12563
    Jan 26, 2019 at 11:24
  • Indeed, I was under the impression that it would be useful anyway. Edited the answer to remove things not related to JSX.
    – amirouche
    Jan 26, 2019 at 13:46
  • Using web-mode with JSX will make you want to download Visual Studio!
    – sshaw
    Mar 27, 2021 at 23:26
1

I also use web mode and if you use use-package you can use this code snippet.

(use-package web-mode
  :defer 2
  :after (add-node-modules-path)
  :ensure t
  :mode ("\\.html?\\'"
         "/themes/.*\\.php?\\'"
         "/\\(components\\|containers\\|src\\)/.*\\.js[x]?\\'"
         "\\.\\(handlebars\\|hbs\\)\\'")
  :config (progn
            (setq
             web-mode-markup-indent-offset 2
             web-mode-css-indent-offset 2
             web-mode-code-indent-offset 2
             web-mode-enable-auto-closing t
             web-mode-enable-auto-opening t
             web-mode-enable-auto-pairing t
             web-mode-enable-auto-indentation t
             web-mode-enable-auto-quoting t
             web-mode-enable-current-column-highlight t
             web-mode-enable-current-element-highlight t
             web-mode-content-types-alist
             '(("jsx" . "/\\(components\\|containers\\|src\\)/.*\\.js[x]?\\'")))))

This also adds local node modules to your path so that you can use eslint with flycheck. Note this assumes you're on macOS, which needs add-node-modules-path to fix that same issue. You will also need to configure Flycheck seperately for linting to work.

If you only want jsx related stuff you can do use this:

(use-package web-mode
  :ensure t
  :mode ("/\\(components\\|containers\\|src\\)/.*\\.js[x]?\\'")
  :config (progn
            (setq
             web-mode-content-types-alist
             '(("jsx" . "/\\(components\\|containers\\|src\\)/.*\\.js[x]?\\'")))))

This will enable web mode only on folders with names components, containers or src. If you want to enable web mode on any .js file then remove those lines. If you don't want web-mode enabled in src folders then remove that line in the string both on :mode and :config.

0

I also add web-mode enabled but for some reasons it was not highligting JSX. The solution (proposed by the author) is to add:

  (setq web-mode-content-types-alist
        '(("jsx" . "\\.js[x]?\\'")))

Source: https://prathamesh.tech/2015/06/20/configuring-web-mode-with-jsx/

2
  • Yes I use web mode for JSX. This is the best solution. But I use (add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode))
    – jcubic
    Mar 29, 2023 at 15:42
  • @jcubic This would work only if you use the .jsx extension for your file. In my cases the react template created .js files containing JSX code, so that's why I needed the above code.
    – tobiasBora
    Mar 29, 2023 at 19:31
0

I use jtsx-jsx-mode from jtsx package (I am the author).

It is implemented on top of js-ts-mode which use `tree-sitter code parser (only available starting Emacs 29.1).

It fixes some issues (JSX comments and indentation) and adds some features : refactoring, jumping, electricity on ">" key, code folding...

jtsx-tsx-mode is also provided by jtsx with the same functionalities.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.