Rails + Browserify + Mithril + cmsxで動くもん書いてみた

作った

これはなにか

  • GitHub の活用の幅を広げていくにあたって Issue のテンプレートがほしいと思ってたけど、最終的には URL を作る必要があるので、それを作るものを作った
  • Rails である必要はまったくなかったけど、裏側の作り込みを考えると組み合わせ的にはよく使いそうな感じが再現できて満足
  • ついでに Material Design てなんだろうと思って、あえて完全な gem を作りようのない Semantic UI を使ってみた

参考になるのはここら辺。

すでに似たようなのは当然世の中にある。

あとはテンプレートのノウハウを集めて作るだけ。こんなのは実は GitHub 時代に入る前の BTS と呼ばれてる時代から言われてたこと。いちばん最初にへーと思ったのはシックスアパートの以下の記事でした。

TypePadのテストで使っている3つのツール - Six Apart ブログ

近況

  • Heroku の multi buildpack を試してみたかった
  • 何やら最近は Rails の AssetPipeline が不人気らしい
  • Browserify Handbook を読んで npm のポリシーのよさ、そのよさに乗った開発をできるよさを知った
  • Mithril 本を読んでとりあえず何か書いてみなきゃと思った

これで夏休み前くらいからちまちまやってたことが一応区切れた。満足ぢゃ。

歴史

自分のスペック的なものなど。こういう経歴なのでこんなこと考えるんだな、こいつは、みたいな判断材料に使ってください。

  • Ruby と CoffeeScript が好きだけど、対レガシー PHP 戦歴もそれなり
  • JavaScript のフレームワークは Backbone.js, Angular1 をつまみ食い程度に
  • 一応 Jasmine でテストとか書けなくもない(今後は Mocha + power-assert にしたい)
  • Node.js は単なるユーザー。bower もタスクランナーも安定しないので敬遠してたらいい具合に npm に集約されそうでラッキー。
  • Rails は Rails 3 時代を中心に少々
  • SPA には縁がないが、Hybrid モバイルアプリでサクッと動くもんを作りたい、みたいなことは思ってる

感想

  • Heroku の multi buildpack は楽ちん
  • ブラウザのロードを契機とせずに watchify で回すのも悪くないかも

cf.

heroku/heroku-buildpack-multi

Mithril

  • Mithril は m.withAttr の名前以外はマジカルさも少なく、素直に書けてよい感じ
    • ただ、class も何もないっつーのは逆に覚えにくいので、API が少ないと言ってもやはりリファレンスが手放せない予感がちょっとしてる
  • 単に form の各要素を監視して値を計算して DOM を更新するだけなので AngularJS が日本で有名になりはじめの頃のサンプルに近く、あまり Mithril 向きじゃないかなと思ったけど、独自タグとかディレクティブがないので普通に JS でループ処理したり、割と楽に書けた
  • JSX クソきもいとか言っちゃってごめんなさい。CoffeeScript + MSX ( JSX for Mithril ) 快適です。

ただ、きっちりした型が(言語的な意味ではない)あった方がよい場合もあるので、AngularJS なんて不要とか言うつもりもないし、足りないものだらけなので、大きなアプリを書こうと思ったら、スケールはするかもしれないけど、実装力高くないとつらそうだなとは思う。

cf.

npm + browserify

きっかけは

俺の最近のRailsのJS開発環境を教えてやる - Qiita

で Sprockets で require するのはいいけど development 環境では GET の log が溢れかえって困るなーなんてことを思っていた時に上の記事を見かけたことだった。一応去年のうちに Browserify の名前は知っていたみたいだけど、この時まですっかり忘れていた。

  • npm の package 管理と npm run でやりたいことはだいたいカバーできてよい。まだ minify とかちゃんと見てないけど、最適化が仕事の中心ではないと理解しているので、概ね満足。
  • Browserify の transform とか、JS が変換前提になりつつある今、Sprockets だけでそれについていくのはやはり厳しい
  • 一方で Browserify もあくまで npm の世界観の一部をブラウザの世界に持ってくるためのものであって、asset 管理を全部任せようとするのは無駄に仕事を複雑にするのでよくない。AssetPipeline の方が楽できることもある。

Rails との組み合わせ方だけど、

Using Browserify with Ruby on Rails

を参考に、npm run で必要なコマンドを叩くだけにした。browserify-rails/browserify-rails よさげだったけど、結局 package.json に書くようなことを Rails の config に書くことになり、rails server が動いてブラウザでアクセスしないと browserify が動かないので邪魔くさいということが分かってやめた。

自分なりに工夫したのは Heroku の buildpack としては先に Node.js が動いて npm install + postinstall で browserify が動くようにしたことと、どうせ Heroku で Procfile を使うので、watchify は foreman で起動するようにしたこと。1

cf.

AssetPipeline

  • 上手に gem になってる asset を扱わせた時の楽さは最強
  • 自分で asset を足していく場合、minify 済みの asset の扱いが苦手なので precompile 設定が外せず、面倒
  • require されてなくても対応拡張子に対してとりあえず変換が走るのうざい、vendor 以下に置いてしまえ

Material Design

いろいろ気づきはあったけど割愛。

Semantic UI

導入方法はともかく、記述量は増えるけど割と直感的に書ける気がする。リファレンス首っ引きにならずとも、たぶんこんな感じだよね?が通じるのは嬉しい。

twitter bootstrap のように標準の域に行くのは難しいかもしれないけど、なかなかよいものだと思う。

deploy時生成2にこだわってたわけ

  • repos を小さく保てる
  • git grep 時に minify した JavaScript が引っかかるとか不幸すぎる
  • gem の読み込みとか node_modules からの deploy 時生成なら repos に入ってないからよい

実際には全部 deploy 時に生成するのは難しく、例えば Semantic UI は npm install 時に自分で build も行おうとするので gulp 必須で build 済みの asset をどう扱うかを考えざるを得ない。

今回、

  • .gitignore 対象ディレクトリ以下に asset を –force add
  • git grep –exclude-standard –no-index で探すと asset が引っかからない

ということを知ったので、repos の容量に影響しやすい font などを除いてこの形でいいような気がする。(font はでかいので CDN で解決できるならそれがベストなのではないかと思う)

まとめ

今回、Browserify と Mithril の二つをメインのキーワードに据えて、ちょっとイマドキなフロントのコードを扱ってみたいということで形にできたのはとても満足している。

次は Electron かな? いやーどうだろう。

  1. バックグラウンドに回ってしまうので終了が面倒くさくなるし、もし Un*x 的なプロセス管理とかに興味のない人にも開発に参加してもらおうと思った場合は間違いなくこの方がよい。 

  2. rails の assets:precompile のようなもの 

More

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Develop Document Jekyll