marizukaの記事一覧

社内業務ツールをVue.js/Vuex/rxjs/RailsでSPAで作ってみた話

配送サービスハコベルの担当の蟻塚です。

ここ1ヶ月半ほど、社内業務ツールを1人でSPAでモリモリ開発していたので、その話を書かせていただきます。

筆者のバックグラウンド

サーバーサイドエンジニア。SPAはBackbone/Marionette, React/Reduxで3回ぐらい書いたことがある。CSSもアニメーションも書けないのでフロントエンドエンジニアからは程遠い。SSRとかも詳しくない。

業務ツールの概要

  • 毎日の業務に使うので、使いやすさは重要
  • ジオコーディング等の非同期処理が数100〜件発生する
  • 社内でのみ使うツールであり、使用者は少人数。
  • 一度運用が回るようになりさえすれば改修はほとんど発生しない(想定)。
  • SSRとかは100%不要

今回使ったもの

フロントエンド

バックエンド

フロントエンドの話

なぜVue.jsを使うことにしたのか

1年ほど前に、React/Reduxで業務ツールを作ったことがあるのですが、その時の思い出として、

  • 開発速度が全然でない
  • 非同期処理を少し書くだけで実装どうするか迷う
  • middlewareを調べるのが手間
  • 関数型のノリが馴染まない

上記のような超個人的感想を持ちました。なので今回は、Vue.jsでSPAを作ってみることにしました。HTMLにJS直書きしているような雑なツールを作る際にVue.jsを使っていて、こっちのが楽なんじゃね、って思ったのもあります。

Vuex

reduxの影響でglobalなstoreでstate管理しようと思ってvuexを導入しました。ですが結局のところ、

  • コンポーネントlocalなstateはコンポーネントで管理する
  • 複数コンポーネント間でデータをやり取りしたいときだけ、Vuexを使う

という形にしました。たとえば、以下のようなものはVuexで管理することにしました。

  • ログイン情報
  • グローバルなメッセージ表示(snackbar)
  • 通信ローディング表示

こういうルールにした理由は、

  • URLに対応するようなコンポーネント(ex. アイテムリスト、アイテム詳細ページ)が破棄された場合は、そのデータを破棄したい。globalなstoreにデータを保存している場合は、明示的に破棄処理を書く必要がある
  • vuex使うと単純に実装時間が増える。
  • vuex付属のデバッガーをそれほど使わない(自分は)
  • そもそもあんまりstate管理に困っていなかった

上記のような理由からです。作るものによっては有用だと思うのですが、今回はそれほどメリットを感じなかったのでlocal管理にしました。

HTTP Responseをhookしてグローバルなメッセージを出す

例えばHTTPのレスポンスコードが500だった場合、エラー表示を出したいケース等あると思います。今回はできるだけ楽したかったので、axiosにインターセプターを登録して、レスポンスコードが200じゃなかった場合はエラーメッセージを表示することにしました。

  function serverErrorInterceptor(error) {
    const { message } = error
    store.commit(types.SHOW_MSG, {
      message: message,
      level: 'error',
    })
    store.commit(types.HIDE_LOADING)
    return Promise.reject(error)
  }

  client.interceptors.response.use(serverErrorInterceptor)

こういった処理はVuexを使ったおかげでスッキリ書けた印象があります。

rxjs

100回非同期処理を行って、10回成功する毎にDBに保存するためにサーバーにリクエストを投げる、みたいなことをシンプルにやりたくてrxjsを使いました。

人を選ぶツールかつ、イニシャルの学習コストが高いので気軽に導入しない方が良いと思いますが、時と場合によってはとても便利に使えます。上記のような例を普通に書くととても汚くなりがちですが、rxjsを使うとスッキリ書けます。

var Rx = require('rxjs/Rx')

const geocode = (v) => {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('geocode:' + v)
      resolve(v)
    }, v * 500)
  })
}

const save = (v) => {
  console.log("save: " + v)
  return new Promise(resolve => {
    setTimeout(() => resolve(v), 100)
  })
}

Rx.Observable.from([1, 2, 3, 4, 5, 6])
  .mergeMap(v => Rx.Observable.fromPromise(geocode(v)))
  .bufferCount(3)
  .mergeMap(locations => save(locations))
  .subscribe(
    () => { /* next */ },
    () => { /* error */ },
    () => console.log('complete')
  )

# output
-> % node sample.js
geocode:1
geocode:2
geocode:3
save: 1,2,3
geocode:4
geocode:5
geocode:6
save: 4,5,6
complete

Vuetify

https://vuetifyjs.com

vuetifyは、Material Component Framework for Vue.js 2 だそうです。SPAだとbootstrapはちょっと勝手が悪いので、vuetifyを使ってみました。現状使ってみて、ほとんど困ることはなかったのですが、

  • まだまだ開発途中(バージョンすぐ上がる)
  • 難しくはないが、ハマった時にソース読むしかない

1年後どうなっているかは不明ですし、まだproductionで使うには早いかな、といった印象はあります。ただ、こういったcomponent frameworkを使って開発する未来は近いという印象を受けました。概要は上記のリンクみて頂くのが早いと思います。

バックエンドの話

webpackerはどうなのか?

webpackerを使う前は、リポジトリのtopに /front  ディレクトリを作ってwebpackでビルドして、アセットパイプライン配下に放り込むスタイルでやってました。

webpackerの良いところは、railsにインテグレーションされていることだけです。悪いところは、webpacker特有のフォルダ構成になることです。

使用感としては、webpackerは開発初日に導入して以降はあまりいじることはありませんでした。また導入自体も困りませんでした。app/javascript/packs というディレクトリ構成はなんか嫌だなって思いましたが、生産性には何の関係もありませんでした。

基本的に、webpackの薄いwrapperであり、辞めたくなったらいつでも辞めれるので、オレオレ構成のwebpack railsインテグレーションするよりは、そのまんま使えば良いんじゃないか、というのが私の見解です。JS書くだけに使う分には困らないと思います。

終わりに

react nativeに対抗して、weex 作ってたりと、Vue.jsの周りのエコシステムもだいぶ充実してきているという印象でした。Backbone/Require.jsでSPA作ってた時代に比べるとだいぶツールも成熟してきており、生産性という観点でも JS FrameworkとComponent Frameworkを使って開発する未来が来てもおかしくないという印象があります。

また、Reactとの比較という点では、Vue.jsもかなり影響を受けており(勝手な主観ですが)、お互い大きな差分は減ってきているように感じます。おそらく React/Reduxで開発できる人は、Vue/Vuexでもそれほど学習コスト無く開発できると思います。

個人的にはVue.jsは開発しやすいフレームワークなので、興味を持った方は試してみては如何でしょうか。

採用もやってます! ↓


新規サービス・ハコベルをPHP/CodeIgniterからRuby on Railsに移行しました

こんにちは、ハコベルの開発を担当している蟻塚です。

2015年12月ハコベル正式リリースの少し前に、PHP/CodeIgniterからRuby on RailsのWAFの移行を行ったのでその際の話を書かせていただきます。
個人的にこっそり調査1ヶ月、業務時間フルで1ヶ月、延べ2ヶ月程度でメイン部分を移行して、その後1ヶ月で残タスクを消化といったスケジュール感でした。

続きを読む


sublime text3でphpの開発環境を整える

11月入社のAです。
前職はソシャゲの会社でPerlを中心に開発しており、php歴は約2ヶ月ほどです。

sublime text3で開発する場合は、デフォルトで十分開発できるのですが、
いくつか小技的なものの紹介させて頂きます。

sshfsでサーバーをマウントしてsublコマンドを使う

ラクスルではIDCFクラウド上のサーバーにsshでログインして開発しているので、
sshfsでリモートサーバーをローカルにマウントしています。

sublimeにはsublコマンドが付属しており、このコマンドを使うとターミナルからファイルを開くことができ非常に便利なのですが、リモートのファイルに対しては当たり前ですが使うことができません。

sshfsでマウントすれば、ターミナルからマウント先に移動できるので
ローカルファイルと変わらず使うことができます。

DocBlockerを入れて、phpdocコメントを書く

phpではphpdocという形式でソースコードにコメントを書けば、自動でドキュメントを生成してくれるツールがあります。

オープンソースプロジェクトなどでは標準的に使われており、できればちゃんと書きたいところですが、docコメント書くのは正直めんどくさい….

ということで当初はさぼっていたのですが、DocBlockerというパッケージを入れると随分書きやすくなりました。

docblocker1

ただし、1点はまりポイントがあって、GoogleIMEで日本語のコメントを書こうとすると、Enterキーを押した時点で内容が消えてしまいます。

パッケージ側の機能をコメントアウトして、対応することもできるのですが、それだと使いづらくなってしまうので、IME側の確定をEnterキー以外にも割り当てることで対応しました。

MacOSの場合、GoogleIMEの環境設定 -> キー設定の選択 の横にある編集ボタンから設定変更することができます。

Phpcsでファイル保存時にコーディング規約にあっているかチェックする

phpにはPHP_CodeSnifferというツールがあり、
ソースコードが、コーディング標準にしたがってくれるかをチェックしてくれます。

ラクスルではコーディング標準はまだしっかり定めているわけではないのですが、
できればPSR標準にしていきたいねーという動きがあり、ひっそりsublimeに導入しました。
php-cs-fixerというphpcsに違反している部分を自動修正してくれるツールがあるので合わせてそれも導入します。

sublimeではPhpcsというパッケージを入れることで、エディタ上からphpcsを利用することができるようになります。

  1. まずはphpcs/php-cs-fixerをインストールします。詳細は割愛しますが、僕はhomebrewで以下のようにインストールしました。
    brew update && brew upgrade
    brew install php56
    brew install php-code-sniffer
    brew install homebrew/php/php-cs-fixer
    
  2. sublimeのパッケージインストールで、Phpcsを入れて設定ファイルを書きます。
    設定ファイルは、Preferences->Package Settings->PHP Code Sniffer->Settings-Userから編集できます。
    他にも挙動は細かく設定できますが、最低限以下の設定をすれば使えるようになります。詳細はDefaultの設定ファイルを読むと良いです。

    {
        "phpcs_php_path": "/usr/local/opt/php56/bin/php",
        "phpcs_executable_path": "/usr/local/bin/phpcs",
        "php_cs_fixer_executable_path": "/usr/local/bin/php-cs-fixer",
    }
    

保存時にphpcsでチェックする例。
ここでは括弧の位置とstatic/pubilcの宣言順序が指摘されています。
phpcs1

php-cs-fixerで修正する例。
phpcs2

これでレビューで怖い人に怒られなくなりますね!

PHP-Twigを入れる

ラクスルではテンプレートエンジンにtwigを使っているのでtwig用のパッケージを入れます。twigを使っているなら入れるべきでしょう。

その他

折角なのでphp関係ないですが、僕が普段使っているパッケージをしれっと付け加えておきます。

Alignment
All Autocomplete
BracketHighlighter
Browser Refresh
Emmet
Markdown Preview
RecentActiveFiles
Sublime Bookmarks
TrailingSpace

何かお役に立つものがあれば幸いです。

ラクスルではsublimeが好きなエンジニアを絶賛募集中です!
ラクスル採用サイト