読者です 読者をやめる 読者になる 読者になる

元フリーエンジニアライフ

Ruby on Rails とか MovableType とかAWSやってるフリーランスウェブエンジニアの記録でした。現在は法人成りしてIT社長。

Rails Asset / Sprockets関係gem使ったものの感想

はじめに 個人的な感想

ガンガンassets pipeline使う

  • Railsエンジニアだけでやる分には楽

assets pipeline / Sprockets使わない

  • SPA開発などで、フロントエンジニアさんが別にいる場合、フロントエンジニアさんが使いやすいツールでやって貰った方が楽
  • 自然と分業できる

プロジェクトによってどちらかに寄せる

今回は「ガンガンassets pipeline使った」例で使ってるassets関係gemの紹介をします

rails-fluxchat-example https://github.com/takeyuweb/rails-fluxchat-example

bower-rails

  • Bower ばうわー JavaScriptパッケージマネージャ
  • rakeコマンドrake bower:installでパッケージのインストールや更新ができる
  • assets precompileの前に自動でパッケージのインストールなどできる
  • インストールしたパッケージのパスをassets precompileの入れてくれる

RAILS_ROOT/vendor/assets/bower_components/alt/dist/alt-with-addons.js

//= require alt/dist/alt-with-addons

さらに後述のbrowserify-railsと組み合わせると

var Alt = require('alt/dist/alt-with-addons');

react-rails

browserify-rails

Browserify

ブラウザ上のJavaScriptvar hoge = require('./hoge');ってできるやつ

browserify-rails

  • Rails(Sprockets)でvar hoge = require('./hoge');ってできるやつ
  • モジュール化
  • ファイルごとに依存関係を記述できて読みやすい、整理しやすい
// app/assets/javascripts/components/Messages.jsx
var React = require('react/react-with-addons');
var AltContainer = require('alt/AltContainer');
var MessageStore = require('../stores/MessageStore.es6');
var MessageActions = require('../actions/MessageActions.es6');

var MessageForm = React.createClass({
// (snip)
});

var Messages = React.createClass({
// (snip)
});

module.exports = Messages;

※ Sprockets Asset Pipelineで使われているプリプロセッサ

sprockets-es6

  • Rails(Sprockets)でES6を書けるようになるやつ
  • Babel((ほぼ)ES6をES5に変換するやつ)
  • ES6前提のライブラリが使える
  • RailsでES6書きたいマン必携?
    • アロー関数書きたい
    • プロトタイプじゃなくてクラス書きたい
    • Promise書きたい など

browserify-rails とのからみ

.es6を付けないとダメ

// hello.es6
class Hello {
    constructor(name) {
        this.name = name
    }
    world() {
        alert('Hello ' + this.name+ ' World!')
    }
}
var Hello = require('./hello'); // NG
var Hello = require('./hello.es6'); // OK

Action Cable

Pub/Sub + WebSocket

Ruby WebSocketサーバ 及び Pub/Sub サーバ実装 JavaScript WebSocketクライアントライブラリ

Sub

Assetsでクライアントをつくる

Subscribe

// app/assets/javascripts/channels/ChatChannel.es6
var ChatChannel = window.App.cable.subscriptions.create("ChatChannel", {
    connected() {
        // Called once the subscription has been successfully completed
        console.log('ChatChannel connected');
    },

ActionCable Server側のRubyコードが呼び出される

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  def subscribed
    stop_all_streams
    stream_from 'chat_activity'
    stream_from "chat_activity:#{connection.uuid}"
  end

Pub

Rails App Server / ActionCable Server から Publish すると・・・

# "chat_activity:#{uuid}"でstream_fromしたSubscriberにメッセージ送信
ActionCable.server.broadcast "chat_activity:#{uuid}", message.to_json

Receive

Subscriber側のブラウザの以下のコードが呼び出される

// app/assets/javascripts/channels/ChatChannel.es6
var ChatChannel = window.App.cable.subscriptions.create("ChatChannel", {

   // (snip)
   
    received(json) {
        var message = JSON.parse(json);
        console.log('ChatChannel message');
        console.log(message);
        MessageServerActionCreators.receiveMessage(message);
    }

僕はES6で書きましたが、サンプルはだいたいCoffeeScriptでつらいです。

個人的感想

ツールとして

  • Rails上での扱いやすさ向上のためのツール類は割と使う
  • JSライブラリをgemにラップするRails AssetsよりはJSはJSの世界で管理できるbowar-railsの方が好き
    • JSライブラリのバージョンアップを追いやすい
    • JS側で依存関係管理しているのだから無理にbundlerでやんなくても。
    • Railsで使うからbundlerでまとめたい、というのも逆の意見であるだろう。おそらく感覚的なもので人それぞれ。

使い分け

  • フロント側の負荷が大きなプロジェクトならフロント側に寄せてあげる
    • Sprocketsで嵌まるのは忍びない
      • digest値のために.css.erbさせるとか
      • Rails.application.config.assets.precompile=を変更して貰うとか
    • turbolinksで嵌まるのは忍びない
    • 外れるなら完全に外せ!中途半端はわけわかんなくなるぞ!
    • 今やってる奴フロントのSPAの実装詳細は関知してないです。API仕様だけ決めてる。
      • 好きに書け、サーバ側でうまいことやってやるから。
  • そうじゃないやつは、ガンガン使ってみると面白い
    • Sprocketsらくちん
      • ERB使えるし
      • 好きな言語で書けるし
      • ソースコード中の記述やRails.application.config.assets.precompileで柔軟に設定できるし
      • 自動でにminifyしてくれるし
      • digest値付けてくれるから何も考えなくてもキャッシュで困らない
    • turbolinksだって真面目に使えばRailsらしいWebアプリがサクサク動いて気持ちいいよ。

Reactとか

  • やっぱり中途半端はよくない
  • UIコンポーネントと割り切って使う
    • 複雑なUI部品を実装する手段にする
  • SPAに使う
    • RailsAPIサーバにする勢いで
    • コントローラごとにSPAにするようなの試したことあるが、どうもコンポーネントの再利用とか、二度手間が増えたりみたいなでイマイチ感。
    • バックエンドやりつつフロントでSPAとかやろうとすると、開発効率すごく下がる実感あり。3倍ぐらい。
    • SPAやるならフロントではRails忘れろ。