EmacsでReact(JSX)コーディングする環境について調べてみた
Reactの開発をする際、JSXで書くのか、それともJavaScriptベースにするのかと大きく2パターンありますが、コンポーネントの構造が把握しやすい点や、タイプ数も少なくなりそうなので、JSXで書くことにしています。
JSXの場合、JavaScriptのコードの中にHTMLタグが出てくるというものになりますが、Emacsでコーディングする際に、シンタックスハイライトや構文チェックをやりたいなーと思ったので、調べてみました。
※2015/10/28追記
JSXHintがDeprecatedになったため、ESLintに切り替えました。
※2015/11/7追記
js2-modeがJSXの編集に対応したそうです。
Emacs で React の jsx を js2-mode で書けるようになってたメモ - 牌語備忘録 -pygo
前提
項目 | バージョン |
---|---|
Emacs | 24.4 |
web-mode | 20150511.1326 |
flycheck | 20150511.1432 |
JSXHint | 0.14.0 |
JSHint | 2.7.0 |
JSXのシンタックスハイライト
js2-modeではJSXはサポートしていない
EmacsでJavaScriptコーディングする際によく利用されていると思われるjs2-modeですが、残念ながらJSXはサポートされていないようです。
少し前まで ReactのGitHub WikiのComplementary Toolsページ に、以下の記述があったのですが、最近見たら消えていました。
Many editors already include reasonable support for JSX (Vim, Emacs js2-mode).
確かに、HTMLタグ部分はハイライトが効いていません。
web-modeはJSXをサポートしている
最近EmacsでHTMLを編集する際におすすめされている web-mode ですが、こちらはJSXをサポートしているようです。
web-modeの公式サイト を見ると、 compatibility with many template engines に reactjs (jsx) の記述ありました。
(わかりにくテーマを使ってしまいましたが…) React.render()
内のJSX部分もタグとしてハイライトされていました。
HTML内にJSXを書く場合も、 <script type="text/jsx">
を認識してハイライトしてくれるので、現状JSXを扱う場合はweb-modeにしてしまった方が良さそうです。
.jsxをweb-modeで開く
JSXで書くJavaScriptファイルには .jsx の拡張子を付けることにして、そのファイルを開いた場合はweb-modeになるようにしました。
(require 'web-mode) ... (add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode))
インデントの調整
また、web-modeの設定例を探すと以下の様な設定をよく見かけていたのですが、これだとインデントがスペース2に揃わないケースがありました。
(defun my-web-mode-hook () "Hooks for Web mode." (setq web-mode-markup-indent-offset 2) (setq web-mode-html-offset 2) (setq web-mode-css-offset 2) (setq web-mode-script-offset 2) (setq web-mode-php-offset 2) (setq web-mode-java-offset 2) (setq web-mode-asp-offset 2) (setq indent-tabs-mode nil) (setq tab-width 2)) (add-hook 'web-mode-hook 'my-web-mode-hook)
公式サイトなどを見ていたところ、どうやら上記設定に該当する変数が新しくなっているようだったので、私の場合は以下のように設定することにしました。
(defun my-web-mode-hook () "Hooks for Web mode." (setq web-mode-attr-indent-offset nil) (setq web-mode-markup-indent-offset 2) (setq web-mode-css-indent-offset 2) (setq web-mode-code-indent-offset 2) (setq web-mode-sql-indent-offset 2) (setq indent-tabs-mode nil) (setq tab-width 2)) (add-hook 'web-mode-hook 'my-web-mode-hook)
(余談)jsx-mode.elはDeNA製JSX用
いろいろ探していると、 jsx-mode.el という、それっぽいものが引っかかってくるのですが、これはFacebookのJSX(React)用ではなく、DeNAが開発した JSX 用のようです。
JavaScriptの歴史には詳しくありませんが、DeNAのJSXは、ECMAScript 6のベースになったECMAScript 4ベースの構文がサポートされているらしいので、ES6風に書く際のシンタックスハイライトは有効なのかもしれませんが、FacebookのJSX部分をハイライトしてくれるのかは、使っていないのでわかりません。
JSXの構文チェック
最近はFlycheckを導入して、JavaScriptの構文チェックをしていました。
JSX向けには、JSX部分も構文チェックする方法と、逆にJSX部分を無視する方法があるようです。
Flycheck + JSXHintによる構文チェック
JSXHint というJSHintのラッパーツールを利用することで、JSX部分の構文チェックもできるようです。
JSXHintのインストールと設定
npmでインストール。
$ npm install -g jsxhint
init.elに以下のように設定しておくことで、web-mode時でかつコンテンツがJSXと判定される場合、JSXHintによる構文チェックをFlycheckが実行してくれます。
(flycheck-define-checker jsxhint-checker "A JSX syntax and style checker based on JSXHint." :command ("jsxhint" source) :error-patterns ((error line-start (1+ nonl) ": line " line ", col " column ", " (message) line-end)) :modes (web-mode)) (add-hook 'web-mode-hook (lambda () (when (equal web-mode-content-type "jsx") ;; enable flycheck (flycheck-select-checker 'jsxhint-checker) (flycheck-mode))))
ただ私の環境では、.jsxではうまく動いているようでしたが、HTMLファイル内にJSXコードがある場合はチェックできていないような感じでした。
JSXHintの設定
私の環境では、2点ほどJS(X)Hintの設定を変更しました。
Mixed double and single quotes ...
というエラーが、引用符を使っていないような箇所でも発生するようになってしまいました。
最近はJavaScript内の文字列にはシングルクォートを使うようにしているのですが、構文チェックをするに辺り、JSXをJavaScriptへ変換していて、その際に発生する文字列にダブルクォートが使われているのだろうと推測しました。
あまりにも多いので、 .jshintrc の "quotmark": false
を設定して、引用符の種類はチェックしないようにしました。
また、 React
がグローバルに出てきてしまうので、これも許容するようにしました。
{ "globals": { "React": true }, "quotmark": false, ... }
このあたりも、使ううちにもっと調整が必要かも。
JSHintを使いつつ、JSXは無視する
これはJSHintの機能ですが、コメントに jshint ignore:〜
という指示を入れておくと、ある部分をJSHintのチェック対象外にできるようです。
複数行の場合は jshint ignore:start
〜 jshint ignore:end
で囲み、1行の場合は jshint ignore:line
を使うようです。
'use strict'; var Hello = React.createClass({ render: function() { return ( <h1>{this.props.message}</h1> ); } }); React.render( // jshint ignore:start <div> <Hello message="Hello, World!" /></Hello> </div> // jshint ignore:end , document.getElementById('example') );
上記のようにすると、 React.render()
内のJSX部分はチェックされないので、不要なエラーを発生させなくすることができます。
スニペット
react-snippets
MELPAに react-snippets というものがありましたが、正直各APIはどの程度使うものなのかまだまだ理解できていないこともあり、現時点では様子見しています。
js-mode、js2-mode、web-modeに対応しているので、package.elを使っていれば、簡単に導入はできそうです。
ちなみに、どんなものが用意されているのかを見てみたところ、以下のとおりでした。
key | スニペット |
---|---|
cc | React.createClass |
cdm | React#componentDidMount |
cdu | React#componentDidUpdate |
cwm | React#componentWillMount |
cwrp | React#componentWillReceiveProps |
cwu | React#componentWillUpdate |
cwum | React#componentWillUnmount |
gdp | React#getDefaultProps |
gis | React#getInitialState |
r | React#render |
rc | React.renderComponent |
scu | React#shouldComponentUpdate |
sp | React#setProps |
ss | React#setState |
作られたのが1年前だけあって、すでに React.render
に置き換わっている React.renderComponent
が残っていたりしますね。
まとめ
ざっと調べてみて、簡単に導入できそうなものとしてはこのくらいでした。
調べている最中に、JSHintの次のLintツールと言われているESLintもJSXに対応していることに気付いた( Announcing ES6 and JSX Support - ESLint - Pluggable JavaScript linter )のですが、ESLint自体をまだ使っていないこともあり、しばらくはこの構成でいってみようと思います。
参考
- Complementary Tools · facebook/react Wiki
- Emacs - Setup JSX mode, JSX Syntax checking and Suggestion
- web-mode
- STRML/JSXHint
- EmacsWiki: Flycheck
Emacs実践入門 ?思考を直感的にコード化し、開発を加速する (WEB+DB PRESS plus)
- 作者: 大竹智也
- 出版社/メーカー: 技術評論社
- 発売日: 2012/03/07
- メディア: 単行本(ソフトカバー)
- 購入: 22人 クリック: 396回
- この商品を含むブログ (1件) を見る
入門 React ―コンポーネントベースのWebフロントエンド開発
- 作者: Frankie Bagnardi,Jonathan Beebe,Richard Feldman,Tom Hallett,Simon HØjberg,Karl Mikkelsen,宮崎空
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/04/03
- メディア: 大型本
- この商品を含むブログ (2件) を見る