エンジニアになりたい

社会人1年目です

js2-jsx-modeでauto-completeを有効にする

js2-modeにjs2-jsx-modeが追加された。これはReact.jsのjsxをサポートしてくれるモードである。

普通にjs2-modeを使うだけではjsxを解釈してくれないが、js2-jsx-modeを導入することで解釈してくれるようになる。

しかし、普通に使うだけではauto-complete-modeと同時に使うことが出来なかった。 以下のような設定をinit.elなどに追記することで、同時に使えるようになる。

;; init.el

(add-hook 'emacs-lisp-mode-hook '(lambda ()
                                   (require 'auto-complete)
                                   (auto-complete-mode t)
                                   ))
(require 'auto-complete-config)
(ac-config-default)
(add-to-list 'ac-modes 'js2-jsx-mode)

さらに、flycheckを使用すると構文チェックをしてくれるのでおすすめ。 最終的に以下のような設定になった。

;; init.el

;; .jsファイルなどでjs2-jsx-modeを有効にする
(require 'js2-mode)
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-jsx-mode))

;; js2-jsx-modeでflycheckを有効にする
(require 'flycheck)
(flycheck-add-mode 'javascript-eslint 'js2-jsx-mode)
(add-hook 'js2-jsx-mode-hook 'flycheck-mode)

;; js2-jsx-modeでauto-complete-modeを有効にする
(add-hook 'emacs-lisp-mode-hook '(lambda ()
                                   (require 'auto-complete)
                                   (auto-complete-mode t)
                                   ))
(require 'auto-complete-config)
(ac-config-default)
(add-to-list 'ac-modes 'js2-jsx-mode)

react-routerでrouteに入った時のイベントを取る

react-routerでは、何かしらのrouteに入った時のフックポイントが用意されている。

以下のように onEnter を使う。

const { Router, Route } = require('react-router');
const { App, Home } = require('./components');

// Homeに入った時の処理
function enterHome() {
   console.log('enter home');
}

ReactDOM.render(
  <Provider>
    <div>
      <Router>
        <Route path="/" component={App}>
          <Route component={Home} onEnter={enterHome}/> // onEnterをここに書く
        </Route>
      </Router>
    </div>
  </Provider>,
  document.getElementById('root')
);

react-router本家では以下の様に説明されていた。

onEnter(nextState, replace, callback?)

routeに入った時に呼ばれる。次のrouterの状態と、別のパスにリダイレクトするための関数が与えられる。 this はフックをトリガーしたrouteのインスタンスになる。

もし callback が第三引数として与えられたら、このフックは非同期に実行され、 callback が呼ばれるまでそのrouteへの遷移はブロックされる。

その他

nextStatereplace も特に使う必要の無い場合は↑に書いたようにすれば良いと思う。以下の記事のように認証系に使うこともあるようだ。ログイン必須のrouteへの遷移の時に強制ログインをさせる、みたいな感じに。

www.terlici.com

Phoenix+Babel環境でWebSocketを扱う際にエラーが出る

Phoenixを使ってWebSocketを扱う際に、クライアントサイドをBabelを使って書いていると以下のようなエラーに出会った。

ERROR in ./deps/phoenix/web/static/js/phoenix.js
Module build failed: TypeError: work_space_path/deps/phoenix/web/static/js/phoenix.js: Duplicate declaration "channel"
  454 | 
  455 |   channel(topic, chanParams = {}){
> 456 |     let channel = new Channel(topic, chanParams, this)
      |         ^
  457 |     this.channels.push(channel)
  458 |     return channel
  459 |   }

/deps/phoenix/web/static/js/phoenix.jsPhoenixが提供している、channel機能を抽象化したJavascriptライブラリである。これを使うと、サーバーサイドのPhoenixとクライアントサイドのJavascript間のWebSocket通信処理を簡単に記述することが出来る。

その phoenix.js を使用すると、上記の通り Duplicate declaration "channel" と言われてしまった。

原因はクライアントサイドをBabelのES2015 transpilerを使って書いているところにあった。これを使っていると、 channel という変数が二重に宣言されていると怒られてしまうようだ。

そこで以下のように phoenix.js を変更すれば良い。

// before
channel(topic, chanParams = {}){
  let channel = new Channel(topic, chanParams, this)
  this.channels.push(channel)
  return channel
}
// after
channel(topic, chanParams = {}){
  let channelInstance = new Channel(topic, chanParams, this)
  this.channels.push(channelInstance)
  return channelInstance
}

ちなみに↑は以下のPRを参考にした。

github.com

Githubに毎日コミットし続けて100日を超えていた

www.slideshare.net

去年の@t_wadaさんの↑の資料に感化され、毎日Githubにコミットし続けてついに100日を超えた!

f:id:pro_shunsuke:20160131214557p:plain

本当は100日ぴったりの時にスクショを撮りたかったけど、完全に忘れていて本当に悔しい・・・。

感想なりなんなりを書いていこうと思う。

そもそも何で始めたのか

元々コード書くのはすごく好きだった(そうでもなければエンジニアという職業に付いていなかったと思うのだが・・・)。エンジニアという職業に付いたからには、やはり自分の力をどうにか伸ばしていきたいなと思っていた。しかし、やはりどこかでちょっと面倒くさいなぁという気持ちもあったのか、思うだけで何も実行していなかった。そんな時に和田さんの↑発表を聞いて、「やろう!」と思い立ったしだい。

達成具合

資料には、以下のルールの元に毎日コードを書く事を目的としていた。

  1. 毎日コードを書くこと。ブログ、ドキュメント、その他はコードを書いたらやってよい。
  2. 意味のあるコードを書くこと。インデントやフォーマットの修正、可能ならばリファクタリングもコード書きにはカウントしない。
  3. 深夜 24 時前に終わらせること。
  4. 書いたコードをgithubで全てOSSにすること

このルールをどれだけ守れていたのか振り返ってみる。

  • 毎日コードを書くこと。ブログ、ドキュメント、その他はコードを書いたらやってよい。

Githubに毎日草を生やす事が出来たので達成出来たと言えるだろう。

  • 意味のあるコードを書くこと。インデントやフォーマットの修正、可能ならばリファクタリングもコード書きにはカウントしない。

これは難しかった。最初の頃はRails Tutorialを毎日やっていたが、それが意味のあるコードと言われるとかなり怪しい。リファクタリングをするだけの日もあったので、完璧に守ることは出来なかった。

  • 深夜 24 時前に終わらせること。

用事があって24時を過ぎて帰宅してしまう日など、次の日になってコミットして、コミット日時をずらしてしまうというずるをする事があった。このずるに関しては批判の声も多いことと思う。ただ、私はこの修行に関しては、続ける事がとても大事だと思っている。たった一日コミットをしないことでモチベーションが下がり、その後続けられなくなってしまうよりは、ずるをしてでも続けた方が良いだろうと思ったのだ。杭はない。

  • 書いたコードをgithubで全てOSSにすること

先ほども書いたが、最初の頃はRails Tutorialの写経をしていた。なので、出だしからすでに破綻していた。ただ、個人的にはあくまで自己鍛錬のためにこの修行を行っているので、そもそも書いたコードをすべてOSSにする気もなかった。

毎日コードを書くことは出来たが、4つのルールを守ることは出来なかった。ただ、自己鍛錬を目的にしているなら必ずしもルールに則る必要は無いのかな?と思う。

モチベーションの保ち方

先輩の存在が大きかった。私がこの修行をやると先輩に言い出した時に、先輩も一緒に乗ってくれた。本来自分のプロダクトに関してコードを書くことは孤独なはずだが、こうやって一緒にやってくれる人がいるととてもやる気になった。他にもちょくちょくモチベーションを保つ方法はあったけれど、やはりコレが一番大きいと思う。

やってよかったこと

会社で触るものとは全く異なる技術に触れることが出来た。現在会社では主にRailsRubyを触っていたり、Symfony2でPHPを触っているが、この修行ではPhoenixを使ってElixirを書いていたりする。また、フロントエンドはReactを使ったり、開発環境にDockerを導入してみたり、とにかく自分の興味のある領域にどんどん進んでいけた。最終的にはうまく会社のプロダクトにも組み込めていけたら良いなと思っている。

最後に

本当に自分に力が伸びたかどうかは正直分からない。そもそもエンジニアの力ってコードを書く能力だけでは無いと思っているし・・・。しかし、ここ数ヶ月毎日コードを書き続けて、やはり良かったなと思う。新しい技術に触れたり、自分で動くものを作ったり、そういうのやっぱり楽しいなと思う。技術が好きでエンジニアになったし、仕事のコードを書くだけだと本来のエンジニアリングの楽しさを忘れてしまうような気がしないでもない。

特にまとまりもなくつらつらと書いてしまったが・・・、これからも毎日コードを書き続けたいと思う。

Rails5のActiion Cableを触ってみた

Rails 5.0.0.beta1が2015年12月18日にリリースされた。Railsの生みの親であるDHH氏によって以下のブログがポストされた。

Riding Rails: Rails 5.0.0.beta1: Action Cable, API mode, Rails command

Rails5.0の注目すべき1つの機能であるAction Cableは、すでにBasecamp3というプロダクトで実際に使われているそう。

basecamp.com

Action CableはWebsocketと呼ばれるプロトコルフレームワークとして扱える機能で、具体的にはリアルタイムWebアプリケーションを簡単に作ることが出来る、というもの。

私も元々リアルタイムで何かをやる系の事が好きだったので、触ってみた。全体感を以下のスライドにまとめた。

www.slideshare.net

簡単なチャットアプリならわりと簡単に作れるので、興味のある人は是非。

ローカルで編集したファイルをDockerコンテナに反映させる

Dockerを使った開発を行う時に、直接コンテナにログインして中のファイルを編集するのでは無く、ローカルでファイルを編集して、それをコンテナに反映したい。

これを実現するためには、 docker run を実行するタイミングで -v オプションを指定する。

以下の様にホスト側のパスとコンテナ側のパスを指定する。

$ docker run -v <host_path>:<container_path> -t ubuntu /bin/bash

-v <host_path>:<container_path> オプション

-v <host_path>:<container_path> オプションを指定すると、 ホスト側のパスをコンテナ側のパスにマウントして起動する ことが出来る。データの実態はホスト側にあって、それをコンテナが参照している感じ。 ホスト側の変更を逐一scpで送信するような事はしていない。

メリット

IDEを使って開発を行いたい時に便利。vagrantでいうsynced_folderのように扱える。

ハマった所

-v オプションを最後に持ってくると失敗した。最後に指定するとダメらしい。

BulletがN+1を検出してくれない事があってそれが分からない

Bulletというgemがある。この人は無駄にクエリが流れていないか、いわゆるN+1になっていないかを見つけて報告してくれる。

github.com

使っていて「あ、N+1になってたんだ。解決しないと」ってなってとても便利。

しかし、ある時Railsのログを見ていたら、明らかにN+1っぽいクエリが流れていたのにBulletがそれを検出出来ていない感じだった。

そしてこのブログを書こうか迷ったのだけど・・・ 結局なぜ検出出来ていないのか分かっていない。 (分かったらまたブログ書く。。)

なので、このブログは「Bulletでも検出出来ない事がある」ということが分かった程度の内容だ。

今回のようなケースがあるので、投げているSQLに不安があるような場合は、下の様に監視しながら開発をした方が良いかもしれない。

$ tail -f development.loog | grep SELECT