LoginSignup
27
28

More than 5 years have passed since last update.

hyperterm読コード感想文

Last updated at Posted at 2016-07-28

hyperなterm

plugin作りたくて色々中身見たり、そもそもどうなってんのみたいな興味本位で読み解いたらreduxの使い方とかちょいちょい面白かったので感想とか雑感
コードはversion 0.6 ~ 7.1らへん。
https://github.com/zeit/hyperterm/tree/v0.7.1

全体感

  • Coreな所
    • Electron
    • おなじみ
    • hterm
    • chromiumのプロダクトの一つ(?)
    • コードはこのあたり
      • あんまりこっちは追ってない
  • 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というのを使ってるというやつ(前述通り)

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使う方が良さそう

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

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.jshtermと直接連携している(前述通り)
    • 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

config

  • gazeはfs.watchのwrapper。
    • 更新監視してるっぽい
  • configファイルの評価はrequestだとかJSON.stringifyではなくvm.Scriptとからへんを使っている模様

app/session

  • ptyとかttyとかあんまり詳しくないので利害が微妙。
  • 結局shellのタイトルを表示するために実行中のプロセスのコマンドを取得しているように見える
  • titleを定期的に取得してemitしている。
  • 使っているのはこのあたりのパッケージ
27
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
28