DC4

最近試しているRails+Reactの構成

最近試しているRails+Reactの構成について。

Rails + React

Rails上でReactを使用する方法は大きく分けて3パターンに分けることができると考えています。

www.openmindedinnovations.com

  1. react-rails 等のGemを用いてRails内で使用する。
  2. frontendディレクトリ等を作成し、一部JS実装部分をRailsから切り離して yarn/npm/webpack 等で管理する。
  3. APIサーバとクライントで完全に分離する。

フロントエンドの実装ボリュームによってどの構成を選択するかが変わってくると思います。

今回の要望

新規Railsプロジェクトを作成する際の要望は以下でした。

  • フロントエンド専任はいない。
  • SPAにしない。
  • なるべくレールに乗りたい。
  • 複雑な箇所、非同期処理の部分はReactを使いたい。
  • Reduxを使うほどの複雑さでもない。でもFlux的な事はしたい。
  • 適宜jQueryも使いたい。
  • ES6を使いたい。
  • JSライブラリの管理はGemでしたくない。

試している構成

検討した結果、現在はパターン2 の構成で試しています。

Railsプロジェクト内にfrontendディレクトリを作成し、npm/webpack/babel でフロントエンドの開発を行い、その成果物をreact-railsでDOMにマウントしています。

frontend/
├── package.json
├── src
│   ├── components
│   │   ├── hoge-container
│   │   │   └── index.js
│   │   └── huga-container
│   │       └── index.js
│   └── entry.js
└── webpack.config.js

react-railsを使用してDOMにマウントするため、各コンポーネントをグローバルから参照できるようにしておきます。

frontend/src/components/hoge-container/index.js

import MicroContainer from 'react-micro-container';
import React, { Component } from 'react';

export default class HogeContainer extends MicroContainer {
  constructor(props) {
    super(props);
  }
.....
}

frontend/src/entry.js

import HogeContainer from './components/hoge-container';
window.HogeContainer = HogeContainer;

webpackので依存関係を解決したjsファイルを/app/assets/javascripts/配下に配置します。

app/assets/javascripts/
├── application.js
├── cable.js
├── channels
└── entry.bundle.js

View内で react-railsのヘルパーメソッド react_component を使用してマウントします。

....
<%= react_component('HogeContainer') %>
....

Flux的なこと。

react-micro-containerを利用しています。

GitHub - hokaccha/react-micro-container: Micro framework for React

所感

RailsとReactの恩恵をどちらも受けれるので、フロント実装が多くないプロジェクトならやっていけるのではないかなと感じています。

部分的にReactを導入できるので今回のようにフロントエンジニア不在の環境下でも現実的な気がしています。

Rails5 + ES6 + React + react-router + axios + CSS Modules でTodoアプリを作った。

前回 Angular2で作成したTODOアプリのReact バージョンを作成しました。

作ったもの

f:id:Yasun:20170225194059p:plain

todo-rails-xxx-js

構成

todo-rails-xxx-js/front/react-ver at master · yassun/todo-rails-xxx-js · GitHub

React

Angular同様に公式のチュートリアルがとても充実していました。

Tutorial: Intro To React - React

ライフサイクルについてはコチラの記事がとても参考になりました。

React component ライフサイクル図 - Qiita

react-router

React.jsのシンプルなルーティングライブラリです。

こちらも公式チュートリアルがあります。 GitHub - reactjs/react-router-tutorial

axios

APIとの通信時にAngularの場合はhttpモジュールが用意されているのですが、 Reactの場合は自分でライブラリを選択する必要があります。

調べた結果、候補として superagentaxios が挙がりました。

GitHub - mzabriskie/axios: Promise based HTTP client for the browser and node.js

GitHub - visionmedia/superagent: Ajax with less suck - (and node.js HTTP client to match)

今回はAngularのhttpモジュールに似ているという理由で axiosにしました。

CSS Modules

CSSモジュール ― 明るい未来へようこそ | プログラミング | POSTD

Reactと組み合わせることでCSSコンポーネント単位で管理することができます。

今までBEM記法等の命名ルールで行っていたことをwebpack(style-loader, css-loader)で自動的に行ってくれます。

今回のようにデザインテンプレートを使用している場合でも、 グローバルで使うために宣言されたクラスとローカルだけで使いたいクラスがコンポーネントを見た際に解かる利点がありました。

その他

css/jsのbundleにwebpack、ES6のコンパイルにBabelを使用しました。

まとめ

今回の構成は何かを作る際に第一候補として考えたいと思ってます。

その際にはRails 5.1 でもJSに関する変更点が多く入っているので、この当たりも合わせて試していきたいです。 weblog.rubyonrails.org

次回はVue.js と Flowtypeを試す予定です。

2016年を振り返る

今年もお世話になりました。
来年もよろしくお願いします。

今年も色々な事がありました。

海外での生活

一番大きな環境の変化として、生活拠点を海外に移して既に1年以上経過しました。

宗教、国民性、言語等が全く違う国に住むことで自分の価値観を強制的に相対化させられました。
また、日本という国を客観的に見れるようになった事も大きいです。

住む前からある程度予測をしていたのですが、こちらでの生活は何をするにも、全然思い通りに行かないです。本当に。本当に…。

今も解約したはずのネット回線業者から使っていない月の請求が来ており、交渉している最中です。

日本では中々味わう事のできない理不尽さのお陰で問題解決力とメンタル面がかなり鍛えられました。

これらの経験が役立つのか今の所わかりません。
ただ、今後、物事の考え方に与える影響は大きいと思ってます。

その他にもこちらの生活を通じて、プログラマとしての仕事は世界中どこでも行う事が出来る貴重なもので、数ある職のなかでこの業界を選んで、自分は本当に良かった。と改めて感じました。

英語

今年は英語に多くの時間を投資しました。

TOEIC200点台だった僕が600点になるまでにやったこと。 - DC4
f:id:Yasun:20161231223841p:image
本当に底辺レベルからのスタートだったのですが、1000時間くらいやった辺りから幾分かマシになりました。

フリーランス

今年からフリーランスとして仕事をしています。

「自分のスキルと時間に値段を付けて交渉する。」という行為に、最初はかなりプレッシャーを感じたのを覚えてます。
そのおかげで数字に根拠を持たせる為に、必要とされているスキルセットはなにか、自分の強みはどこにあるのか、といった事を日々悶々と考えるようになりました。

そしてなにより、会社という看板が無いにも関わらず、自分個人に仕事を依頼してくれる方々に出会えた事、またその信頼に応えたい。というモチベーションで仕事ができたというのはとても大きな経験です。

その他にも税金について学ぶ必要があり、それをきっかけに多くの事を学ぶ事ができました。

フロントエンド 

やっぱり前にも出たくて学習を再開しました。

Rails 5 + Angular2 + TypeScript でTodoアプリを作った。 - DC4

旅行 

リモート中心の仕事だった事もあり、
今年はアジアを中心に色々な国に行く事ができました。

初めて海外旅行にいったのは3年前なのですが、数えてみるとこの1年で30回以上飛行機に乗っていました。

今もこの記事をベトナムハノイで書いてます。

来年に向けて

現時点で日本のどこに住むのかが決まっていないのでなんとかしたいです。

英語に忙しくて個人でサービスを作れなかったので、来年は色々やっていきたいです。

帰国したらつけ麺やすべえと寿司を堪能しながら「君の名は」と「シンゴジラ」が見たいのとVRを体験したいです。

 

それではよいお年を!

Rails 5 + Angular2 + TypeScript でTodoアプリを作った。

フロントエンドの勉強のため、 Rails 5 + Angular2 + TypeScript + SystemJS の組合せでTodoアプリを作成しました。

作ったもの

f:id:Yasun:20161221000644p:plain

todo-rails-xxx-js

構成

GitHub - yassun/todo-rails-xxx-js: Todo samples by Rails 5 (API mode) and JS frameworks.

f:id:Yasun:20161221233809p:plain

開発中は RailsAPI と Angular2 それぞれでローカルサーバを立ち上げて作業しています。 違うポートでの通信となるのでクロスドメイン問題を解決する必要があります。

今回はこちらのGemを使用しました。 GitHub - cyu/rack-cors: Rack Middleware for handling Cross-Origin Resource Sharing (CORS), which makes cross-origin AJAX possible.

リリース時にビルドしたフロントのリソースfront/angular2/public/*Rails側の/public に移動しています。

Rails5

APIモードのオプション(rails new app --api)を付けて以下記事と同じ手順で作成しました。

Rails-APIでTODOアプリを作る。

Angular2 + TypeScript + SystemJS

Angular2は公式のチュートリアルがとても充実していました。

まずはこちらの章でAngular2の雰囲気を掴むことから始めました。

Quickstart - ts - QUICKSTART

その後はより実践的なチュートリアルに進みました。

Tutorial: Tour of Heroes - ts - TUTORIAL

こちらはかなりボリュームがあるのですが、ヒーローを題材としたSPAを作りながら

  • Component
  • Module
  • Routing
  • DI
  • Two-Way Binding / Event binding
  • Service
  • Mockの作り方
  • RxJS...etc

と開発に必要な要素を一通り学ぶことができます。

フロントエンド開発について

何も知らない状態からフロントエンドに入る際の障壁として、 Angular2 / TypeScript / RxJS の学習はサクサクと進めれたのですが、モジュール管理とビルド周りが辛かったです。

特にSystemJSをbundleするのに苦戦しました。

さいごに

Angularの次期バージョンは 3 ではなく、4になるそうです。 そして6ヶ月ごとにメジャーバージョンが上がるとの事です。

Angularの次バージョンは「Angular 4」に、2017年3月リリース。今後は単に「Angular」と呼んでほしいと - Publickey

Angularはフロント開発に必要なライブラリが既に用意されている状態で開始できるので、入門としては入りやすかったです。

次回はReact.js + Redux.js + ES6 で挑戦してみようと思います。

社内ISUCONに参加した。

そろそろISUCONの時期ですね!

今年は諸事情で参加できそうにないのですが...。

その変わりに(?)とある御縁からこちらの社内ISUCON(通称:ISHOCON)にお邪魔させて頂きました!

http://blog.mmmcorp.co.jp/blog/2016/08/05/ito-time-management/blog.mmmcorp.co.jp

やったことをざっくりと振り返りたいと思います。

言語選択はRuby。 環境は c3.xlarge。

開発環境の整備

  • AWSの構築 / sshの設定
  • ソースのGit管理
  • nginx/MySQLの設定バックアップ
  • vimの設定

アプリケーションの動作確認 (score : 104)

  • 機能の把握
  • 構成の把握

解析ツールの整備

  • kataribe
  • pt-query-diges
  • rack-lineprof
  • slow.logの出力設定
  • ログ退避したりミドルウェアを再起動したりするシェルを作成

準備していた設定ファイルの置き換え(score : 165)

アプリケーション修正 (score : 5569)

  • N+1の修正
  • 事前にJOIN出来る箇所を修正
  • OFFSETを使用している箇所の修正
  • nilを想定していない箇所の修正
  • 未使用カラムの削除

インデックスの追加 (score : 37908)

  • ベンチマークを実行しながら各種追加。
  • インデックスに合わせてクエリを修正。

キャッシュ戦略 (score :51319)

既にredis で実装している方が居たので今回は memchached でやってみることにしました。

ベンチマーク実行前に呼ばれる /initialize 内で必要な集計結果をどんどん乗せて、 最終的にベンチマークが集計時に必要としている特定テーブル以外のクエリ発行を無くしました。

sysctl.confの修正

ISUCON定番ネタですね。
ISUCON4 予選でアプリケーションを変更せずに予選通過ラインを突破するの術 - Hateburo: kazeburo hatenablog

css/imageの非同期読込み

こちらで紹介されていたテクニック。
#isucon 4に参加して予選2日目暫定1位になりました - 酒日記 はてな支店

最終調整

  • nginx, unicorn のプロセス数、workload数の調整
    • unicorn : 9, nginx worker_processes:4 / worker_connections=10240, workload: 10

足掻く (score :52403)

  • テンプレートから空白と改行の除去
  • String.freezeする

結果

f:id:Yasun:20160831175706p:plain

GitHub - yassun/ISHOCON1

反省点

memchached の方がクエリ発行より速いと決めつけてどんどん乗せたのですが、 最終的にボトルネックになってしまいました...。 DBとキャッシュのバランスをとりながら実装するべきでした。

あとはリダイレクトは点数加算されないという点をレギュレーションから見落としていました。

Nginxでセッション操作ができるので、そちらで完結出来るものがあると気が付きませんでした。

自分としてはこれ以上は厳しいと思ったのですが、まだまだやれることが沢山ありました。

ISUCON4 予選 参考解答(Redis版) : ISUCON公式Blog

まとめ

こういったイベントがあると実践的に楽しみながら勉強できるので良いですね。 出題を担当したshowwinさんに感謝です!

今回参加させて頂いたMMMさんではにエンジニアを募集中です!
リモートワークに興味がある方は是非! www.wantedly.com