Open37

『[作って学ぶ]ブラウザのしくみ──HTTP、HTML、CSS、JavaScriptの裏側』写経記録

awayatakumaawayatakuma

環境

            .-/+oossssoo+/-.               awawa@DESKTOP-T1C0N93
        `:+ssssssssssssssssss+:`           ---------------------
      -+ssssssssssssssssssyyssss+-         OS: Ubuntu 22.04.4 LTS on Windows 10 x86_64
    .ossssssssssssssssssdMMMNysssso.       Kernel: 5.15.153.1-microsoft-standard-WSL2
   /ssssssssssshdmmNNmmyNMMMMhssssss/      Uptime: 16 mins
  +ssssssssshmydMMMMMMMNddddyssssssss+     Packages: 1025 (dpkg), 6 (snap)
 /sssssssshNMMMyhhyyyyhmNMMMNhssssssss/    Shell: zsh 5.8.1
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Theme: Adwaita [GTK3]
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   Icons: Adwaita [GTK3]
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   Terminal: Windows Terminal
ossyNMMMNyMMhsssssssssssssshmmmhssssssso   CPU: Intel i7-14700KF (28) @ 3.417GHz
+sssshhhyNMMNyssssssssssssyNMMMysssssss+   GPU: 5871:00:00.0 Microsoft Corporation Device 008e
.ssssssssdMMMNhsssssssssshNMMMdssssssss.   Memory: 1896MiB / 15906MiB
 /sssssssshNMMMyhhyyyyhdNMMMNhssssssss/
  +sssssssssdmydMMMMMMMMddddyssssssss+
   /ssssssssssshdmNNNNmyNMMMMhssssss/
    .ossssssssssssssssssdMMMNysssso.
      -+sssssssssssssssssyyyssss+-
        `:+ssssssssssssssssss+:`
            .-/+oossssoo+/-.

WSL上にたててるよ

➜ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
awayatakumaawayatakuma

ch0

awayatakumaawayatakuma

p.xでエラー

error[E0463]: can't find crate for `core`
 --> /home/awawa/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/micromath-2.1.0/src/float/log2.rs:4:5
  |
4 | use core::f32::consts::LOG2_E;
  |     ^^^^ can't find crate
  |
  = note: the `x86_64-unknown-none` target may not be installed
  = help: consider downloading the target with `rustup target add x86_64-unknown-none`
  = help: consider building the standard library from source with `cargo build -Zbuild-std`
awayatakumaawayatakuma

ごちゃごちゃやってたらなおった
以下が効いてたっぽい

rustup target add x86_64-unknown-none
awayatakumaawayatakuma

うーん...
Timeoutエラーが発生してるっぽい
pingは通るけど...
一旦放置でええんかこれ

dns: Some(8.8.8.8)
[INFO]  os/src/cmd.rs:54 :  Executing cmd: ["wait_until_dns_ready"]
[INFO]  os/src/cmd.rs:90 :  DNS server address is set up! ip = 8.8.8.8
[INFO]  os/src/cmd.rs:54 :  Executing cmd: ["nslookup", "example.com"]
[WARN]  os/src/net/manager.rs:429:  No route to 8.8.8.8. Sending ARP from all the interfaces.
[ERROR] os/src/main.rs:147:  Failed("Timed out")
[INFO]  os/src/executor.rs:147:  Task completed: Task(os/src/main.rs:210): Ok(())
awayatakumaawayatakuma

よく書籍をみてみると、ここエラー発生するっぽい
あと書籍再現するために、コンソール上でsabaを送る必要があった

awayatakumaawayatakuma

OSの方の書籍はまだ発売されてなかった...
2025年発売らしい

awayatakumaawayatakuma

ch2

awayatakumaawayatakuma
    fn test_url_host_path_searchquery() {
        let url = "http://example.com:8888/index.html?a=123&b= 456".to_string();
        let expected = Ok(Url {
            url: url.clone(),
            host: "example.com".to_string(),
            port: "8888".to_string(),
            path: "index.html".to_string(),
            searchpart: "a=123&b=456".to_string(),
        });
        assert_eq!(expected, Url::new(url).parse())
    }

"http://example.com:8888/index.html?a=123&b=456"の誤りか?書籍の体裁の違いな気がする

awayatakumaawayatakuma

ch3

awayatakumaawayatakuma

特につまったポイントなし(自分のコードのタイポがあったくらい)
改めてブラウザといえども、単なるjavascriptのランタイムの上で動くGUIなのだということが肌身にしみてくる

awayatakumaawayatakuma

ch4 html解析

awayatakumaawayatakuma

黙々と写経しているが、やっぱり写経だとアルゴリズムの理解にはつながらないなと気づいた
だから〇〇作ってみた系の教材では写経はあまり効果的な勉強方法ではないのかもしれない
逆に新しく言語を学ぶなど手になじませる系だと効果的な気がします

awayatakumaawayatakuma

だからメモをリアルタイムで取る必要があるんですねぇ~

awayatakumaawayatakuma

ユニットテスト書いてあるの助かる
2つめで早速頓挫した🫠

awayatakumaawayatakuma

テストでパニック起きる
もう少し細かい粒度でテストを書いてもらえるとう嬉しいが、書面の都合上無理か...

awayatakumaawayatakuma

ステートマシン自体は美しくて好きだが、バグ取りがめんどくさいのいつも苦しめられてる気がしてきました

awayatakumaawayatakuma

ステート(状態)のマシンだから単体テストがやりにくいのは当然か

awayatakumaawayatakuma

最後のブラウザでの検証でpanicが発生

netmask: Some(255.255.255.0)
router: Some(10.0.2.2)
dns: Some(8.8.8.8)
[INFO]  os/src/cmd.rs:58 :  Executing cmd: ["wait_until_dns_ready"]
[INFO]  os/src/cmd.rs:94 :  DNS server address is set up! ip = 8.8.8.8
[INFO]  os/src/executor.rs:147:  Task completed: Task(os/src/main.rs:211): Ok(())
saba
[INFO]  os/src/cmd.rs:58 :  Executing cmd: ["saba"]
PANIC!!!
panicked at /home/awawa/.local/share/cargo/git/checkouts/wasabi-03f40552360a1354/54bff89/noli/src/sys/wasabi.rs:62:5:
allocation error: Layout { size: 104, align: 8 (1 << 3) }
[INFO]  os/src/cm
awayatakumaawayatakuma

main.rsのうち、let dom_string = page.borrow_mut().receive_response(response);をコメントアウトしたら正常終了

awayatakumaawayatakuma

入力から以下を消したら一部出た

  <h1 id="title">H1 title</h1>
  <h2 class="class">H2 title</h2>
  <p>Test text.</p>
  <p>
    <a href="example.com">Link1</a>
    <a href="example.com">Link2</a>
  </p>

十中八九コーディングミスだ...(´;ω;`)

awayatakumaawayatakuma

普通に実装が漏れてた

                InsertionMode::InBody => match token {
                    Some(HtmlToken::StartTag {
                        ref tag,
                        self_closing: _,
                        ref attributes,
                    }) => match tag.as_str() {
                        "p" => {
                            self.insert_element(tag, attributes.to_vec());
                            token = self.t.next();
                            continue;
                        }
                        "h1" | "h2" => {
                            self.insert_element(tag, attributes.to_vec());
                            token = self.t.next(); // ←これがなかった
                            continue;
                        }
                        "a" => {
                            self.insert_element(tag, attributes.to_vec());
                            token = self.t.next();
                            continue;
                        }