Kentaro Kuribayashi's blog

Software Engineering, Management, Books, and Daily Journal.

JSXを、RailsのAsset Pipelineを使って動かしてみた

JSXがアツい感じだったので触ってみようと思いつつも、Rails学習中なので時間取れないなーと思っていたのだけど、Asset Pipelineで使えるようにしたらRails学習にもなるし、一石二鳥だなーってんで、ちょっとやってみた。

やったのは、

  • SassとかCoffeeScriptとかそれ系のものをいい感じにコンパイルするためのTiltというライブラリの、JSX対応
  • それをRailsで使えるようにする方法を調べた

という感じです。とりあえず、rails serverで起動したら、以下の通りHello, World!はできました(HTMLではなく、consolel.logの出力です)。

f:id:antipop:20120604025745p:plain

しかし、多分(?)Tiltだけ対応しても、Sprockets側でも対応しないとrake assets:precompileとかが動かない気がする。この点、rails serverについては、config.ruでTilt::JSXTemplateを使うように指定した。

開発環境の前提は以下の通り。

  • rails 3.2.3
  • jsxコマンドにPATHが通っていること

ほんでもって以下、rails new JSXTestしたばかりのコードと、fork版Tiltを使ってJSXをassets pipelineを使って動かすようにしたところまでのdiffです。

  • Gemfile
  • config.ru
  • app/assets/javascripts/application.js
  • app/assets/javascripts/hello.js.jsx

このあたりを見ていただくとよいかと思います。しかし、ちゃんとやるにはまだいろいろ必要そうだなー。Tiltのforkしたのも適当な実装だし。

diff --git a/Gemfile b/Gemfile
index ab4e34b..e84abea 100644
--- a/Gemfile
+++ b/Gemfile
@@ -36,3 +36,5 @@ gem 'jquery-rails'
 
 # To use debugger
 # gem 'ruby-debug19', :require => 'ruby-debug'
+
+gem 'tilt', github: 'kentaro/tilt', branch: 'jsx'
diff --git a/Gemfile.lock b/Gemfile.lock
index db9214f..0b0dedd 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,3 +1,10 @@
+GIT
+  remote: git://github.com/kentaro/tilt.git
+  revision: befa7aaf98a35d3fdda1568857b865d2f1dff8e8
+  branch: jsx
+  specs:
+    tilt (1.3.3)
+
 GEM
   remote: https://rubygems.org/
   specs:
@@ -90,7 +97,6 @@ GEM
       tilt (~> 1.1, != 1.3.0)
     sqlite3 (1.3.6)
     thor (0.14.6)
-    tilt (1.3.3)
     treetop (1.4.10)
       polyglot
       polyglot (>= 0.3.1)
@@ -108,4 +114,5 @@ DEPENDENCIES
   rails (= 3.2.3)
   sass-rails (~> 3.2.3)
   sqlite3
+  tilt!
   uglifier (>= 1.0.3)
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 9097d83..2567ea9 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -10,6 +10,8 @@
 // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
 // GO AFTER THE REQUIRES BELOW.
 //
-//= require jquery
-//= require jquery_ujs
-//= require_tree .
+//= require hello
+
+window.addEventListener("load", function(e) {
+    JSX.require("/Users/usr0600239/tmp/JSXTest/app/assets/javascripts/hello.js.jsx")._Main.main$AS();
+});
diff --git a/app/assets/javascripts/hello.js.jsx b/app/assets/javascripts/hello.js.jsx
new file mode 100644
index 0000000..2bf614a
--- /dev/null
+++ b/app/assets/javascripts/hello.js.jsx
@@ -0,0 +1,5 @@
+class _Main {
+    static function main(args : string[]) : void {
+        log("Hello, world!");
+    }
+}
diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb
new file mode 100644
index 0000000..3430228
--- /dev/null
+++ b/app/controllers/root_controller.rb
@@ -0,0 +1,4 @@
+class RootController < ApplicationController
+  def index
+  end
+end
diff --git a/app/views/root/index.html.erb b/app/views/root/index.html.erb
new file mode 100644
index 0000000..dc3e58a
--- /dev/null
+++ b/app/views/root/index.html.erb
@@ -0,0 +1 @@
+Hello, JSX!
diff --git a/config.ru b/config.ru
index 0f0fe27..93f19c4 100644
--- a/config.ru
+++ b/config.ru
@@ -1,4 +1,8 @@
 # This file is used by Rack-based servers to start the application.
 
+require 'tilt'
+require 'sprockets'
+Sprockets.register_engine '.jsx', Tilt::JSXTemplate
+
 require ::File.expand_path('../config/environment',  __FILE__)
 run JSXTest::Application
diff --git a/config/routes.rb b/config/routes.rb
index eace287..d9bb320 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,4 +1,6 @@
 JSXTest::Application.routes.draw do
+  root to: 'root#index'
+
   # The priority is based upon order of creation:
   # first created -> highest priority.