plugin作りたくて色々中身見たり、そもそもどうなってんのみたいな興味本位で読み解いたらreduxの使い方とかちょいちょい面白かったので感想とか雑感
コードはversion 0.6 ~ 7.1らへん。
https://github.com/zeit/hyperterm/tree/v0.7.1
全体感
- Coreな所
- Electron
- おなじみ
 
 - hterm
- chromiumのプロダクトの一つ(?)
 - コードはこのあたり
- あんまりこっちは追ってない
 
 
 
 - Electron
 - Electronの中で使われてる技術要素
- React + Redux
 - CSS in JS
 - ビルドにwebpack
 
 
プロジェクト構成など
- 
/(root)- webpackで管理している部分
 - libに関連するpackageはroot管理
 
 - 
/lib- hypertermの本体部分。
 - React + Reduxなプロダクト
 - plugin作るときとかこのへん見るパターンが多くなる
 
 - 
/app- 
/lib以外の色々 - 
electronに関連する部分とか
- menuとかpluginとかindex.htmlとかnotify.htmlとか。 - plugin関連だったりconfig関連だったり。
 - libとは独立的にpackage.jsonを管理している。
 - 起動時には
$ electron app的な事で起動している 
 - 
 - 
/assets,/build- assetだったりelectron用のアイコンだったり
 
 
Code
hterm
- そもそもterminalどうやってんだよ?という所の回答が
htermというのを使ってるというやつ(前述通り)- 
hypertermでは下記らへんでhtermが絡んでいる
- components/term.js
- React的なComponentとhtermを繋いでる箇所
- htermへの設定追加なども行っているっぽい- 
lib/term.js
- htermそのままでは動かない部分をprototype継承でパッチしたりしている。 
 - 
lib/term.js
 
 
reduxまわり
結構おもしろいと思った。
actionとeffect-middleware
redux-thunkを使っているので、関数を返して非同期処理をしている。
ちょっと面白いと思ったのがeffectというパラメータ
export function someAction (uid) {
  return (dispatch, getState) => {
    dispatch({
      type: SOME_TYPE,
      value,
      effect () {
        dispatch(otherAction(uid));
      }
    });
  };
}
これをeffectというmiddlewareで、色々処理した後に実行している。
middleware
index.jsを見ると、thunk -> plugin.middleware -> thunk -> effectとやっている。
thunk二回やってるのは何か辛そうなものを感じる。
pluginは、名の通りpluginが仕掛けるmiddleware。
Reducerらへん
- 
seamless-immutableでimmutable化してる
- ArrayとかObject準拠なimmutable library?
 
 - terminalのセッションの管理には
uuidが使われている- reducerでよく追加するものがある場合に
nextId的なもので管理することとかあるけど、uuid使う方が良さそう 
 - reducerでよく追加するものがある場合に
 
Container色々
- ReduxとReact繋いでるところ。
 - dispatchを利用するhandler関数はContainerレイヤーで作って、viewにはdispatchを意識させないようにしているらしい
 - reslectはcontainers/header.jsでのみつかわれている。
- 若干のノリで入れてみたんじゃないだろうか感も感じてしまう
 - reselectorとcontainerを同じファイルに書くのは結構アリかも
 
 - 各Container
- Hyperterm
- いわゆるメイン
- キーバインドとかしてある - HeaderContainer
- ヘッダ部分(タブとか) - NotificationContainer
- Notification関連
- Electronのnotificationではなく、hyperterm内部のnotification。 - TermsContainer
- Terminal関連Container 
 - Hyperterm
 
React関連
Component
- hypertermで利用されているComponentは、ReactのComponentを直で使うのではなく、一つ独自にComponentを作ってwrapしている
 - PureRenderMixinを利用している
 - ほぼCSS in JSの為という印象
 - コンポーネントは
renderではなく、templateメソッドに、Virtual DOMを記載する - 
renderは、CSSとtemplateのvdomを組み合わせる役割をするようになっている - pluginを作る時は、この辺りの勘所注意だろう
 
CSS in JS
- jsonなconfigで色設定などをできるようにしている都合もあるのだろう、CSS in JSを行っている。
 - 利用しているのはaphroditeというライブラリ
- 実際にはaphrodite-simpleというforkしたっぽいライブラリを使ってるようだが、コードが見当たらないので正確な違いはわからに
 
 
Component細かく
ほぼContainerと対をなしている感じ。
- header, tab, tabs
- terminal上方のTab周り
 - 
header > tabs > tabみたいな構成 
 - notification, notifications
- あんまりちゃんと見てない
 
 - term, terms
- terminal表示部分。
 - 
term.jsが
htermと直接連携している(前述通り) - termsの
this.terms
- 子termの管理として、this.termを管理してる
- 中身はhtermのインスタンスでpureなobjectではない
- stateやreduxのstateではなく、Componentのpropertyでの管理しているのは、多分pureなObjectじゃないから扱いづらいとかそういう感じに見える 
 
plugin
- app/plugins.jsに、hook出来そうなplugin列挙されている
 - ドキュメントが整備されている感じではないので、何出来るかは気持ちを察していくしかない
 
decorate
- pluginがhypertermに行う加工に関して、
decoratorとかdecorateとか名前付けられている - Componentなどを覗いたりしても、ちょこちょここの
Decorateという話が出てくる。- Componentのdecorateは、いわゆるHocsっぽい形になっている。
 
 - plugin側で色々拡張させるための工夫っぽい
- うまく作ってないと途端にやばくなりそうではあるワイルドさを感じる
 
 - objectのdecorateは単に
Object.assignで拡張される感じ 
rpc
- htermとelectronとhypertermの命令疎通をしている。
 - 
electron <-> rpc <-> redux(action)という感じの双方向な通信 - EventEmitter
 - このへん
 
config
app/session
- ptyとかttyとかあんまり詳しくないので利害が微妙。
 - 結局shellのタイトルを表示するために実行中のプロセスのコマンドを取得しているように見える
 - titleを定期的に取得してemitしている。
 - 使っているのはこのあたりのパッケージ