INDEX
目次
4章 エラーよ、さようなら!AIデバッグ術
この章の目安学習時間:60分
この章で到達できるゴール:
- コードのエラーメッセージをAIに読み解かせ、原因と解決策を提示させることができる。
- AIを活用して、デバッグ作業の時間を大幅に短縮できる。
【4-1】AIと協力してエラーを解決する
目安の学習時間:30分
赤いエラー表示ともお別れ!
コーディングにおいて、エラーは避けて通れないものです。
特に初学者のうちは、ブラウザの開発者コンソールに表示される赤いエラーメッセージを見て、頭が真っ白になってしまうことも少なくありません。
デバッグ(エラーを修正する作業)が難しいのは、
特に初学者のうちは、ブラウザの開発者コンソールに表示される赤いエラーメッセージを見て、頭が真っ白になってしまうことも少なくありません。
デバッグ(エラーを修正する作業)が難しいのは、
- エラーメッセージが英語で、意味が分からない。
- エラーが起きている場所と、本当の原因の場所が違うことがある。
- 何から手をつけて良いか分からない。
といった理由が挙げられます。
しかし、AIデバッガーとしてのCopilotは、この状況を一変させます。
これからは、エラーは解決のヒントが詰まった「宝の地図」に見えるようになるでしょう。
しかし、AIデバッガーとしてのCopilotは、この状況を一変させます。
これからは、エラーは解決のヒントが詰まった「宝の地図」に見えるようになるでしょう。
AIにエラーの原因を特定させる方法
AIデバッグの基本は、「エラーメッセージ」と「関連するコード」をセットでAIに提供することです。
例えば、ブラウザの開発者コンソールに以下のようなエラーが表示されたとします。
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
このエラーメッセージと、エラーが発生している箇所のJavaScriptコードをCopilot Chatに貼り付け、次のように質問します。
例えば、ブラウザの開発者コンソールに以下のようなエラーが表示されたとします。
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
このエラーメッセージと、エラーが発生している箇所のJavaScriptコードをCopilot Chatに貼り付け、次のように質問します。
AIは、エラーメッセージの意味(「nullに対してaddEventListenerを呼び出そうとしています」)とコードを照らし合わせ、「document.getElementById('my-button')がnullを返している。
つまり、HTML内にIDがmy-buttonの要素が存在しないか、あるいはJavaScriptがHTML要素より先に読み込まれていることが原因です」といったように、的確に原因を特定してくれます。
つまり、HTML内にIDがmy-buttonの要素が存在しないか、あるいはJavaScriptがHTML要素より先に読み込まれていることが原因です」といったように、的確に原因を特定してくれます。
修正コードをAIに提案させる神テク
エラーの原因が特定できたら、解決は目前です。続けてAIに、修正案を尋ねましょう。
AIは、複数の解決策を提示してくれることがあります。
例えば、
例えば、
- HTML側に<button id="my-button">が正しく記述されているか確認すること。
- JavaScriptの実行を遅らせるために、DOMContentLoadedイベントを使う方法や、scriptタグにdefer属性を付ける方法。
これらの提案の中から、自分の状況に合った最適な修正コードを選んで適用することで、エラーを迅速に解決できます。
【4-2】4章 -章末課題- [バグ探しゲーム]
目安の学習時間:30分
問題
ここに、意図的にいくつかのバグが仕込まれたHTMLとJavaScriptのファイルがあります。
このHTMLファイルをブラウザで開くと、期待通りに動作しません(例:ボタンをクリックしても何も起こらない、計算結果が正しく表示されないなど)。
ブラウザの開発者コンソールでエラーを確認し、Copilot Chatと協力してバグを全て修正し、期待通りに動作するようにしてください。
このHTMLファイルをブラウザで開くと、期待通りに動作しません(例:ボタンをクリックしても何も起こらない、計算結果が正しく表示されないなど)。
ブラウザの開発者コンソールでエラーを確認し、Copilot Chatと協力してバグを全て修正し、期待通りに動作するようにしてください。
【提供されるファイル(見本)】
buggy.html
buggy.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>バグ探しゲーム - カウンターアプリ</title> <style> body { font-family: Arial, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; background-color: #f4f4f4; margin: 0; } .container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); text-align: center; } #counter-display { font-size: 3em; margin-bottom: 20px; color: #333; } .buttons button { font-size: 1.5em; padding: 10px 20px; margin: 0 10px; border: none; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } #increase-btn { background-color: #4CAF50; color: white; } #increase-btn:hover { background-color: #45a049; } #decrease-btn { background-color: #f44336; color: white; } #decrease-btn:hover { background-color: #da190b; } #resett-btn { /* バグ1: IDのタイプミス 'reset-btn' -> 'resett-btn' */ background-color: #008CBA; color: white; margin-top: 20px; } #resett-btn:hover { /* バグ1: IDのタイプミス */ background-color: #007bb5; } </style> <script src="buggy.js"></script> </head> <body> <div class="container"> <h1>シンプルなカウンター</h1> <div id="counter-display">0</div> <div class="buttons"> <button id="increase-btn">増やす (+)</button> <button id="decrease-btn">減らす (-)</button> </div> <button id="resett-btn">リセット</button> </div> </body> </html>
HTML
buggy.js
// buggy.js // ① カウンターの初期値を格納する変数 (グローバルスコープだが問題あり) let count = "0"; // バグ: 数値ではなく文字列として初期化 // 要素の取得 (セレクタにバグあり) const counterEl = document.querySelect('#counter-display'); // バグ: メソッド名の間違い const increaseBtn = document.getElementById('increase-btn'); const decreaseBtn = document.getElementById('decrease-btn'); const resetBtn = document.getElementById('resest-btn'); // バグ: IDのタイプミス (HTMLのIDとも不一致) // ② ボタンクリックイベントのリスナー increaseBtn.addEventListener('click', () => { count = count + 1; // バグ: 文字列結合になる counterEl.innerText = count; }); decreaseBtn.addEventListener('click', () => { count -= 1; // この行は数値として処理されるが、初期値が文字列だと問題あり counterEl.innerText = count; }); resetBtn.addEventListener('click', () => { counter = 0; // バグ: 別の変数名を使用 counterEl.innerText = count; // バグ: 更新されていない変数を表示 }); // ③ 初期表示の更新 // counterElement.textContent = count; // バグ: 未定義の変数名を使用
JavaScript
解答手順
修正後
buggy.html
buggy.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>バグ探しゲーム - カウンターアプリ</title> <style> body { font-family: Arial, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; background-color: #f4f4f4; margin: 0; } .container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); text-align: center; } #counter-display { font-size: 3em; margin-bottom: 20px; color: #333; } .buttons button { font-size: 1.5em; padding: 10px 20px; margin: 0 10px; border: none; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } #increase-btn { background-color: #4CAF50; color: white; } #increase-btn:hover { background-color: #45a049; } #decrease-btn { background-color: #f44336; color: white; } #decrease-btn:hover { background-color: #da190b; } #reset-btn { /* バグ修正: IDのタイプミス 'resett-btn' -> 'reset-btn' */ background-color: #008CBA; color: white; margin-top: 20px; } #reset-btn:hover { /* バグ修正: IDのタイプミス */ background-color: #007bb5; } </style> </head> <body> <div class="container"> <h1>シンプルなカウンター</h1> <div id="counter-display">0</div> <div class="buttons"> <button id="increase-btn">増やす (+)</button> <button id="decrease-btn">減らす (-)</button> </div> <button id="reset-btn">リセット</button> </div> <script src="buggy.js"></script> </body> </html>
HTML
buggy.js
// buggy.js - 完全に修正済みバージョン // カウンターの初期値を格納する変数 // バグ修正: 数値として初期化 (let count = 0;) let count = 0; // 要素の取得 // バグ修正: querySelector メソッド名の修正 (document.querySelector) // バグ修正: reset-btn のIDのタイプミス修正 (document.getElementById('reset-btn')) const counterEl = document.querySelector('#counter-display'); const increaseBtn = document.getElementById('increase-btn'); const decreaseBtn = document.getElementById('decrease-btn'); const resetBtn = document.getElementById('reset-btn'); // 修正 // ボタンクリックイベントのリスナー increaseBtn.addEventListener('click', () => { // バグ修正: 数値の加算 (count = count + 1; または count++;) count++; counterEl.innerText = count; }); decreaseBtn.addEventListener('click', () => { count--; counterEl.innerText = count; }); resetBtn.addEventListener('click', () => { // バグ修正: 正しい変数 'count' を更新 (count = 0;) count = 0; counterEl.innerText = count; }); // 初期表示の更新 // バグ修正: 正しい変数 'counterEl' を使用 (counterEl.textContent = count;) // HTML要素が読み込まれた後にスクリプトが実行されるように、DOMContentLoaded //イベントリスナー内に記述するのがベストプラクティスです。 // ただし、この場合は <script> タグが </body> の直前に移動されたため、直接記述しても動作します。 // より堅牢な書き方としては以下のようにラップすることもできます。 document.addEventListener('DOMContentLoaded', () => { counterEl.textContent = count; });
JavaScript
この章のまとめ
これで「4章:エラーよ、さようなら!AIデバッグ術」の解説を終わります。
かつては何時間も溶かしていたかもしれないデバッグ作業が、AIとの対話によって、数分で解決できる知的で楽しいゲームに変わる。そんな体験をしていただけたなら幸いです。
次の最終章では、この教材で学んだ全てのスキルを総括し、AIと共創するプロのWeb制作者としての心構えを固めます。
かつては何時間も溶かしていたかもしれないデバッグ作業が、AIとの対話によって、数分で解決できる知的で楽しいゲームに変わる。そんな体験をしていただけたなら幸いです。
次の最終章では、この教材で学んだ全てのスキルを総括し、AIと共創するプロのWeb制作者としての心構えを固めます。