新宿.rb#30で、僕はどうしてもlibsassが使いたかったんだ!というLTをした

ザックが来ていて、写真を撮ってもらえて浮かれた。

instagram.com

資料

www.slideshare.net

割りと赤裸々に、Libsass on Sprockets を実現するために苦しんだ話をさせてもらった。

これは西日暮里.rbでもLTさせてもらったsprocketsを捨てたい話の延長線の話で、gulpを使ってフロントエンドでビルドをした成果物(assets)をapp/assetsに配置する時の苦労話のstyle編。

具体的には

  1. 複数エントリーポイントの差分ビルドをどうやって実現するか
  2. asset_pathヘルパーをどうやって解決するか

の2つの問題があった。

複数エントリーポイントの差分ビルドをどうやって実現するか

これはproductionデプロイ時には関係なくて、開発時の悩みの話。

開発時のSprocketsさんは、依存関係を定義しておけば、リクエストされたタイミングでassetsを動的にコンパイルする。
styleに複数エントリーポイントがあってもなくても、リクエストされた段階で依存関係を解決して、assetsのurlを提供してくれる。
なのでファイルの変更を監視する必要はない。

しかしSprocketsさんに頼らずにgulpでビルドする場合には事前にビルドすることになるため、app/assetsに出力した段階で依存関係を解決しておく必要がある。
つまり、ファイルが変更されたタイミングでの再ビルドが必要になる。

コードベースが小さければ、大元のエントリーポイントを1つだけ設けて、全てビルドしてapp/assetsに配置すればいいのだけど、コードベースが大きくなってくると、1回あたりのビルド時間が長くなってしまう。
開発時にファイルの変更が入るたびに1s以上待つようになると、非常に苦痛で発狂しかねない。
ということで差分ビルドする必要がある。

そのためにはgulpタスク内でsassの依存関係(@import)を辿れるようにすればいい、ということでやってみたのが以下の記事。

qiita.com

最善策かどうかは置いといて、現状とりあえずうまく動いている。

asset_pathヘルパーをどうやって解決するか

sprockets外しで避けては通れない、asset_pathヘルパーをどうやって解決するか、という問題。

sprocketsはassetsファイルに変更があった場合には、ブラウザのキャッシュを効かせないため、ファイル名にdigestを付与する。

このdigestを無視して記述することができるのが、asset_pathヘルパーメソッドで、Sprocketsでruby-sassを使ってビルドする際には このヘルパーメソッドが使える。

だけどasset_pathはあくまでSprocketsの仕組みで、libsassには当然ないし、そもそもgulpでビルドした段階ではsprocketsのdigestを知ることはできない。

これをSprocketsのRailに乗っかったままどうやって解決するか、というのは下記の記事が参考になる。

qiita.com

しかし開発段階で、.css.erbなファイルにはしたくない。
影響範囲が大きいので、imageをpublicに配置するようにするのもどうかな。。
あとある事情で、どうしてもruby-sassを撲滅したい理由もあった。(つまり.scssなファイルはapp/assetsには置きたくない。(詳しくはLT資料を参考)

そのためにどうしたか、というのが以下のqiitaの記事。

qiita.com

簡単に言うと

gulpで無理やり.css.erbに変換するか。erbなら余計な処理もなくて軽いでしょ

という雑な対応。まぁうまく動いた。

これもっとかっこいい解決策あるだろ、という感じがする。

具体的にはsprocketsでcssのプロセッサーを自作すればいいのでは?と思っているのだけど、sprockets力が足りなくてそこまでには至っていません。

かっこいい解決策をお持ちの方は是非教えてください!

さいごに

新宿.rb、運営されてる方々、参加された方々お疲れ様でした!
次回以降も是非参加させていただきたいと思っています。
よろしくお願いします <(_ _)>

ブラウザ上で開いているものをなんでもOCRできるようにしてみた

英語の勉強も兼ねてhuluとかで海外ドラマを字幕付きで見ることがあって、かっこいいセリフとか出てきたときに字幕をクリップボードにコピーできたら便利だよなーと思ってそんなchrome extensionを作ってみた。

インストールはこちら

github.com

使い方はこんな感じ。

https://github.com/joe-re/OCR-Screen/raw/master/OCRScreen.gif

OCR処理にはOcrad.jsというライブラリを使っている。

このchrome extensionの主な処理はOCRしやすいように画像を加工すること。
具体的には、画像の中に出ている文字と似ている色は黒にして、それ以外は白にする。
つまり、背景は白で文字が黒になるように画像を加工する。

これをHTML5canvas APIを使って、1ピクセル単位でごりごりやっている。

ずばっとOCRできたときは気持ちいい感じだけど、失敗したときには結局手直ししなきゃいけないのが面倒。
OCR対象の文字の色を教えるために、画像内の文字をクリックする必要があるのだけど、対象文字が小さいとクリックしづらい。

とか問題が多くあって、OCR精度上げるのは難易度が高いけど、このあたりのUX改善させる余地はまだまだありそう。

西日暮里.rbでSprocketsを捨てたいという内容のLTをした

西日暮里.rbの1周年記念LT大会でSprocketsを捨てたいというLTをさせてもらった。

かれこれ2週間ぐらい前の話。ただでピザ食べられて、ビールも飲めて、ほんと最高だった。

資料

www.slideshare.net

今回資料結構詳しく書いた(発表する時間が全然足りなかった。。反省。)ので、内容は置いといて気持ちを中心に追記する。

Sprocketsを捨てたいという気持ちについて

最近のフロントエンド衰勢はほんとに早い。
気を抜くとすぐ「まだxxで消耗してるの??」と言われて、むきー!となる。

あと煽り属性強めな人多い。(それはそれでいいところ、というか僕は好き。でもある程度の煽り耐性必要。)

そんな環境の中でSprocketsというのは、はっきりいってしまえば邪魔。

reactを使うためには、react-railsを使わなければいけない?
browserifyを使うために、browserify-railsを使わなければいけない?

そんな世界はもういやだ!

このruby gems達は果たして、常に最新を追っていけるのか。
reactやbrowserifyならば、今は人気もあって、メンテしていくモチベーションもあるだろう。
しかし、それがどこまで続くのかは保証がない。

ライブラリが廃れても、今走っているプロダクトは止まれない。
好きなライブラリを使う!という意思表示は、プロポーズと似ている。

一度選んだからには、真摯に付き合わなくてはならない。(とはいえ移行計画は進めつつ。。)

例えgemは最新を追っていたとしても、依存関係のあるgemやRailsのバージョンなどが、なんらかの事情ですぐに最新にあげるのが難しい場合もあるだろう。

Railsのバージョンとgemのバージョンが合わなくて最新ライブラリ使えません。 ><

そんなハメには陥りたくないんです!!

という気持ち。

資料の最後に書いた課題について

以下の3つが課題かなー、と資料に書いた。

  1. 移行するにあたってSprocketsの付与しているmd5フィンガープリントをどうするか
  2. Sprocketsのrequireディレクティブをどうやって撲滅するか
  3. gemにassetsが含まれているやつらの対処

その後の展望的なものを備忘録的に記す。

移行するにあたってSprocketsの付与しているmd5フィンガープリントをどうするか

もちろんgulpタスクでファイルの末尾に何らかの文字列を付与するのは簡単。

なんだけど、それを愚直にやってしまうと、Railsのasset_pathヘルパーメソッドが効かなくなるという問題が発生する。

会社でこれ問題だなーって話してたら、先輩とか同僚とかに色々アイディアもらった。
「筋がいいなー、これがいいなー」と思ったのは、gulpでビルドした時に付与した文字列を一旦どこかに出力しておいて、それをRailsが見に行くようにするというアイディア。

この仕組み作れればこれはなんとかなりそう。今度asset_pathメソッドの仕組み読んでみて、実装を模索しよう。

Sprocketsのrequireディレクティブをどうやって撲滅するか

Sprocketsのrequireディレクティブとbrowserifyのrequireは共存できない。
Sprocketsのrequireディレクティブが存在する状態でbrowserifyかけると、Sprocketsのrequireディレクティブは死ぬ。

これを解決するためには、browserify-railsを使うか、単純にファイル単位で置き換えて、置き換えできたものにだけbrowserifyをかければ良い。

ファイル単位に置き換えていくのはつらい作業だけど、xxxx-railsなgemは使いたくない。必要なのは気合いと根性だ。

gemにassetsが含まれているやつら

jsライブラリなら殆どはnpmにあるので困らないと思う。 だけどviewをgenerateする機能があって、styleもあててるようなやつはどうするか。 (管理画面作る系のgemにありがちな気がする。。)

資料にも書いたけど、そのgemやめるのが近道。それかそのgemのassetsだけリポジトリにコミットして管理する荊の道を歩くか。

Sprockets完全撤廃にこだわらないのであれば、この解決だけSprocketsでもいいかも。

最後に

西日暮里.rb、1周年ほんとにおめでとうございます!