Elixir OSSハック①【Livebook①】：LiveViewフロントデバッグを使って易々とLivebookを改造

この記事は、[Elixir Advent Calendar 2023 シリーズ12](https://qiita.com/advent-calendar/2023/elixir) の13日目です

---

[piacere](https://twitter.com/piacere_ex) です、ご覧いただいてありがとございます :bow:

今回は、下記を追体験いただく … つまり「OSSの改造をする」コラムです

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">たった1時間の短時間で、<br><br>・Livebookホーム画面<br>・ユーザー設定<br>・セッション（起動されたNotebookのこと）<br>・コードエディタ部分<br>・コード実行部分<br><br>のハックや改造ができました😆 <a href="https://twitter.com/hashtag/LiveViewJP?src=hash&amp;ref_src=twsrc%5Etfw">#LiveViewJP</a><br><br>今回、初めてLivebookハックしてみましたが、いつものElixirらしく読みやすいコードでハッピーでした😍 <a href="https://t.co/EhohlbKTmA">pic.twitter.com/EhohlbKTmA</a></p>&mdash; piacere @ Elixir／D2C／xR＋メイドコスプレでデジタルから現実改変する49歳 (@piacere_ex) <a href="https://twitter.com/piacere_ex/status/1706658075321704577?ref_src=twsrc%5Etfw">September 26, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

昨年／今年のElixir界隈と、Elixir Advent Calendarを賑わす、高機能Web開発環境「Livebook」ですが、OSSなので、当然ソースコードは読める訳です

しかし、素晴らしいWeb上開発体験を提供しているからこそ、複雑そうに思われるコードを読む気は、なかなか高まらないですよね？

そこで、みんなでコードを眺めて、震えて、納涼するというイベントを[LiveViewJP#21「Livebookコードを眺めてみんなで震えて納涼する会」](https://liveviewjp.connpass.com/event/294500/)で、今年9月に開催しました

https://liveviewjp.connpass.com/event/294500/

ちな、私もマトモにLivebookコードを読んだことが無かったので、会が成立しない位、グダグダになったらゴメンナサイ … と予め謝った上で開催しました 😋

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">来月の <a href="https://twitter.com/hashtag/LiveViewJP?src=hash&amp;ref_src=twsrc%5Etfw">#LiveViewJP</a> は、Elixirに素晴らしいWeb上開発体験を提供している「Livebook」のコードハック会😜<a href="https://t.co/tlHSq67Wmg">https://t.co/tlHSq67Wmg</a><br><br>みんなでコードを眺めて、震えて、納涼しましょう🤣<br><br>ちな私もマトモに読んだこと無いので、会が成立しない位、グダグダになったらゴメンナサイ…と予め謝っておく😋</p>&mdash; piacere @ Elixir／D2C／xR＋メイドコスプレでデジタルから現実改変する49歳 (@piacere_ex) <a href="https://twitter.com/piacere_ex/status/1694957213415333990?ref_src=twsrc%5Etfw">August 25, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ですが結果的には、新たなLiveViewデバッグ機能も使い倒す、ステキなElixir printfデバッグ（正確にはIO.inspectだがｗ）のシェア会になりましたので、その一端をコラムでも共有します

あと、このコラムが、面白かったり、役に立ったら、![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/907a8695-4d83-1b5c-8052-d0ce52de5f66.png) をお願いします :bow:

# 事前準備：Livebookのgit clone

Livebookのソースコードは、下記GitHubにあります

https://github.com/livebook-dev/livebook.git

まず、これをgit cloneで落としてきます

```bash
$ git clone https://github.com/livebook-dev/livebook.git
```

VSCodeで開きます（別に他のエディタでもOKです）

```bash
$ cd livebook
$ code . -r
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/e0ca25ed-476f-897d-fce6-8b7ccb73ad21.png)

# Livebookのファイル内訳

下記コマンドでLivebookコードのファイル数をカウントすると、880件（バージョンはLivebook 0.12.0-dev、2023/12/14現在）もあるようです（なお、mix desp.getを先にやると数が変わるので、その前に実施）

```bash
$ find -type f | grep -v "^./.git/" | grep -v "^./.github/" | wc -l
880
```

うち、Elixirコードであるlib配下は27%程度のようで、うち.exファイルが大半を占め、残りは.livemdと.jpegのようです

```bash
$ find -type f | grep "^./lib/" | wc -l
238

$ find -type f | grep "^./lib/" | grep ".ex$" | wc -l
226

$ find -type f | grep "^./lib/" | grep -v ".ex$"
./lib/livebook/notebook/learn/intro_to_vega_lite.livemd
./lib/livebook/notebook/learn/kino/custom_kinos.livemd
./lib/livebook/notebook/learn/kino/intro_to_kino.livemd
./lib/livebook/notebook/learn/kino/smart_cells.livemd
./lib/livebook/notebook/learn/kino/vm_introspection.livemd
./lib/livebook/notebook/learn/deploy_apps.livemd
./lib/livebook/notebook/learn/distributed_portals_with_elixir.livemd
./lib/livebook/notebook/learn/intro_to_maplibre.livemd
./lib/livebook/notebook/learn/intro_to_explorer.livemd
./lib/livebook/notebook/learn/intro_to_livebook.livemd
./lib/livebook/notebook/learn/files/portal-list.jpeg
./lib/livebook/notebook/learn/files/portal-drop.jpeg
```

その他のファイルは、下記の割合のようです

```bash
$ find -type f | grep "^./assets/" | wc -l
77
$ find -type f | grep "^./assets/" | grep ".js$" | wc -l
63
$ find -type f | grep "^./assets/" | grep -v ".js$"
./assets/package-lock.json
./assets/.babelrc
./assets/package.json
./assets/css/components.css
./assets/css/global.css
./assets/css/tooltips.css
./assets/css/notebook.css
./assets/css/editor.css
./assets/css/live_view.css
./assets/css/markdown.css
./assets/css/js_interop.css
./assets/css/app.css
./assets/css/utilities.css
./assets/css/ansi.css
```

# Livebookを起動

下記コマンドでLivebookを起動します

```bash
$ mix deps.get
$ MIX_ENV=prod iex -S mix phx.server
…
==> livebook
Compiling 239 files (.ex)
Generated livebook app
[Livebook] Application running at http://localhost:8080/?token=pleguigyspnkwph5thoxi2ul3w5ywgix
Erlang/OTP 26 [erts-14.1.1] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.7) - press Ctrl+C to exit (type h() ENTER for help)
iex(livebook_xxxxxxx)1>
```

上記の末尾の方に出てきたURLをブラウザで開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/d95984e9-1d52-22c3-8e6a-6b3f1d11c2f8.png)

# LiveViewフロントデバッグ機能でLivebookコードをブラウザ上から特定

いきなりコード実行画面（下記）から行くと、脱落しやすそうなので、手慣れをする意味でも、大して面白くない（笑）ホーム画面から始めてみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/1c6b7b79-95f6-1a77-cd2c-0afdcd3c4e82.png)

LiveView 0.20から、LiveViewコードやLiveComponentsをフロントデバッグできる機能が入ったので、早速これを有効活用してみます

[LiveViewJP#21「Livebookコードを眺めてみんなで震えて納涼する会」](https://liveviewjp.connpass.com/event/294500/)イベント開催当時は、LiveView 0.20がリリースされて3日後（！）だったので、LivebookにLiveView 0.20が梱包されておらず、自身で `mix.exs` の `deps` に追加する必要がありましたが、今ならLivebookに勝手に入ります

https://twitter.com/piacere_ex/status/1705469187047694374

フロントデバッグの設定を、下記の通り、入れてみてください

```diff_elixir:config/config.exs
import Config
…
import_config "#{Mix.env()}.exs"
+
+config :phoenix_live_view, :debug_heex_annotations, true
```

Ctrl-Cを2回押した後、再度ビルドします（LivebookのURLが変わるのでブラウザに再度、入力し直します）

```bash
$ MIX_ENV=prod iex -S mix phx.server
```

ブラウザ上で、「RUNNING SESSIONS」で右クリックし、「検証」を選択すると、下部にブラウザのデバッガペインが表示され、HTMLコメントでLiveViewコードのファイル名と行番号が表示されるようになるのが、LiveView 0.20で入ったフロントデバッグです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/707de495-e234-f762-f492-5a571f958669.png)

実際に、該当ファイルとその行番号を見てみると、render関数の先頭行が特定できました … つまり、この部分は[LiveComponent](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveComponent.html)で構成されているということが分かります（まぁ、ファイル名からもお察しですがw）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/88d3d50a-085b-5666-c86c-60c194d21a62.png)

試しに、「Running sessions」の文言を変えてみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/932746c4-9787-05b7-5530-b79c5754fdbf.png)

Livebookを起動したターミナルでiexが起動しているので、下記で再コンパイルし、ブラウザをリロードしてみましょう

```bash
iex> recompile
```

下図の通り、Livebookを改造することができました :tada:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/710ac4ba-bcb8-e5ed-602c-0a66832870fb.png)

試しに、右上の「New notebook」から幾つかセッションを追加してみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/3f0a470c-0ac3-cc47-88e9-21891e28cb56.png)

すると、下図の通り、日本語メッセージでセッション数を表示してくれます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/b4b82f45-7676-c368-803c-3ce3c932fe1d.png)

# 終わりに

複雑なOSSも、デバッグのテクニック次第で易々と改造していけることが伝わったでしょうか？

ポイントは、Livebookと言えど、所詮、「LiveViewアプリの1つ」に過ぎないので、LiveViewやLiveComponentsの構造を把握していればハックしていけるという、たったそれだけのことです

[次回は、Livebookコードブロックの実行付近を攻略していきます](https://qiita.com/piacerex/items/a4e86c810fb3c45a71ae)

# p.s.このコラムが、面白かったり、役に立ったら…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/907a8695-4d83-1b5c-8052-d0ce52de5f66.png) にて、どうぞ応援よろしくお願いします :bow: