CURRICULUM  /  LAYER 01  /  CHAPTER 07

読む道具と構え

6章かけて、HTMLからSQLまでの登場人物を一通り眺めてきました。

この最終章は、本を閉じる前のひとときです。

「読む」ためにあなたの手元に置いておくべき3つの道具と、読み手としての構えについて話します。

読むには、道具がいる

本を読むには眼鏡がいります。

料理をするには包丁がいります。

コードを読むにも、同じく専用の道具があります。

初心者の多くは、これを知らないまま「コードが読めない」と悩んでいますが、道具を手にした瞬間、視界が一変します。

この章で紹介するのは3つ。

ディベロッパーツールファイルとパスの感覚、そしてエラーメッセージとの付き合い方

どれも地味ですが、これらが身に付いているかどうかで、同じコードから受け取れる情報量がまったく違ってきます。

道具その1 ─ ディベロッパーツール

あなたが今、このページを開いているブラウザには、実はプロフェッショナル向けの解析ツールが最初から組み込まれています。

ほとんどの人は知らずに過ごしていますが、これを使えるか使えないかで、ウェブの理解度が一段変わります。

開き方は簡単です。

すると、画面の右側か下側に、何やらごちゃごちゃした画面が現れます。

これがディベロッパーツール(略してDevTools)です。

最初は戸惑いますが、特によく使うのは次の3つのタブだけです。

Elements タブ ─ HTMLとCSSをその場で覗く

Elementsタブを開くと、今表示されているページのHTMLの構造が丸見えになります。

しかも、HTMLのどこかをクリックすると、ページ上のその要素がハイライトされ、さらに右側にはその要素に当たっているCSSが全部表示されます。

これが何を意味するか、分かりますか?

「このサイトのこの見出し、なんでこんな色なんだろう?」と思ったら、Elementsで見出しをクリックするだけで、どのCSSが、どのファイルの何行目から、どう効いているかが一目で分かるのです。

世界中のあらゆるウェブサイトが、あなたにとっての「生きた教材」になります。

— Try it

今このページで、試しにF12を押してElementsタブを開いてみてください。

画面上の「読む道具と構え」という見出しをクリックすると、右側に .lesson__title というクラスに対するCSSが表示されるはずです。

そこで color の値をダブルクリックして、別の色に書き換えてみましょう。

見出しの色がリアルタイムで変わります(リロードすると元に戻ります)。

さらに、Elementsタブ上でHTMLを直接編集することもできます。

もちろんそれは「あなたのブラウザの中だけ」の変更で、サーバー側のファイルは何も変わりませんが、「もしここのタグをこう変えたらどうなるか」を試せるサンドボックスとして最強です。

Console タブ ─ JavaScriptの声を聞く場所

Consoleタブは、JavaScriptとあなたとの対話窓口です。

ここには主に2種類のものが表示されます。

一つは、JavaScriptが何かに失敗したときのエラーメッセージ

ページを開いて「なんか動きがおかしいな」と思ったら、まずConsoleを見ます。

赤いメッセージが出ていたら、そこに原因が書かれています。

もう一つは、前章までに何度か出てきた console.log(...) の出力先。

コードの途中に console.log(変数名) と書いておくと、その時点で変数に何が入っているかを、Consoleで確認できます。

これがデバッグの基本のキです。

const price = 1000;
const tax   = 0.1;
const total = price * (1 + tax);

console.log(total);  // Consoleに 1100 と表示される

Consoleにはもう一つ隠された使い方があります。

タブそのものにJavaScriptを直接打ち込めるのです。

1 + 1 と打ってEnterを押せば 2 と返ってきますし、今開いているページのJavaScript変数を直接参照することもできます。

電卓代わりにも、実験場にも使えます。

Network タブ ─ ブラウザとサーバーの会話を覗く

01-01で「ウェブはブラウザとサーバーの会話でできている」と話したのを覚えていますか? Networkタブは、その会話の中身を実際に覗ける盗聴器のようなものです。

タブを開いた状態でページをリロードすると、そのページを表示するためにブラウザがサーバーに送った全てのリクエストと、サーバーから返ってきた全てのレスポンスが一覧で表示されます。

HTMLファイル、CSSファイル、画像、JavaScriptファイル、それぞれいつ、どんな順序で、どれくらいの時間で読み込まれたか、丸見えです。

最初のうちは「ふーん」で通り過ぎるだけで構いません。

でも、後でLayer 02やLayer 03に進んだとき、「フォーム送信で何を送っているか確認したい」「APIが正しい値を返しているか見たい」という場面が必ず来ます。

そのときにNetworkタブの存在を思い出せるかどうかで、問題解決の速度が何倍も違ってきます。

— Note

ディベロッパーツールは、最初は「情報量が多すぎて怖い」と感じるかもしれません。

でも、使うのは本当にElements・Console・Networkの3つだけで十分です。

他のタブ(Sources、Performance、Applicationなど)は、必要になったときに少しずつ覚えれば大丈夫です。

欲張らないこと。

道具その2 ─ ファイルとパスの感覚

次は、もう少し地味だけど、初心者が最もつまずく場所の話です。

「CSSファイルを作ったのに、HTMLに反映されない」 「画像が表示されない」 「リンクをクリックしても404エラーになる」

これらの原因のほとんどは、実はパスの書き方の間違いです。

コードは正しいのに、ファイルの場所を正しく指せていない。

ファイルは「フォルダの中に住んでいる」

当たり前のことから始めます。

あなたのパソコンの中では、ファイルは必ずどこかのフォルダ(ディレクトリ)の中にあります。

そしてウェブサイトも同じで、サーバー上の特定のフォルダにHTML・CSS・JS・画像などが並んでいます。

たとえばこのCodeReaderの内部は、こんな構造になっています。

code_school/
├── index.php              ← トップページ
├── curriculum.php         ← カリキュラム目次
├── lessons/
│   ├── 01-01.php
│   ├── 01-02.php
│   └── 01-07.php          ← 今あなたが見ているページ
├── includes/
│   ├── config.php
│   ├── header.php
│   └── footer.php
└── assets/
    ├── css/
    │   └── style.css      ← 見た目を決めているCSS
    └── js/
        └── main.js

このツリー構造は、あなたのパソコンのフォルダ構造とまったく同じ発想です。

上から下へ入れ子になっていて、各ファイルは自分の「住所」を持っています。

相対パスと絶対パス

あるファイルから別のファイルを参照するとき、住所を書く方法は2種類あります。

絶対パスは、サイトのトップからの完全な住所です。

/assets/css/style.css のように、必ず / から始まります。

どのファイルから見ても同じ住所で通じるので、分かりやすい。

大きなサイトではこちらが主流です。

相対パスは、今いるファイルを基点にした住所です。

同じフォルダにあるファイルなら名前だけ書けばよく、一つ上のフォルダに出たければ ../、二つ上なら ../../ と書きます。

// 例: lessons/01-07.php から assets/css/style.css を参照したい場合

絶対パス: /assets/css/style.css
相対パス: ../assets/css/style.css     ← 「一つ上に出てから、assets/css/style.css」

// 例: lessons/01-07.php から lessons/01-06.php を参照したい場合

相対パス: 01-06.php                   ← 同じフォルダなので、名前だけでOK
相対パス: ./01-06.php                 ← 明示的に「今のフォルダの」と書いてもよい

最も混乱するのが ../ の使い方です。

これは「今いるフォルダから、親フォルダに一つ出る」という意味の魔法の記号です。

二つ出たければ ../../、三つ出たければ ../../../

出た先からさらに /assets/css/ と潜っていく、というように組み合わせて読みます。

— 初心者の鉄則

「画像が表示されない」「CSSが効かない」ときは、まずディベロッパーツールのConsoleタブを開いてください。

赤いエラーで「404 Not Found」と出ているはずです。

そしてエラーメッセージに、ブラウザが探しに行ったパス(住所)が書かれています。

そこに実際にファイルがあるか、ファイル名の綴りやフォルダ階層が合っているかを確認する。

これで大半の「謎の表示されない問題」は解決します。

道具その3 ─ エラーと仲良くなる

最後は、道具というより心構えの話です。

プログラミングを始めると、ほぼ毎日エラーに遭遇します。

初心者の多くは、エラーが出ると「あ、失敗した」と落ち込んで、エラーメッセージを読まずに投げ出してしまいます。

これが、プログラミング学習における最大の罠です。

エラーメッセージは「敵」ではなく「親切なガイド」

発想を逆転させてください。

エラーメッセージは、コンピュータがあなたに送ってくれているラブレターです。

「ここがこうなっていて、私はこれを理解できなかったよ。直してもらえないかな」と、丁寧に伝えてくれているのです。

たとえば、JavaScriptでこんなエラーが出たとします。

Uncaught ReferenceError: usernmae is not defined
    at login.js:12:7

英語が苦手でも、落ち着いて読んでみましょう。

答えが全部書いてあります。

「usernmae」は「username」のタイプミスです。

login.jsの12行目を見に行けば、そこに直すべき箇所があります。

エラーメッセージは、あなたを責めているのではなく、問題の場所と原因を教えてくれているのです。

エラー対処の3ステップ

エラーに出会ったときの基本の動き方を覚えておきましょう。

この順番を守るだけで、解決までの時間が劇的に短くなります。

  1. 読む ── まずエラーメッセージを、最後まで落ち着いて読む。長くて怖くても、必要な情報はだいたい最初の1〜2行に書いてある
  2. 場所を特定する ── 「何行目の、どのファイルか」を必ず確認する。エラーメッセージに書いてある
  3. 狭く絞る ── その周辺のコードを console.log や PHPの var_dump() で探りながら、「どこまでは正しくて、どこから間違っているか」を見つけ出す
— AIと付き合う上での鉄則

エラーが出たとき、エラーメッセージをそのままAIに貼り付けて「直して」と頼むのは、最後の手段にしてください。

まず自分で読む、まず自分で場所を特定する、まず自分で原因を推測する。

そのうえで、「このエラーは出ているけど、自分はこう考えた。合っているか?」とAIに聞く。

これが、AI時代でも自分の力を失わない付き合い方です。

エラーメッセージをコピペしてAIに丸投げする癖をつけると、似たエラーに何度でも同じように遭遇し続け、経験値が一切貯まりません。

PHPのエラーを表示させる

最後にひとつだけ、PHP特有のハマりどころを。

PHPは、デフォルトではエラーを画面に表示しない設定になっていることが多いです。

「画面が真っ白になった」「何も出ない」という場合、実はエラーは起きているのに、隠されている可能性があります。

開発中は、PHPファイルの先頭に次の2行を書いておくと、エラーがすべて画面に表示されるようになります。

<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);

ただし、本番環境では必ず外してください

エラー表示には、ファイルパスやデータベース構造など、攻撃者にとって有用な情報が含まれてしまうからです。

これもLayer 02で改めて触れます。

解読演習

— EXERCISE 01-07-A

このエラーメッセージは、何が起きているか

ブラウザのConsoleに、次のエラーが表示されました。

何が起きていて、どこを見れば直せそうか、自分の言葉で説明してください。

Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
    at main.js:5:17
解答例を見る

直訳するとこうなります:「null(=何もない)のプロパティを読もうとしました。addEventListenerを読もうとした箇所です。main.jsの5行目17文字目。」

つまり、JavaScriptが 何か.addEventListener(...) という呼び出しを実行しようとしたのに、その「何か」が null だったということです。

最もあり得るのは、document.getElementById("xxx") で要素を探したけど、HTMLにその id の要素が存在しなかった、というケース。

たとえば:

const btn = document.getElementById("login-btn");  // ← 該当要素がなければ null
btn.addEventListener("click", ...);                // ← ここで落ちる

直し方は、main.jsの5行目を確認して、その直前で取得している要素が本当に存在するか(HTMLに id のタイプミスがないか、要素がページに存在するか)を確認することです。

よくある原因は、JavaScriptが要素を探しに行ったタイミングで、まだHTMLが読み込まれていなかったパターン。

<script></body> の直前に置くか、DOMContentLoaded イベントで囲むと解決します。

— EXERCISE 01-07-B

このパス、何が間違っている?

次のフォルダ構造があります。

lessons/01-01.php の中から assets/css/style.css を参照したいのですが、書かれているパスが間違っています。

正しくはどう書くべきでしょうか?

code_school/
├── lessons/
│   └── 01-01.php     ← このファイルの中で…
└── assets/
    └── css/
        └── style.css ← これを参照したい
<!-- 01-01.php の中に書かれているコード -->
<link rel="stylesheet" href="assets/css/style.css">
解答例を見る

このコードは、「今いるフォルダ(lessons/)の中に assets/css/style.css を探しに行く」という意味になっています。

でも実際には、assetsフォルダは lessons の隣(親フォルダである code_school/ の直下)にあります。

なので、ブラウザは code_school/lessons/assets/css/style.css を探しに行って、「そんなファイルはない」と404エラーを返します。

正しくは、一度 lessons フォルダから外に出て、そこから assets に入っていく必要があります。

相対パスで書くならこうです:

<link rel="stylesheet" href="../assets/css/style.css">

../ が「一つ上のフォルダに出る」という意味です。

これで「lessons/ から一つ上の code_school/ に出て、そこから assets/css/style.css を探す」という正しい住所になります。

もしくは、絶対パスで書くこともできます(この書き方ならどこからでも同じ):

<link rel="stylesheet" href="/code_school/assets/css/style.css">

CodeReaderでは、このサイト全体で「どのページから読み込んでも同じパスでCSSに辿り着けるようにしたい」ので、実際のコードでは絶対パス方式を採用しています。

includes/config.php の中で SITE_BASE_URL という定数を定義しておいて、それを使って組み立てているのです。

サイトが大きくなるほど、この工夫が効いてきます。

— EXERCISE 01-07-C

DevToolsを使って、このサイトを調査してみよう

これは手を動かす課題です。

今開いているこのページで、実際にディベロッパーツールを開いて、次の3つを調べてみてください。

  1. このページの「読む道具と構え」という見出し(h1)に、どんなCSSが当たっているか。特に文字サイズ(font-size)と色(color)の値を確認する
  2. Consoleタブを開いて、1 + 1 と打ってEnterを押してみる。何が返ってくるか
  3. Networkタブを開いた状態でページをリロードして、このページを表示するために読み込まれたファイルの種類(HTML、CSS、画像、JSなど)がいくつあるか眺めてみる
解答例を見る

これは手を動かす課題なので、「こうなっていたはず」という答えを一つに決めることはしません。

でも、この作業をやった人は、たった3分で「ウェブサイトの裏側を覗く」という体験をしたことになります。

1つ目の見出しのCSSについて。

このサイトでは、.lesson__title というクラスに対して font-size が可変(clamp関数で画面幅に応じて変わる)、colorvar(--ink)(=ほぼ黒)に設定されているはずです。

値をいじって遊んでみると、「CSSを変えるとリアルタイムで見た目が変わる」という体験ができます。

2つ目のConsoleでの 1 + 1 は、もちろん 2 が返ります。

当たり前ですが、これはConsoleがJavaScriptの実行環境として生きていることの証です。

今後、console.log(変数名) を使ってデバッグするときの練習にもなります。

3つ目のNetworkタブ。

このページを開くために、HTMLが1つ、CSSが1つ(style.css)、JavaScriptが1つ(main.js)、そしてGoogle Fontsから読み込まれているフォントファイルが数個、合わせて10個前後のリクエストが飛んでいるはずです。

これがウェブページ1枚の裏側で起きている「会話」の全体像です。

01-01で話した「ブラウザとサーバーの会話」の、実際の様子を目撃した瞬間です。

この章のまとめ

Layer 01、これにて終了です

これで本当にLayer 01の全章を読み終えました。

おつかれさまでした。

あなたは今、HTML・CSS・JavaScript・PHP・SQLの基本を「読める」状態にあり、さらにそれを読むための道具(ディベロッパーツール)と読み手としての構え(パスの感覚、エラーとの付き合い方)も手に入れています。

これだけあれば、AIが書いてきたコードを開いて、「ざっくり何をしているコードか」を自分の言葉で説明できるはずです。

次のLayer 02では、「気付ける」の訓練に入ります。

読めるだけでは足りません。

そのコードが本当に安全か本番環境に置いて大丈夫かを見抜く眼を育てていきます。

SQLインジェクション、XSS、CSRF、認証の不備、ファイルアップロードの罠。

一つずつ、じっくり扱っていきましょう。