すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

GitHub Copilot による効率的なシステム開発とその応用

この記事で出来るようになること

本日セミナー講師を担当させていただく株式会社pikawakaの荒木と申します。どうぞよろしくお願いいたします。また弊社代表の宮嶋もサポートとして参加させていただきます。

それではこれからGitHub Copilotによる効率的なシステム開発とその応用についてのセミナーを始めさせていただきます。

1. GitHub Copilotの導入

GitHub Copilotの特徴

まずはGitHub Copilotを始めて使われる方もいらっしゃるということなので簡単な特徴を説明いたします。
GitHub CopilotはAIを使ったコーディング支援サービスです。AIというとChatGPTのような生成AIを思い浮かべますが、GitHub Copilotはプログラミングに特化したAIツールです。ですので、プログラミング以外の質問には答えられなかったりするんですけれども、プログラミングにおいてはChatGPTのような生成AIよりもはるかに便利な機能を持っています。

またGitHub CopilotはJavaScript、Python、Ruby、Goなど、複数のプログラミング言語に対応しています。AIが各言語に特化したパターンを理解しているため、どの言語でも適切なコード提案をしてくれるんですね。これにより、フロントエンド、バックエンド、テストコードなど、幅広いシナリオでAIがサポートしてくれます。

AIがリファレンスや既存コードを参照し、自動でコードを提案してくれるので、リファレンスを調べる時間やコーディングの手間を大幅に削減することができます。初心者にとっても、AIがサポートしてくれることで難解なコードを書かなくてもよく、自然な形でプログラミングスキルを向上させることができます。

ではGitHub Copilotを使う準備をしていこうと思います。
使用する前提としてGitHubのアカウントを取得しておく必要があります。
皆さん、こちらは問題ありませんでしょうか。

VSCodeのインストール

今回はVisual Studio Codeを使ってGitHub Copilotの機能を確認していきます。
すでにインストールされていてもバージョンによってセミナーで紹介するCopilotの機能が使えない場合がございますので、現在の最新バージョンである1.97.2になっているかご確認をお願いいたします。
最新バージョンになっていない方は「再起動して更新」をクリックし、インストールをお願いいたします。

また今後も、GIthub Copilotで使える機能が追加されていきますので、Visual Studio Codeのバージョンは常に最新にしておくのをお勧めします。

GitHub Copilot拡張機能のインストール

次にVSCodeにGitHub Copilotの拡張機能をインストールします。

まずはVSCodeを開いてください。ナビゲーションバーの「表示」をクリックして、「拡張機能」を選択してください。するとサイドバーの一番上に検索窓が表示されるので「GitHub Copilot」と入力してください。するとGitHub Copilotの拡張機能が表示されるので「インストール」をクリックしてインストールします。

すると右下に「Sign in to GitHub」と表示されるのでクリックし、GitHubにログインします。
連携画面が表示されるので「Authorize Visual-Studio-Code」をクリックし、右下にCopilotのアイコンが表示されれば完了です。

次にGitHub Copilot Chatの拡張機能をインストールします。同じように検索窓に「GitHub Copilot Chat」と入力し、インストールしてください。

これでGitHub Copilotを使う準備ができましたので、実際の使い方に移ります。

2. GitHub Copilotの基本的な使い方

この章ではGitHub Copilotの基本的な使い方について解説していきます。
これから実際に私が手を動かして説明を行うんですけれども、同じことをみなさんに体験していただく時間を取ります。
私と一緒に作業していただく必要はございませんので、画面に集中していただければと思います。

(1)GitHub Copilotの使い方

それでは基本となる使い方を順に解説していきます。
すでにGitHub Copilotを使いこなしている方もいらっしゃると思いますが、基本を再確認することで新たな発見や活用のヒントを得られるかもしれませんので、ぜひ一緒にご覧ください。

a. コード補完

まずはGitHub Copilotの主な機能であるコード補完について説明します。コード補完というのは、コードの一部を入力すると、それに続くコードをGitHub Copilotが自動的に提案してくれる機能になります。

では実際に今回のセミナーで使うcopilot_seminarというディレクトリを作成して、そのディレクトリ内に
script.jsというファイルを作成して体験してみます。

まずはディレクトリを作成し、作成したディレクトリをVSCodeで開きます。そしてscript.jsというファイルを作成します。これで準備ができたので、補完機能を体験してみます。

例えばこのように2つの数を足し合わせるadd関数を作成するため、コードを記述していると...

| スニペットの説明 -->
1
function add(

このように入力するだけで、Copilotが自動的に灰色のテキストでコードを補完してくれます。

| スニペットの説明 -->
1
2
  return a + b;
}

このように、コードを書き進める際にCopilotがコードの意図を理解し、効率的に補完を行います。今回であれば途中まで入力した関数名から情報を得て、その名前にあったコードを補完してくれました。補完されたコードを実際に使いたい場合はタブキーを押すとコードが反映されます。

はい、こんな感じですね。

では同じようにしてオブジェクトを作成してみます。
例えば人間の情報をもつpersonというオブジェクトを作成してみます。

| スニペットの説明 -->
1
const person = {

と書くだけでpersonという名前にあったプロパティの提案をしてくれます。

| スニペットの説明 -->
1
2
const person = {
    name: 'John',

personだから人間の情報を持っているだろうなと推測してコードを提案してくれました。

皆さんも補完機能を使って関数やオブジェクトを作成する体験をしてみてください。

まずはスライドにあるようにファインダー、もしくはエクスプローラーでcopilot_seminarというディレクトリを作成し、そのディレクトリをVSCodeで開いてください。そしてcopilot_seminarディレクトリ内にscript.jsというファイルを作成してコードの補完を体験してみてください。このディレクトリとファイルは今後も使用しますので、補完の体験は不要だという方も作成をお願いいたします。

まずは、関数の冒頭部分だけを入力し、Copilotがどのような提案をしてくるか確認してみましょう。関数名が大切なので、スライドの動画のように内容が具体的にわかるような名前をつけましょう。オブジェクトも同様です。

b. 便利なショートカットの使い方

補完の体験はできましたでしょうか?
次は便利なショートカットの使い方について解説していきます。

今回も先ほどと同じように関数を作成してみます。

| スニペットの説明 -->
1
function birt

このように入力すると補完がされます

| スニペットの説明 -->
1
2
3
4
function birthdayCakeCandles(candles) {
  const max = Math.max(...candles);
  return candles.filter(candle => candle === max).length;
}

このように補完してくれました。タブキーを押すことで補完を反映させることができますが、部分的に反映させたい時もあります。その際はcommandキーを押しながらキー(Windowsの場合はcontrolキーとキー)を押すと一つ一つの単語ごとに反映させることができます。

補完の候補が複数ある場合、候補が表示された状態でoptionキーを押しながら]キーを押すことで次の候補を表示させることができます。またoptionキーを押しながら[キーを押すと前の候補を表示させることができます。

それでは皆さんも、ショートカットキーを使ってみましょう。

では次ですね、新しいタブで複数の候補を表示させるショートカットをご紹介いたします。先ほどはショートカットキーで個別に確認していましたが、cntrolキーとenterを押すことで別タブを開いて複数の候補を確認することができます.

先ほどと同じようにコードが補完されたら、controlキーを押しながエンターキーを押すとこのように右枠に新たなタブが開いて複数の候補を確認することができます。反映させたかったらaccept suggestionをクリックします。

それでは皆さんも、実際にショートカットキーを使ってみましょう。

c. コメントの使い方

次はコメントの使い方について解説していきます。
これまでは関数名やオブジェクト名の情報からcopilotがコードを補完してくれましたが、この情報だけだと自分が望むコードを補完してもらう確率は低くなります。なぜかというと情報が名前からでしか得られないからですね。
そのため、作成して欲しい詳しい内容をコメントで書いておくことで、より自分が意図したコードを提案してくれます。
例えばこのようにコメントを記述してから、コードを書いてみます。

| スニペットの説明 -->
1
// 数値が偶数か奇数かを判定し、"even" または "odd" を返す関数を作成する

コメントも補完してくれますね。このように作ってもらいたい内容を具体的に記述して補完してもらいます。
この状態で改行していくと、Copilotが自動的に

と関数名も含めて補完してくれます。

このようにコメントを入れることで、Copilotは自動的にその内容に基づいて適切な関数を提案してくれます。
もちろん先ほどのcontrol + enter で複数の候補を表示できます。

それでは皆さんもコメントを追加して、そのコメントに基づいたコードを生成する体験をしてみてください。

コメントが思い浮かばない方はスライドの動画を参考にしてください。

これがGitHub Copilotのコード補完機能になります。

(2)GitHub Copilot Chatの使い方

この補完機能だけでも便利なんですけれども、GitHub Copilotはこのようにコードを補完してくれるだけでは無いんですね。
この機能にプラスして2023年の12月から新たにGitHub Copilot Chatが利用できるようになりました。この機能の追加によってプログラミングのサポートや質問対応、リアルタイムでのコードの改善提案を行えるようになりました。モデルにはOpen AIが開発したGPT-4oが使われています。

またモデルですが、こちらから他のモデルを選択することができます。
GPT-4oの他にもClaudeやGemini、o3-miniを選択できますが、(preview)と表示されています。これは正式リリース前の試験的な機能を意味しているので、まだ完璧に動作しない可能性があるので注意してください。

a. チャットの使い方

チャットを使用するには左のアクティビティバーの一番下にある吹き出しのアイコンをクリックするか、controlキー+commandキー+i(Windowsはctrlキー+i)を同時に押すことで、チャットビューを開くことができます。今回はアイコンをクリックして開いてみましょう。

一番下にプロンプトの入力欄があるので、そこに文字を入力し、Copilotに対して質問を行います。
例えばこのように「2つの数の合計を返す関数を作成してください。」を入力します。そして紙ヒコーキのアイコンかエンターキーを押すとCopilot Chatに送られます。

すると答えが返ってきます。

| スニペットの説明
1
2
3
4
5
6
7
8
9
計画
1. 関数 sum を定義する
2. 関数は2つの引数 a  b を取る
3. 引数 a  b の合計を計算して返す
4. 
コード
function sum(a, b) {
    return a + b;
}

するとこのように自動で関数を作成してもらうことができました。
他にもエラーを解決する時などに使用します。
例えば今作成してもらった関数に意図的にエラーを発生して試してみましょう。

※エラーコードが記述されているファイルを用意しておき、ここで開く

| スニペットの説明 -->
1
2
3
4
5
6
7
8
// 配列から特定の要素を削除する関数
function removeItem(arr, item) {
  const index = arr.indexOf(item);
  if (index !== -1) {
    arr.splice(index, 1);
  } else {
    console.log("Item not found");
}

このようにエラーがあるファイルを開いて「このファイルのエラーを解決してください」と質問してみると

このようにしてcopilotと会話をしながらコードの提案や修正をしてもらうことができます。

ではみなさんもチャットウィンドウを開いていただき、コードを提案してもらいましょう。同じようにエラーを発生させてエラー解決もしてもらってください。

※チャット欄に以下のエラーコードを共有する

| スニペットの説明 -->
1
2
3
4
5
6
7
8
// 配列から特定の要素を削除する関数
function removeItem(arr, item) {
  const index = arr.indexOf(item);
  if (index !== -1) {
    arr.splice(index, 1);
  } else {
    console.log("Item not found");
}

b. インラインチャットの使い方

これがチャットの基本的な使い方になります。
さらにGitHub Copilotにはこのようにチャットウィンドウを開いて質問する方法ともう一つインラインチャットという機能が用意されています。
インラインチャットを使うと、わざわざ今みたいにチャットウィンドウを開かなくてもエディターの方でピンポイントに質問をすることができます。使い方はエディターの開きたい箇所でcommandキー+i(Windowsはctrlキー + i)を押すと入力欄が表示されます。

ではインラインチャットを使って関数を作成してもらましょう。

※「2つの数を掛け合わせる関数を作成してください。」

そうするとこのように関数を作成してくれました。インラインチャットの場合は英語で返ってくることが多いので、その場合は「日本語でお願いします」と打つと日本語で回答が返ってきます。このコードを反映させたい場合は「同意する」をクリックします。するとコードに反映されます。インラインチャットだとこのように簡単にコードに反映させることができるというメリットもあります。

では次にエラーの解決をしてもらいましょう。先ほどと同じように意図的にエラーを発生させます。今回は「日本語でお願いします」も付け足して質問してみます。

※綴じかっこを外して「このエラーを解決してください。日本語でお願いします」と入力する

はい、このようにエラーを解決してもらえました。同じように同意するをクリックして反映させます。

それではみなさんも実際にインラインチャットを開いて、エラーの解決やコードの解説などを体験してみてください。

c. スラッシュコマンドの使い方

では次はスラッシュコマンドの使い方ということでスラッシュコマンドについて解説していきます。
スラッシュコマンドは、/から始まる特定のキーワードを入力することで、Copilot Chatに対して迅速に特定のアクションを依頼できるショートカットコマンドです。スラッシュコマンドを使うことで、通常ならば今のように文字を入力する作業を簡単に実行することができます。

例えば先ほどのエラーの解決ですが、/fixとだけ入力するだけで「エラーを解決してください」と入力した時と同じ結果を得ることができます。

※インラインチャットを開いて/fixコマンドを実行する

このようにエラー解決をしてくれました。同じようにチャットウィンドウを開いて使うこともできます。

※チャットウィンドウを開いて/fixコマンドを実行する

すると同じようにエラーの解決をしてくれます。インラインチャットだと英語で返ってきて、チャットウィンドウだと日本語で返ってくるのはなぜかというと、Copilot ChatはChatGPTなどの生成AIと同じように会話の履歴を参照して新たな提案をしてくれるからです。チャットウィンドウではこのようにずっと日本語でやりとりをしていたので、それにならって日本語で回答をしてくれましたが、インラインチャットは会話の履歴が存在しないので、「/fix」と英語で質問をしたため、英語で回答が返ってくるというわけなんですね。

他にもコードの解説をしてくれる/explainがあります。

※エラーを解決したコードに対して/explainを使う

するとこのように表示されている関数の解説をしてもらうことができます。

他にも便利なスラッシュコマンドがあります。
/helpコマンドを実行するとwebのヘルプページのようにGitHub Copilot Chatの使い方について教えてくれて、主なスラッシュコマンドをここで確認することができます。

※/helpコマンドを実行する

他にも便利なコマンドがありますので、みなさんもスラッシュコマンドを使ってみましょう。

4. GitHub Copilotベストプラクティスを活用した新規アプリケーションの開発

では次に移ります。
以上がGitHub Copilotの基本的な使い方になります。

このようにGitHub Copilotは非常に便利なAIツールなんですが、新しいフレームワークやライブラリの使い方を学ぶのと同じように、GitHub Copilotの最適な使い方を学ぶことでさらに開発の効率を高めることができます。

この章では新規のアプリケーションを開発していく中でGitHub社が公式に発表しているGitHub Copilotのベストプラクティスを学んでいきます。アプリを完成させるのがゴールではなくて、実際の開発の中での便利な使い方を学ぶのが目的になります。ですので、最終的に仕様通りのアプリが完成できなくても問題はありません。

(1)仕様の作成

ではまずはじめに、今回作成するアプリケーションの仕様を確認していきます。

今回は、「シンプルタスクマネージャー」というシンプルなタスク管理アプリを作成します。このアプリは、日常的なタスクを管理し、ユーザーが自身の進捗状況を把握できるようにすることを目的としたアプリです。

このアプリケーションの主要な機能なんですけれども

  1. タスクの追加: ユーザーが新しいタスクを簡単に追加できるようにします。追加されたタスクはリストに表示されます。
  2. タスクの表示: 追加されたタスクを視覚的にわかりやすく一覧表示します。
  3. タスクの完了/未完了の切り替え: ユーザーがタスクの完了状況をチェックできるようにし、完了済みのタスクは取り消し線で表示します。
  4. タスクの削除: 不要になったタスクをリストから削除する機能を実装します。
  5. タスクのフィルタリング: すべてのタスク、完了済みのタスク、未完了のタスクを簡単に切り替えて表示できるフィルタリング機能を追加します。

これだけではイメージがわかないと思うので、実際に作成ずみのアプリで確認してみましょう。
※完成アプリの画面を共有

このアプリなんですけどHTMLとCSS、JavaScriptの3つのファイルで構成します。

(2)チャットを使用した見た目の作成

まずはチャット機能を使用して基本となるHTMLを作成していきます。
まずは先ほど作成したフォルダ内にindex.htmlというファイルを作成します。
※作成したフォルダ内にindex.htmlを作成する。

a. 見た目の作成

それではcopilotに基本的なHTMLのコードを提案してもらいます。

プロンプト:シンプルなHTMLページの基本構造を作成してください。

b. スパークルを活用したファイルの作成

このようにチャットによってHTMLの基本的な部分が作成されました。
これをコピーしてファイルに貼り付けても良いのですが、提案されたコードをホバーすると表示される3つのアイコンの真ん中の「AIカーソルを挿入します」をクリックすると簡単にファイルに反映させることができます。

はい、このように反映されました。ChatGPTのような生成AIだと回答をコピペしてファイルに反映させる必要がありますが、このようにアイコンをクリックするだけで反映させることができるのもGitHub Copilotの便利な点の一つだと思います。

作成してもらったコードですが、このアプリは「シンプルタスクマネージャー」という名前なので、タイトルを変更しておきます。

※タイトルを「シンプルタスクマネージャー」に変更する

続いてタスクを追加するためのフォームを作成していきます。
※実際にアプリを表示させ、作成する部分を見せる

プロンプト:タスクを追加するためのフォームを作成してください。入力欄と送信ボタンが必要です。

このように新たにコードを追加してくれました。先ほどのアイコンでファイルに反映させてしまうと、カーソルがある箇所から全てのコードが反映されてしまいます。
今回のように新たに追加されたコードをファイルに反映させるには3つのアイコンの一番左の「エディターで適用します」のアイコンをクリックします。

スライドにはスパークルを活用したファイルの作成とありますが、以前は星の形をしたアイコンだったため、スパークルと呼んでいましたが、最新のバージョンからこのアイコンに変わりました。ですので、スパークルイコールこのアイコンだというふうに認識していただければと思います。
※スパークルをクリックし、作成したファイルにコードを自動で記述する。

クリックするとこんな感じで追加されたコードがハイライトされた状態になります。

「変更を受け入れる」をクリックするとこの変更がファイルに反映されます。
このように追加されたコードのみを反映させることができるので、とても便利ですね。
ただファイル内のコードが長くなりすぎてしまった時にはうまく反映されないときもあるので注意してください。

では続いて完了タスクと未完了タスクをフィルタリングするためのボタンを作成していきます。

プロンプト:完了タスクと未完了タスクをフィルタリングするためのボタンを作成してください。

同じようにしてファイルに反映させます。

最後に追加されたタスクを表示するリストを作成します。

プロンプト:追加されたタスクを表示するためのリストを作成してください。

| スニペットの説明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>シンプルタスクマネージャー</title>
</head>
<body>
    <h1>こんにちは、世界!</h1>
    <p>これはシンプルなHTMLページの例です。</p>

    <form id="task-form">
        <label for="task">タスクを追加:</label>
        <input type="text" id="task" name="task" required>
        <button type="submit">追加</button>
    </form>

    <div>
        <button id="show-all">すべてのタスク</button>
        <button id="show-completed">完了タスク</button>
        <button id="show-pending">未完了タスク</button>
    </div>

    <ul id="task-list">
        <!-- ここにタスクが表示されます -->
    </ul>
</body>
</html>

これで一通りHTMLが完成しました。
一回ブラウザでデザインを確認してみましょう。この時ですが、index.htmlのタブを右クリックし、「パスのコピー」をクリックした後、ブラウザのURLにペーストすると簡単に表示できます。

※index.htmlのタブを右クリックし、「パスのコピー」をクリックした後ブラウザのURLにペーストして表示させる。

はい、このようにしっかりとHTMLが作成されました。

チャットを使いHTMLを作成してみよう

それでは皆さんも同じような流れでHTMLを作成してみましょう。
同じプロンプトでも人によって回答が異なるので、必ずしも私と同じようにならなくても問題ありません。HTMLを完成させる過程で、ぜひ実践的なチャットの使い方を体験してみてください。

時間:3分

CSSの作成

これでHTMLが作成できました。

次はスタイルシートを作成します。
まずはstyles.cssというファイルを作成します。

※styles.cssというスタイルシートを作成

CSSも同じようにチャットで作成していきます。

この時、一つ大事なポイントがあります。それは作成したHTMLを開いた状態で質問をすることです。

今回はこのHTMLに対するスタイルシートを作成するので、当然HTMLの情報が必要になります。
ChatGPTのような生成AIの場合だと、プロンプトにこのHTMLのコードコピーして入れる必要があり面倒なんですが、GitHub Copilotであればわざわざプロンプトにコードを入力せずとも、開いているファイルを自動で参照してコードの提案をしてくれるので、とても便利なんですね。

ただし、ファイルを開いていても、表示が確認できるコードしか参照されないので注意が必要です。例えば現在は1行目から◯行目までしかコードを確認できないので、1行目から◯行目までしかコードが参照されません。ではファイル全体を参照させるにはどうしたら良いのかというのはこの後で解説いたします。

また先ほど少し触れましたがcopilotは今までの会話の内容を参考に提案してくれるので、HTMLを作成した会話のなかにHTMLの情報があるので、この続きでCSSファイルを作成してもらっても問題ありませんが、たまに反映されない場合があるので参照するファイルを開いておくと確実です。

ではindex.htmlを開いた状態でCSSを作成していきましょう。

プロンプト:styles.cssファイルにCSSを作成し、美しいデザインにしてください。

するとこのようにCSSを作成してくれました。
回答を確認すると参照されているファイルが確認できます。

同じようにスパークルで反映させるのですが、反映させるファイルを開いた状態でないと違うファイルに反映されてしまうので注意しましょう。

このように反映することができました。
実際に確認してみましょう。

チャットを使いCSSを作成してみよう

それでは皆さんも同じようにCSSを作成してみましょう。その際index.htmlを開いておくのを忘れないようにしてください。

時間:90秒

c. ファイル添付機能を使ったコードの最終確認

これでHTMLとCSSが完成しましたが、念の為コードに問題がないか確認してみます。

先ほどCopilotは開いているファイルを参照して回答を作成すると申し上げました。
今回はHTMLとCSSの2つのファイルを参照して、コードの確認をしてもらう必要があります。
ですが、どちらか一つのファイルしか開いて置けないですし、そもそも表示されているコードのみ参照されるので、ファイルに記述されている全てのコードを参照する必要があります。

今回のように複数のファイルを参照させて、提案をしてもらうにはファイル添付機能を使います。

※ファイル添付機能の説明
以下の3つの方法を説明
- プロンプト入力欄のクリップアイコンをクリックし添付するファイルを選択する。
- 添付したいファイル、エディタータブをプロンプト入力欄にドラッグする
- プロンプト内で「#」を入力し、添付したいファイル名を打ち込んでいくと候補が表示されるので、そこから選択をする。

※ファイル添付機能を使い、2つのファイルを読み込ませた上で行う。
今回はHTMLとCSSの2つのファイルを添付してから質問してみます。

プロンプト:これでHTMLとCSSが完成しましたか?もし修正が必要なら提案してください。

※実行後、「2参照 使用済み」を展開し、参照しているファイルを確認する
回答後、どのファイルが参照されたかを確認することができます。

今回ファイル添付機能を使いましたが、HTMLとCSSの内容が会話の中にあればその情報を元に紐づけてくれるのですが、先ほどと同様、参照しない場合もあるので、このようにファイルを添付しておくと確実です。

では見た目を確認してみます。
思った通りのデザインにならなくても、今回は実際の開発の中で色々な機能を体験してもらうことが目的なので問題ありません。

それでは皆様も実際にファイルを添付してから質問をし、ファイル添付機能を使ってみてください。

時間:2分

(3)機能の実装

a. トップレベルのコメントを活用した新規機能の作成

次に機能の実装を行います。
このアプリではJavaScriptを使って動的なアプリを作成していきます。

先ほど基本的な使い方でコメントを使ってコードの提案をしてもらう方法を実践していただいたと思いますが、今回はこの方法でJavaScriptのコードを提案してもらいます。

会話の履歴から機能を推測して作成してもらうこともできますが、確実に仕様通りのコードを作成してもらうために、トップレベルにコメントを記述します。

最初に作成したscript.jsのトップレベル、つまり一番上の行にコメントを作成します。

| スニペットの説明 -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// タスク管理アプリケーションのためのJavaScriptコード

// 1. DOM要素の取得
// - タスク入力フィールド、追加ボタン、タスクリストのDOM要素を取得する。

// 2. タスクの追加機能
// - 新しいタスクを入力フィールドから取得し、タスクリストに追加する。
// - フォーム送信時にページがリロードされないようにする。
// - 空のタスクを追加できないようにバリデーションを行う。

// 3. タスクの完了/未完了の切り替え機能
// - 各タスクに完了チェックボックスを追加する。
// - チェックボックスの状態に応じて、タスクのスタイルを変更する。

// 4. タスクの削除機能
// - 各タスクに削除ボタンを追加し、クリックするとそのタスクをリストから削除する。

// 5. タスクのフィルタリング機能
// - 全てのタスク、完了済みのタスク、未完了のタスクをフィルタリングして表示するボタンを実装する。

このようにコメントをしました。

このように具体的に作成してほしい内容をトップレベルにコメントとして記述することで、自分が望むコードを提案してもらいやすくなります。

ではjsのコードを作成してもらいましょう。

ただjsはHTMLのコードの情報が必要なので、正確な提案を受けるためにも先ほど学んだファイルを添付する形で参照させましょう。

プロンプト:コメントを元にJavaScriptのコードを作成してください。

| スニペットの説明 -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// タスク管理アプリケーションのためのJavaScriptコード

// 1. DOM要素の取得
const taskInput = document.getElementById('task');
const taskForm = document.getElementById('task-form');
const taskList = document.getElementById('task-list');
const showAllButton = document.getElementById('show-all');
const showCompletedButton = document.getElementById('show-completed');
const showPendingButton = document.getElementById('show-pending');

// 2. タスクの追加機能
taskForm.addEventListener('submit', function(event) {
    event.preventDefault();
    const taskText = taskInput.value.trim();
    if (taskText !== '') {
        addTask(taskText);
        taskInput.value = '';
    }
});

function addTask(taskText) {
    const li = document.createElement('li');
    li.textContent = taskText;

    const completeButton = document.createElement('input');
    completeButton.type = 'checkbox';
    completeButton.addEventListener('change', function() {
        li.classList.toggle('completed');
    });

    const deleteButton = document.createElement('button');
    deleteButton.textContent = '削除';
    deleteButton.addEventListener('click', function() {
        taskList.removeChild(li);
    });

    li.appendChild(completeButton);
    li.appendChild(deleteButton);
    taskList.appendChild(li);
}

// 5. タスクのフィルタリング機能
showAllButton.addEventListener('click', function() {
    filterTasks('all');
});

showCompletedButton.addEventListener('click', function() {
    filterTasks('completed');
});

showPendingButton.addEventListener('click', function() {
    filterTasks('pending');
});

function filterTasks(filter) {
    const tasks = taskList.getElementsByTagName('li');
    for (let task of tasks) {
        switch (filter) {
            case 'all':
                task.style.display = '';
                break;
            case 'completed':
                task.style.display = task.classList.contains('completed') ? '' : 'none';
                break;
            case 'pending':
                task.style.display = task.classList.contains('completed') ? 'none' : '';
                break;
        }
    }
}
| スニペットの説明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>シンプルタスクマネージャー</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>シンプルタスクマネージャー</h1>
    <p>タスクを追加して、完了したタスクと未完了のタスクを管理しましょう。</p>

    <form id="task-form">
        <label for="task">タスクを追加:</label>
        <input type="text" id="task" name="task" required>
        <button type="submit">追加</button>
    </form>

    <div class="filter-buttons">
        <button id="show-all">すべてのタスク</button>
        <button id="show-completed">完了タスク</button>
        <button id="show-pending">未完了タスク</button>
    </div>

    <ul id="task-list">
        <!-- ここにタスクが表示されます -->
    </ul>

    <script src="script.js"></script>
</body>
</html>

これでHTMLとCSS、JavaScriptのファイルが完成しました。
仕様通りに動くか確認してみます。

トップレベルのコメントを作成しよう

それでは皆さんも、トップレベルのコメントを作成してみましょう。記述するコードはスライドを参照し、入力してください。

時間:3分30秒

チャットを使いjsを作成してみよう

HTMLを添付するのを忘れないようにしましょう。
作成後、もし仕様通りに動かない場合は次の章でコードの確認を行いますので、そのままにしておいてください。

時間:2分

| スニペットの説明 -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// タスク管理アプリケーションのためのJavaScriptコード

// 1. DOM要素の取得
// - タスク入力フィールド、追加ボタン、タスクリストのDOM要素を取得する。

// 2. タスクの追加機能
// - 新しいタスクを入力フィールドから取得し、タスクリストに追加する。
// - フォーム送信時にページがリロードされないようにする。
// - 空のタスクを追加できないようにバリデーションを行う。

// 3. タスクの完了/未完了の切り替え機能
// - 各タスクに完了チェックボックスを追加する。
// - チェックボックスの状態に応じて、タスクのスタイルを変更する。

// 4. タスクの削除機能
// - 各タスクに削除ボタンを追加し、クリックするとそのタスクをリストから削除する。

// 5. タスクのフィルタリング機能
// - 全てのタスク、完了済みのタスク、未完了のタスクをフィルタリングして表示するボタンを実装する。

b. @workspaceを使用し、アプリ全体のコードを把握した上でのコード確認

@workspaceを使用し、アプリ全体のコードを把握した上でのコード確認ということで、先ほどのように関連付けたいファイルを添付しておけば各ファイルを参照して、コードの提案を行ってくれますが、大規模なアプリとなると全てのファイルを添付するのは大変ですよね。そういった時は@workspaceを使うと便利です。

@workspaceを質問の一番前につけてから質問をすることで今回であればcopilot_seminerのディレクトリ内にある全てのコードを解析し、提案に必要なファイルを自動で参照して回答をしてくれます。

それでは@workspaceをつけてコードの確認をしてもらいます。

プロンプト:@workspace これで問題なく仕様通り動きますか?

今回は何もファイルを添付せずに質問をしましたが、こ参照したファイルを確認するとこのように全てのファイルを参照した上でコードを提案してくれたことがわかります。
実際に仕様通り動くか確認してみましょう。

これで仕様通りのアプリを作ることができました。

@workspaceを使い、最終確認をしてみましょう

時間:90秒

今回はファイル数が少なかったので@workspaceの恩恵を感じにくかったかもしれませんが、大規模なアプリだと数百のファイルがあるので、便利さを実感できると思います。

4. GitHub Copilotを使った既存アプリケーションの改修

では次ですね。GitHub Copilotを使った既存アプリケーションの改修ということで、
この章では今作成したアプリに新機能を追加していく中で、便利なcopilotの使い方を学んでいきます。

(1)アプリに新機能を追加

a. サンプルコードを使った新機能の追加

サンプルコードを使って新機能を追加してみます。
サンプルコードというのは文字通り、コードを提案してもらう際に参考にしてほしいコードのことを指します。

今回は参考にしてほしいコードをハイライトし、サンプルコードとして参照させてみます。

※ハイライト機能について解説をする

今回は登録したタスクを編集するための機能を追加してみるので、このタスクを追加するコードをサンプルコードとして提案してもらいましょう。

プロンプト:ハイライトしたサンプルコードを元に、既存のタスクに「編集ボタン」を追加し、編集機能を実装してください。

| スニペットの説明 -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// タスク管理アプリケーションのためのJavaScriptコード

// 1. DOM要素の取得
const taskInput = document.getElementById('task');
const taskForm = document.getElementById('task-form');
const taskList = document.getElementById('task-list');
const showAllButton = document.getElementById('show-all');
const showCompletedButton = document.getElementById('show-completed');
const showPendingButton = document.getElementById('show-pending');

// 2. タスクの追加機能
taskForm.addEventListener('submit', function(event) {
    event.preventDefault();
    const taskText = taskInput.value.trim();
    if (taskText !== '') {
        addTask(taskText);
        taskInput.value = '';
    }
});

function addTask(taskText) {
    const li = document.createElement('li');
    li.textContent = taskText;

    const completeButton = document.createElement('input');
    completeButton.type = 'checkbox';
    completeButton.addEventListener('change', function() {
        li.classList.toggle('completed');
    });

    const editButton = document.createElement('button');
    editButton.textContent = '編集';
    editButton.addEventListener('click', function() {
        const newTaskText = prompt('タスクを編集:', taskText);
        if (newTaskText !== null && newTaskText.trim() !== '') {
            li.firstChild.textContent = newTaskText;
        }
    });

    const deleteButton = document.createElement('button');
    deleteButton.textContent = '削除';
    deleteButton.addEventListener('click', function() {
        taskList.removeChild(li);
    });

    li.appendChild(completeButton);
    li.appendChild(editButton);
    li.appendChild(deleteButton);
    taskList.appendChild(li);
}

// 5. タスクのフィルタリング機能
showAllButton.addEventListener('click', function() {
    filterTasks('all');
});

showCompletedButton.addEventListener('click', function() {
    filterTasks('completed');
});

showPendingButton.addEventListener('click', function() {
    filterTasks('pending');
});

function filterTasks(filter) {
    const tasks = taskList.getElementsByTagName('li');
    for (let task of tasks) {
        switch (filter) {
            case 'all':
                task.style.display = '';
                break;
            case 'completed':
                task.style.display = task.classList.contains('completed') ? '' : 'none';
                break;
            case 'pending':
                task.style.display = task.classList.contains('completed') ? 'none' : '';
                break;
        }
    }
}

では実際に動きを確認してみましょう。

※うまく動かない場合は治さずにこの後のスラッシュコマンドで修正する

では皆さんもサンプルコードを使って新機能を実装してみましょう。もし意図した通りに動かない場合はこの後修正するのでそのままにしておいてください。

時間:2分

b. OSSを参照した新機能の追加

このように参考にしてほしいコードをハイライトすることで、そのコードを参照したコードを提案してもらえます。
同じようにして参考にしたいOSSのコードを参照させることで、OSSを利用したコードの提案してもらうこともできます。

例えば同じタスク管理アプリのコードを参考に、新たな機能の提案などをしてもらうことができます。

今回はこのリポジトリのコードを参考に、新しい機能の提案してもらいます。
※以下のOSSのコードを参照させる例
https://github.com/tastejs/todomvc/tree/master

それでは実際にリポジトリをダウンロードしましょう。
ダウンロードしたファイルはcopilot_seminerディレクトリの中に移動させます。
するとこのようにVSCode上で確認することができます。

ですがこのままだとダウンロードしたディレクトリを追加する前にVSCodeを開いたので、追加したディレクトリがうまく参照されません。ですので、一度再起動させます。

そうするとこのtodomvcディレクトリ内のすべてのコードを解析した上での提案をしてくれるようになります。

それでは先ほど学んだ@workspaceを使って新機能の提案をしてもらいましょう。

プロンプト:@workspace todomvcのコードを参考に、このシンプルタスクマネージャーに新しい機能を提案してください。

このようにして参考にしたいOSSのコードを使ってコード提案をしてもらうことができます。

では皆さんもリポジトリからファイルをダウンロードして、そのファイルを参考に新機能を提案してもらいましょう。

時間:4分

(2)スラッシュコマンドを使ったコードのデバッグ

今のコードだとリロードするとデータが消えてしまうため、実用的ではありません。
ですので、リロードしてもデータが消えないようコードを修正してもらいます。

a. スレッドを使用した会話の整理方法

その前に会話が長くなってきたので、新たなスレッドを作成し質問していきます。
前述した通り、copilotは会話の履歴を参照し、コードの提案を行うので、余分な情報が多いと提案がぶれてしまうことがあります。
またスレッドで会話を整理しておくと、「この会話はデバック用」、「この会話はリファクタリング用」と整理することができるので便利です。

新しいスレッドは「+」をクリックすると作成できます。クリックするとこのようにまっさらな状態で会話を始めることができます。では過去の会話はもう確認ができなくなるのかというとそんなことはなく、その横のアイコンをクリックすることで、過去の会話を呼び出すことができます確認できます。過去の会話の一覧では、会話のタイトルを編集したり、不要となった会話を削除することもできます。

※実際にやってみせる。

それでは新しいスレッドで会話を始めます。

プロンプト:登録したデータをリロードしても表示されるように修正してください。

今回は過去の会話がない状態なので「@workspace」をつけて質問します。その際、先ほどのように先頭につけてから質問をする方法とショートカットキーを使って質問する方法があります。このように紙ヒコーキアイコンの右の矢印をクリックするとコマンドが確認できます。
コマンドを押しながらエンターもしくはこれをクリックしてもOKです。

| スニペットの説明 -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// タスク管理アプリケーションのためのJavaScriptコード

// 1. DOM要素の取得
const taskInput = document.getElementById('task');
const taskForm = document.getElementById('task-form');
const taskList = document.getElementById('task-list');
const showAllButton = document.getElementById('show-all');
const showCompletedButton = document.getElementById('show-completed');
const showPendingButton = document.getElementById('show-pending');

// 2. タスクの追加機能
taskForm.addEventListener('submit', function(event) {
    event.preventDefault();
    const taskText = taskInput.value.trim();
    if (taskText !== '') {
        addTask(taskText);
        taskInput.value = '';
    }
});

function addTask(taskText) {
    const li = document.createElement('li');
    li.textContent = taskText;

    const completeButton = document.createElement('input');
    completeButton.type = 'checkbox';
    completeButton.addEventListener('change', function() {
        li.classList.toggle('completed');
        saveTasks();
    });

    const editButton = document.createElement('button');
    editButton.textContent = '編集';
    editButton.addEventListener('click', function() {
        const newTaskText = prompt('タスクを編集:', taskText);
        if (newTaskText !== null && newTaskText.trim() !== '') {
            li.firstChild.textContent = newTaskText;
            saveTasks();
        }
    });

    const deleteButton = document.createElement('button');
    deleteButton.textContent = '削除';
    deleteButton.addEventListener('click', function() {
        taskList.removeChild(li);
        saveTasks();
    });

    li.appendChild(completeButton);
    li.appendChild(editButton);
    li.appendChild(deleteButton);
    taskList.appendChild(li);

    saveTasks();
}

// 3. タスクの保存機能
function saveTasks() {
    const tasks = [];
    const taskItems = taskList.getElementsByTagName('li');
    for (let taskItem of taskItems) {
        tasks.push({
            text: taskItem.firstChild.textContent,
            completed: taskItem.classList.contains('completed')
        });
    }
    localStorage.setItem('tasks', JSON.stringify(tasks));
}

// 4. タスクの読み込み機能
function loadTasks() {
    const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
    for (let task of tasks) {
        addTask(task.text);
        if (task.completed) {
            const lastTask = taskList.lastChild;
            lastTask.classList.add('completed');
            lastTask.querySelector('input[type="checkbox"]').checked = true;
        }
    }
}

// 5. タスクのフィルタリング機能
showAllButton.addEventListener('click', function() {
    filterTasks('all');
});

showCompletedButton.addEventListener('click', function() {
    filterTasks('completed');
});

showPendingButton.addEventListener('click', function() {
    filterTasks('pending');
});

function filterTasks(filter) {
    const tasks = taskList.getElementsByTagName('li');
    for (let task of tasks) {
        switch (filter) {
            case 'all':
                task.style.display = '';
                break;
            case 'completed':
                task.style.display = task.classList.contains('completed') ? '' : 'none';
                break;
            case 'pending':
                task.style.display = task.classList.contains('completed') ? 'none' : '';
                break;
        }
    }
}

// ページが読み込まれたときにタスクを読み込む
document.addEventListener('DOMContentLoaded', loadTasks);

このようにローカルストレージに保存するよう提案してくれました。ブラウザのローカルストレージは、Webアプリケーションがユーザーのブラウザにデータを保存するための仕組みです。保存されたデータは、ブラウザを閉じても消えず、長期的に保持されます。LocalStorageは「キーとバリューのペア」を保存でき、1ドメインあたり約5MBまでデータを保存できます。

ローカルストレージは検証モードにしてからアプリケーションタブを選択します。そしてストレージのローカルストレージを選択すると確認ができます。このようにキーとバリューのペアになって保存されます。

それではコードを反映してみます。

では実際にリロードしても消えなくなったか確認してみましょう。

うまく動かなかった場合はスラッシュコマンドを使ってデバッグしてもらいましょう。
修正してもらうコマンドは/fixコマンドでしたね。

ではみなさんも新しいスレッドを開いて機能を追加してみましょう。もし正しく動かない場合はfixコマンドで修正してみましょう。

時間:4分

(3)スラッシュコマンドを使ったソースコードの解説

ここまで全てのコードをcopilotに作成してもらいました。
ですので、部分的に理解できないコードがあると思います。
copilotには基本的な使い方で紹介した「/explain」という便利なスラッシュコマンドが用意されています。

a. インラインチャットを使用したコード解説

まずはインラインチャットを使ってコードを解説してもらいます。

※インラインチャットについて復習

インラインチャットとはエディタ内でチャットウィンドウを開いて質問する機能でしたね。commandキーとiで開くことができます。escキーで閉じることができます。左のチャットウィンドウは閉じてみましょう。

それではインラインチャットを開いて、プロンプトを入力してみます。

プロンプト:/explain

すると開いているファイルのメソッド一覧が表示されるので、解説してほしいメソッドを選択します。

※何を解説するのかメソッドや変数一覧が表示されるので、どれか選択。

このように選択したコードの解説をしてもらうことができます。

インラインチャットはチャットを開いていなくてもピンポイントで質問できるので便利な機能です。

b. ハイライト機能を使用したコード解説

特定の部分のコードを解説してもらうにはその部分をハイライトした状態でインラインチャットを開いて質問します。

それでは解説してもらいたい箇所をハイライトした状態プロンプトを入力してみます。

※コードのハイライトを行う

※会話の履歴の活用を説明
今回は前と同じコマンド「/explain」を入力するのですが、ターミナルのようにキーボードの上下の矢印キーを押すことで、過去のプロンプトを呼び出すことができます。

※キーボードの上下の矢印キーを使い、「/explain」を呼び出し、他のメソッドの解説をしてもらう

それでは実行してみます。

プロンプト:/explain

そうすると、先ほどは解説してもらいたい関数の一覧が表示されましたが、ハイライトするとハイライトしたコードの解説をしてもらうことができます。

インラインチャットやハイライト機能を使ってコードの解説をしてもらいましょう。

時間:4分

(4)スラッシュコマンドを使ったコードのリファクタリング

次はスラッシュコマンドを使ってコードのリファクタリングを行います。
今回も新しくスレッドを作成して行います。

※新しくスレッドを開く

「/refactor」と打つと選択したコードをリファクタリングしてくれます。これは公式に定義されたコマンドではないのですが、実際にリファクタリングをしてくれるコマンドとして使用できます。

では同じようにリファクタリングしたい部分をハイライトしてコマンドを入力してみます。

※新しくスレッドを開き、リファクタリングする箇所をハイライト

プロンプト:/refactor

このようにリファクタリングされました。

それでは皆さんもいくつかリファクタリングしたい箇所をハイライトして/refactorコマンドを使ってみましょう。

時間:2分

完成コード

| スニペットの説明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>シンプルタスクマネージャー</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>シンプルタスクマネージャー</h1>
    <p>タスクを追加して、完了したタスクと未完了のタスクを管理しましょう。</p>

    <form id="task-form">
        <label for="task">タスクを追加:</label>
        <input type="text" id="task" name="task" required>
        <button type="submit">追加</button>
    </form>

    <div class="filter-buttons">
        <button id="show-all">すべてのタスク</button>
        <button id="show-completed">完了タスク</button>
        <button id="show-pending">未完了タスク</button>
    </div>

    <ul id="task-list">
        <!-- ここにタスクが表示されます -->
    </ul>

    <script src="script.js"></script>
</body>
</html>
| スニペットの説明 -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* 全体のスタイル */
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
}

/* ヘッダーのスタイル */
h1 {
    color: #333;
}

/* フォームのスタイル */
form {
    margin-bottom: 20px;
}

label {
    font-size: 1.2em;
    margin-right: 10px;
}

input[type="text"] {
    padding: 10px;
    font-size: 1em;
    border: 1px solid #ccc;
    border-radius: 5px;
    width: 200px;
}

button {
    padding: 10px 20px;
    font-size: 1em;
    color: #fff;
    background-color: #007BFF;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    margin-left: 10px;
}

button:hover {
    background-color: #0056b3;
}

/* フィルターボタンのスタイル */
.filter-buttons button {
    margin: 5px;
}

/* タスクリストのスタイル */
ul {
    list-style-type: none;
    padding: 0;
}

li {
    background-color: #fff;
    margin: 10px 0;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

li.completed {
    text-decoration: line-through;
    color: gray;
}

li button {
    background-color: #dc3545;
}

li button:hover {
    background-color: #c82333;
}
| スニペットの説明 -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// タスク管理アプリケーションのためのJavaScriptコード

// 1. DOM要素の取得
const taskInput = document.getElementById('task');
const taskForm = document.getElementById('task-form');
const taskList = document.getElementById('task-list');
const showAllButton = document.getElementById('show-all');
const showCompletedButton = document.getElementById('show-completed');
const showPendingButton = document.getElementById('show-pending');

// 2. タスクの追加機能
taskForm.addEventListener('submit', function(event) {
    event.preventDefault();
    const taskText = taskInput.value.trim();
    if (taskText !== '') {
        addTask(taskText);
        taskInput.value = '';
    }
});

function addTask(taskText) {
    const li = document.createElement('li');
    li.textContent = taskText;

    const completeButton = document.createElement('input');
    completeButton.type = 'checkbox';
    completeButton.addEventListener('change', function() {
        li.classList.toggle('completed');
        saveTasks();
    });

    const editButton = document.createElement('button');
    editButton.textContent = '編集';
    editButton.addEventListener('click', function() {
        const newTaskText = prompt('タスクを編集:', taskText);
        if (newTaskText !== null && newTaskText.trim() !== '') {
            li.firstChild.textContent = newTaskText;
            saveTasks();
        }
    });

    const deleteButton = document.createElement('button');
    deleteButton.textContent = '削除';
    deleteButton.addEventListener('click', function() {
        taskList.removeChild(li);
        saveTasks();
    });

    li.appendChild(completeButton);
    li.appendChild(editButton);
    li.appendChild(deleteButton);
    taskList.appendChild(li);

    saveTasks();
}

// 3. タスクの保存機能
function saveTasks() {
    const tasks = [];
    const taskItems = taskList.getElementsByTagName('li');
    for (let taskItem of taskItems) {
        tasks.push({
            text: taskItem.firstChild.textContent,
            completed: taskItem.classList.contains('completed')
        });
    }
    localStorage.setItem('tasks', JSON.stringify(tasks));
}

// 4. タスクの読み込み機能
function loadTasks() {
    const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
    for (let task of tasks) {
        addTask(task.text);
        if (task.completed) {
            const lastTask = taskList.lastChild;
            lastTask.classList.add('completed');
            lastTask.querySelector('input[type="checkbox"]').checked = true;
        }
    }
}

// 5. タスクのフィルタリング機能
showAllButton.addEventListener('click', function() {
    filterTasks('all');
});

showCompletedButton.addEventListener('click', function() {
    filterTasks('completed');
});

showPendingButton.addEventListener('click', function() {
    filterTasks('pending');
});

function filterTasks(filter) {
    const tasks = taskList.getElementsByTagName('li');
    for (let task of tasks) {
        switch (filter) {
            case 'all':
                task.style.display = '';
                break;
            case 'completed':
                task.style.display = task.classList.contains('completed') ? '' : 'none';
                break;
            case 'pending':
                task.style.display = task.classList.contains('completed') ? 'none' : '';
                break;
        }
    }
}

// ページが読み込まれたときにタスクを読み込む
document.addEventListener('DOMContentLoaded', loadTasks)

5. GitHub Copilot Tips

この章ではGitHub Copilotを使う上でのちょっとした助言や注意点を解説していきます。

(1)Copilot Editsでコードを直接編集

GitHub Copilotにはチャット機能とは別にCopilot Editsという機能があります。
チャットではコードが提案された時にそのコードを自分で反映させる必要がありました。
それに対し、Copilot EditsはCopilotが直接提案したコードを記述してくれます。

実際にやってみましょう。
それではJavaScriptのコードをCopilot Editsを使ってリファクタリングしてもらいます。
するとこのようにコードを直接記入してくれました。
問題がなければ反映させます。

では皆さんも、APIを叩いて取得したJSONを扱いやすく整形してみましょう。

(2)GitHub Copilotを使う上での注意点

最後にGitHub Copilotを使う上での注意点を確認しておきましょう。

a. 最終的な責任は自分

GitHub Copilotは、高い精度でコード提案を行ってくれるのですが、それが必ずしも安全で最適なコードであるとは限りません。特に、セキュリティに関連するコードの場合、自動生成されたコードに脆弱性が含まれている可能性があります。
Copilotで生成されたコードに関する最終的な責任は使用者である自分にあります。ですので問題なく動くかどうか、必ず自分でコードの品質を確認しましょう。

b. 著作権と派生的作品に関するリスク

GitHub Copilotは、インターネット上に公開されている膨大な量のコードを学習してコードの提案を行います。そのため、生成されたコードには、オープンソースプロジェクトからのコードが含まれることがあります。これにより、コードが特定のライセンス条件を満たしていない可能性が出てくる場合があります。

基本的なアルゴリズムや標準的なループ処理、条件分岐、配列操作などは、一般的に多くの場所で共通して使用されているもので、特定の著作権やライセンスに縛られにくいです。一方で、Copilotが提案する複雑なコードや、特定のライブラリに依存していると明らかにわかるコードは、ライセンスに注意を払いましょう。

c. データ流出リスク

GitHub Copilotは、オープンソースのリポジトリを学習してコード提案を行いますが、セキュリティリスクも伴います。特に、Copilotが参照する公開リポジトリには、攻撃者が意図的にアップロードした悪意のあるコードが含まれる可能性があり、これがデータ流出につながる危険があります。

ですので生成されたコードに、APIキーやパスワードなどの機密情報を埋め込まないように注意しましょう。またプロンプト内にAPIキーなどの個人情報を含めないよう注意しましょう。

ということで、これでセミナーの解説は終了になります。

ワークショップ

それではこれからワークショップを行います。
先ほどタスク管理アプリを作成いたしましたが、同じような流れで掲示板アプリを作成いたします。
前回はこちらの指示で作成いたしましたが、このワークショップでは皆さんがベストプラクティスを使いながら仕様通りのアプリを作成していただきます。

仕様を確認しよう

それでは作成するアプリの仕様を確認しましょう。
まず投稿機能です。入力フォームにはユーザー名とメッセージを入力をする欄があります。ユーザー名は任意で、入力されていない時には「匿名」として表示されます。

投稿ボタンを押すと画面に反映されます。
投稿された内容は投稿フォームの下に新しい順に表示されます。
表示される項目はユーザー名とメッセージです。

それではこれまで学んだGitHub Copilotの機能を使って仕様通りにアプリを作成してください。どの機能を使うかは自由です。チャットではなく、先ほどのCopilot Editsを使っていただいても構いません。

機能を追加しよう

すでに完成した方はこのアプリに機能を追加しましょう。

最後に

いかがでしたでしょうか?
GitHub Copilotを使うことで、開発作業の効率が劇的に向上することを実感していただけたのではないでしょうか。特に、プロジェクト全体のコードを検索した上でコードを提案してくれる点は、ChatGPTのような汎用的な生成AIでは難しい部分であり、Copilotを導入する価値が十分にあります。

ぜひ、今日学んだことを日々の業務やプロジェクトで積極的に活用してみてください。GitHub Copilotの力を借りて、よりスムーズな開発環境を実現していただければと思います。

ということで最後の質疑応答に移ります。

それではこの辺で本日のセミナーを終了させていただきます。本日は長い時間ありがとうございました。

この記事のまとめ

  • 一行コードスニペットだよ
  • 〇〇〇
  • 〇〇〇