たごもりすメモ

コードとかその他の話とか。

EmacsでTypeScript/React開発する2023

世間に死ぬほど色々な方法があるのはわかっているがとにかくまっさらな状態から最短手順でEmacsでJSX/TSXが書けるようになりたい! という話。VSCodeとかそういう話には目を背ける。

自分で調べつつ試行錯誤したんだけど、最終的にはこのtweetで教えてもらった通りになった。メジャーモードとしてweb-modeを使いつつflycheckとLSPで開発支援。

macOSにインストールしたEmacs*1、およびMELPAにあるパッケージだけで、以下のようになった。

(require 'web-mode)
(add-to-list 'auto-mode-alist '("\\.ts[x]?\\'" . web-mode))
(add-hook 'web-mode-hook 'lsp)
  
(setq web-mode-markup-indent-offset 2)
(setq web-mode-css-indent-offset 2)
(setq web-mode-code-indent-offset 2)

Emacs + web-mode + lsp
補完も効く

事前にM-x list-packagesしてweb-modelsp-modeをインストール後に上記の設定をした。あとlanguage-serverをnpm install -g typescript-language-server typescriptしてインストールしてある。

他に関係あるのはcompanyflycheckかな? companyは以下のように読み込みと余計なことしないよう最低限の設定だけ。flycheckはインストール以外なんもしてない。lsp-modeも個別の設定は何もしていない。

(require 'company)
(global-company-mode) ; enable it anywhere
(setq company-idle-delay 0.1) ; no delay (default 0.5)
(setq company-minimum-prefix-length 2) ; (default 4)
(setq company-selection-wrap-around t)
(define-key company-active-map (kbd "M-n") nil)
(define-key company-active-map (kbd "M-p") nil)
(define-key company-active-map (kbd "C-n") 'company-select-next)
(define-key company-active-map (kbd "C-p") 'company-select-previous)
(define-key company-active-map (kbd "C-h") nil)
  
(set-face-attribute 'company-tooltip nil
                    :foreground "black" :background "lightgrey")
(set-face-attribute 'company-tooltip-common nil
                    :foreground "black" :background "lightgrey")
(set-face-attribute 'company-tooltip-common-selection nil
                    :foreground "white" :background "steelblue")
(set-face-attribute 'company-tooltip-selection nil
                    :foreground "black" :background "steelblue")
(set-face-attribute 'company-preview-common nil
                    :background nil :foreground "lightgrey" :underline t)
(set-face-attribute 'company-scrollbar-fg nil
                    :background "orange")
(set-face-attribute 'company-scrollbar-bg nil
                    :background "gray40")

JS/JSXはまだ別

JavaScriptおよびJSXも一緒の設定で編集できればよかったんだけど、手元で.jsのファイル開いてみたらJSXの部分がハイライトされない状態になってて微妙だった。なんでだ。今のところ、そっちは以前に設定したjs-jsx-modeをそのままにしてある。そのうち統合したいが、めんどいなあ。

(追記)ファイル拡張子のせいだった

わかった、JSXを.jsのファイルに書いていると、web-modeはJSX部分に反応しない、という話みたいだった。.jsxに拡張子を変更したら問題なくハイライトされるようになった。

*1:現時点で最新版は 28.2