よくないねボタン0.1 ~ReactからVueへ、そしてFluxの消失~

よくないね いいね ポエム
0 Comments
Tweet

よくないねボタン - Poem
よくないよ。こんなこと
大好評をいただいているよくないねボタンですが、おかげさまで512よくないねを達成しました:tada:
それを記念して、大幅にちょっとだけ変更を加えました。バージョン:0.0.4⇒0.1.0
変更点をご紹介します!

RFC 7807に対応した

めちゃくちゃどうでもいいことですが、エラー表現をRFC 7807に対応させました。エラーなんて見る人いないと思いますが、ちゃんとContent-Typeはapplication/problem+jsonになっています。

ReactからVue.jsに乗り換えた

だいたいここに書いてあることに共感したためです。
私たちはなぜReactではなくVue.jsを選んだのか | プログラミング | POSTD

忌まわしきJSX

.

必要な道具が多すぎる

React+ReduxからVue+Vuexに乗り換えました。

利点1:トランスパイルいらず

トランスパイルとかうんざり。そもそもこんなミクロなプロダクトにReactはデカすぎた。

利点2:コード量の減少

Reactですべてがすべて出来上がっているページではなく、拡張機能としてページに対してコードをインジェクトしているため、どうしてもDOM操作が絡んできます。その都合上、Reactのクリーンな設計を前にしても、document.querySelectorでごちゃごちゃ弄っている部分が多くありました。
Reactでは、仮想DOM1(?)で作られたCoolな要素をインジェクションするためのdivラッパーを挿入したり、各コンポーネントに分けたクラスをrenderしたりするためにコンポーネントの定義とは別に追加で多く書く必要があったりしていました。

対してVueではコンポーネントの定義と同時にelオプションでマウントする要素を指定でき、1つのコンポーネントで記述量が減りました。
全体のコード記述量も減り、Reactで各コンポーネントに分かれたjsxファイルとindex.jsファイルの累計コード行数が200行を超えていたのに対し、VueではCommonJSを意識しなくしてindex.jsファイルのみに収め、160行程度になりました。
トランスパイル後のReactで書いたものが20000行を超えていたのに対し、Vueのほうはというと、vue.jsとvuex.jsとindex.jsの行数を足し合わせても10000と数百行になりました。

Fluxモデルをやめた

React+ReduxからVue+Vuexに移行したものの、Reduxの時と変わらずFluxストアに対する値の操作がとてもめんどくさいものでした。Fluxストアに対してdispatchする日々は変わらず、そもそも大げさにState管理をするほどでもないことに気付いたのでFluxやめました。ReduxでsetStateばかり書いてあるコード見るのも辛いしね。
そもそもなんでステート管理をしていたかというと、各コンポーネント間でよくないねの状態を共有する必要があったからでした。

digraph G {
	graph [
	layout=neato
	];
	edge [
	labelfloat=false
	];
	"Store" [shape=doublecircle];
	"LikeButton" [shape=box];
	"Label" -> "Store" [label="count", style=dotted ,len=2];
	"Button" -> "Store" [label="diasliked", labelfloat=false, len=2, labelloc="t", labeljust="r"];
	"Button" -> "Store" [label="liked", style=dotted, len=2];
	"Warning" -> "Store" [label="count >= 2, style=dotted, len=2];
	"LikeButton" -> "Store" [label="liked", len=2];
	"LikeButton" -> "Store" [label="disliked", style=dotted, len=2];
}

Vueは全体の状態の値の変化を即座にキャッチしてくれるので、ReduxのsubscribeやgetStateを必要としません。
そのため、Fluxによる管理をやめて、値を最も多く扱うコンポーネントに値を保持させ、それを他のコンポーネントから参照させる形にしました。

digraph G {
	graph [
	layout=fdp
	];
	edge [
	labelfloat=false
	];
	"LikeButton" [shape=box];
	"Button" [xlabel="liked, disliked"];
	"Label" [xlabel="count"];
	"Warning" -> "Label" [label="count", style=dotted, len=2];
	"Button" -> "Label" [label="count", len=2];
	"LikeButton" -> "Button" [label="liked", len=2];
	"LikeButton" -> "Button" [label="disliked", style=dotted, len=2];
}

これでVuexとはおさらば、さらにコード記述量が減り、140行程度まで小さくなりました。vue.jsとindex.jsを合わせても10000行にも満たなくなりました。

Vue.jsのセキュリティ上の懸念点

Vueは便利に書ける反面、セキュリティ上の懸念点が少々あります。よくないねの設定ページもVueで記述していたのですが、最初は動かなくてとても困っていました。いろいろ調べていると原因はCSPでした。
Content Security Policy (CSP) - Google Chrome
Chrome拡張機能はデフォルトでscript-src 'self'; object-src 'self'のポリシーが割り当てられています。しかし、VueJSはテンプレートのコンパイルにnew Function()を用いているようです。
インストール CSP 環境 - Vue.js
この問題を解決するために、CSPを変更して安全でない評価関数の実行を有効にしてあげる必要がありました。これにより、悪意のあるコードが設定ページに注入されることが万が一にでもあった場合、その攻撃を受けてしまう可能性が微粒子レベルで上昇してしまいました。
まぁそこまで気にすることではないんですがね。

ポップアップメニューを追加してよくないね総数を確認できようにした

よくないね総数を確認して世のよくない記事の数を聢と見よ。

Semantic UIやめてUIKit3にした

そもそもどこでそんなUIがあったのか気づいてない人多いと思いますが、設定ページのUIがそれです。
Semantic UI使ってた理由がReactコンポーネントとして使えてたからってたけなので、UIKit3(beta)に変えました。UIKitは昔と比べて見た目が良くなってきましたね。

よくないねページから直接インストールできるようにした

よくないね総数が見られるyokunaine.mzyy94.comのページから拡張機能をダウンロードできるようにしました。Inline installationを試してみたかったので。
Chrome Extension inline installationの使い方 - Qiita

おしまい

なんかいっぱい書こうと思ったけど疲れたのでおしまい。前回予告していたyokunaineの実装に関するGoodな点の話はいろいろと語り尽くされてる感じがして書くのめんどくさいのでコードみて確認してください。