2024-3I プログラミング3 第01回 講義資料

2024年10月03日(木)1・2時限

1 ガイダンス

1.1 概要

本科目ではNext.jsをフレームワークに採用した「ウェブアプリ開発」を実践形式で学び、実際にオリジナルのブログシステム (記事の閲覧と投稿機能を持つもの) をゼロから開発、デプロイ・公開することができる知識とスキルの修得を目標としています。デプロイとは 開発したウェブアプリをサーバにアップロードし、実際に、ユーザーがインターネット経由でスマホやPCから利用できる状態 にすることです。

皆さんが、この授業で開発したウェブアプリは、来年のインターンシップや、将来の就活の「選考」のなかで、自分の能力と経験 (実績) を客観的に示すこと に利用できます。授業という枠を超え、意欲的に取り組んで欲しいと思います (特にウェブ系エンジニアを視野に入れているひとは頑張ってください)。

1.2 授業の位置づけ

この授業の位置づけは、次のようになります。

1.2.1 基本情報

学修単位

本科目は、前期の 情報3プログラミング2 と同じく「学修単位」の科目であり「30時間 (相当) の対面授業」と「60時間 (相当) の授業時間外学習」が要求される科目となります。

授業については毎週90分を実施し、これを2時間と見なして全15回の講義によって「30時間相当の対面授業」を確保しています。これに加えて、皆さんは授業1回につき、授業時間外に 約4時間の自主的な学習 が求められます

そして、この授業は、それらの授業時間外学習を前提にボリューム設定や難易度設定をしています。

1.2.2 関連科目

知能情報コースの専門科目は ソフトウェア系ハードウェア系応用情報科学系3系統 から構成されています。ここでは、ソフトウェア系応用情報科学系 のなかで本科目と特に関連がある科目を挙げています。


また、4年生以降は、次のような科目が展開されます。

1.3 本科目を通じて学べる知識・スキル

本科目ではNext.jsをフレームワークに採用した「ウェブアプリ開発」についてハンズオン形式で実践的に学び、最終的にオリジナルのブログシステム (記事の閲覧と投稿機能を持つもの) を ゼロから開発、デプロイ (公開) できる知識とスキルの修得 を目指します。

当初は、バックエンドを「Django (Python)」、フロントエンドを「React (TypeScript/JavaScript)」を使って開発することを予定していました。しかし、9月中旬のアンケートの結果、Next.js によるモダン開発の希望が圧倒的多数 (12対2) だったので、予定を変更してバックエンドもフロントエンドも Next.js (React) を採用した開発について学びます。

Next.js は Reactを基盤として、バックエンドも含めたウェブアプリ開発環境を提供するフレームワーク です。

具体的には、Next.js のほか、次のような技術やウェブサービスについて学びます。

「React」とは

React は、SPA (Single-Page Application) を採用したウェブアプリ(ウェブサービス / ウェブサイト)の開発に特化した ユーザーインターフェイス構築ライブラリ (フロントエンドフレームワーク) です。

ウェブアプリの開発者に対しては 高度な再利用性と優れた保守性を提供 し、ウェブアプリの利用者には 高速で応答性の高い快適なUI/UX を提供します。Meta社 (旧Facebook社) が開発・保守しているライブラリで、ウェブ版の Facebook や Instagram、メルカリ、LINE、Netflix、Dropbox、UberEats などでガンガンに使われています。

ウェブアプリのフロントエンドフレームワークとしては、Reactの他、Vue.js(ビュージェイエス) やAngular (アンギュラーアンギュラー)、Svelte(スヴェルト) なども存在しますが、いまは React が最も人気で技術情報も豊富です。

1.3.1 前提とする知識とスキル

本科目は、概ね次のような学習経験を積んでいることを「前提」とした授業内容、授業スピード (展開速度) となります。

知識やスキルが不足していると感じる学生はProgeteなどを活用して補習しておいてください。

1.4 成績評価法

総合成績(年度末の最終成績)は、シラバスに記載したように次のように評価します。

中間試験や期末試験などの筆記形式の定期試験は実施しません

1.5 授業の進め方

ウェブアプリ開発とは?」や「ウェブアプリ開発とウェブサイト制作の違いは?」といった座学的な内容は、今後の授業のなかで、順次、説明していきます。初回授業から、手を動かさずに話を聞いているだけでは実感も湧かず、眠くなってしまうと思うので・・・。

気になる人は以下を参考にしてください (内容としては、キャリア形成の観点で極めて重要です)。

本日 (第01回) から 第05回講義 ぐらいまでは「開発環境の構築・設定」「モダンTypeScriptの学習」「Reactを使った「Todoアプリ」の開発」を目標に進めていきます。ここでの「Todoアプリ」は フロントエンドだけで完結するウェブアプリ (ウェブブラウザを実行環境とするアプリ) として開発します。

その後、データベースや、各ウェブサービス (microCMS) との連携、Next.js によるウェブAPI開発などの「バックエンドの領域」について学びながら「オリジナルのブログシステムの開発」に挑んでいきます。

後期中間ぐらいまでの流れ (予定)

  1. モダンTypeScript基礎学習のための環境構築
  2. TypeScript基礎学習
  3. Reactを使ったTodoアプリのための環境構築
  4. Todoアプリ開発(Reactによるフロントエンド開発)のチュートリアル
  5. Todoアプリのカスタマイズや作り込み → 前半の大課題

2 最初の目標「Todoアプリの開発」

後期の中間試験前ぐらいまでは、次のリンクに示すようなTodoアプリを「React」とよばれる JavsScriptライブラリ (フロントエンド開発フレームワーク) を使って開発できるようになること (= ある程度の意味や内容を理解して実装できるようになること ) を目標にします。

そのために、まず、要求されるのが TypeScript言語 (JavaScript言語) の基礎 であり、そのために必要となるのが 開発環境の構築 になります。なお、エディタについては、皆さんも使い慣れているハズの「VSCode」を使用していきます (GitHub Copilot の支援も受けてください)。

3 JavaScript/TypeScriptの概要

TypeScript (タイプスクリプト) は、JavaScript (ジャバスクリプト) に「静的型付け」や「クラスベースのオブジェクト指向」など導入して拡張したプログラミング言語です。Microsoft によって開発・保守され、最近の中規模以上のフロントエンド開発では、TypeScript が事実上の標準言語 (ほぼ唯一の選択肢) となっています。

この授業で学ぶ React や Next.js のほか、AngularVue.js などのウェブアプリ開発の主要フレームワークも TypeScript による開発を推奨しており、実際に多くのウェブ開発現場で TypeScript が採用されています。プログラミング言語別の求人ランキング (参考) においても上位を陣取る言語となっています。

なお、TypeScript プログラムは、「トランスパイラ」というものを使って JavaScriptプログラムに変換できるので、基本的には 「TypeScriptが使える」=「JavaScriptが使える」 と考えて問題ありません。

トランスパイラによる「TypeScript」から「JavaScript」への変換

prac00.ts という TypeScriptプログラム があるとき、tsc --target es6 prac00.ts というコマンドで prac00.js という JavaScriptプログラム に変換できます。今回の授業後半で開発環境が構築できたら、実際にトランスパイルをしてもらいます。

(変換前)

function greetAndCalculate(name: string, a: number, b: number): string {
  const sum: number = a + b;
  return `Hello, ${name}! The sum of ${a} and ${b} is ${sum}.`;
}

const userName: string = "Alice";
const x: number = 10;
const y: number = 20;

const result: string = greetAndCalculate(userName, x, y);
console.log(result);

(変換後)

function greetAndCalculate(name, a, b) {
    const sum = a + b;
    return `Hello, ${name}! The sum of ${a} and ${b} is ${sum}.`;
}
const userName = "Alice";
const x = 10;
const y = 20;
const result = greetAndCalculate(userName, x, y);
console.log(result);

3.1 JavaScript (\(\neq\) TypeScript) の実行環境

もともと JavaScript はNetscapeというウェブブラウザにおいて、HTML要素に対して動的な視覚的効果を与えたり、ダイアログを表示したりするために開発された言語であり、JavaScript の (基本的な) 実行環境ウェブブラウザ (Chrome、Edge、Safari、Firefox など) となります。

「JavaScript」は、当初「LiveScript」という名前でした。しかし、当時の Java の爆発的人気にあやかって JavaScript に改名しています。念のために「Java」と「JavaScript」は メロンとメロンパンぐらい違う (有名な「たとえ」ですね) ので注意してください。完全なる別物です。

JavaScriptは、ウェブブラウザを実行環境として動作する」というのは、Python や C言語 などのネイティブアプリ開発用の言語と比較して大きな特徴 となります。ウェブブラウザが使える環境であれば OS や デバイス (スマホやPC) に依存せず JavaScript が実行可能できる というのは 大きな「強み」 といえます。

例えば、自分が作成した「Pythonプログラム」を誰かに使ってもらおうとしたら、その利用者のPCに Python の実行環境をインストールしてもらって、さらに必要なパッケージを pip でインストールしてもらって…という非常に高いハードルがありました (PythonコードをEXEファイル化して配付するという手段もありましたが、ファイルサイズも非常に大きく起動も遅いアプリになってしまいました) 。

3.1.1 ウェブブラウザで実行されるJavaScript

JavaScriptの実行環境が「ウェブブラウザ」であること」を実際に確認してましょう。

次の2つのファイルをテキストエディタで作成・保存 (拡張子に注意) し、index.html のほうをダブルクリックして Chrome を起動してください。さらに、Chrome で [F12] を押下して デベロッパーツール (開発者ツール) を起動し「コンソール」タブを確認してください。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
  <p>"F12"で「コンソール」を開いて結果を確認してください。</p> 
  <script src="hoge.js"></script>
</body>
</html>

上記 index.ts第09行目 で、以下のJavaScriptプログラムを呼び出しています。

function add(a, b) {
  const c = a + b;
  console.log(`${a}${b} を足すと ${c} です。`);
}
add(10,20);
add(50,-30);

デベロッパーツールのなかの「コンソールタブ」から、次のように ウェブブラウザを実行環境として JavaScriptプログラム が動くこと が確認できたと思います。

img

なお、ウェブブラウザで JavaScript を実行するためには HTMLファイル の内部から JavaScriptプログラム を呼び出す必要 があります。hoge.js をダブルクリックしたり、ウェブブラウザ画面に「JavaScriptファイル」をドラッグアンドドロップしても動作しません。実際に試してみてください。

注意

ウェブブラウザでは「TypeScript」で書かれたプログラムコードを直接実行することはできません。ウェブブラウザで実行するためには トランスパイラ を使って、あらかじめ「TypeScript」を「JavaScript」に変換・配置し、基本的にはHTMLファイルから呼び出す必要があります。

なお「トランスパイラ (Transpiler)」とは、あるプログラミング言語で書かれたソースコードを、別のプログラミング言語のソースコードに変換するツールのことで「トランスレート (Translate)」と「コンパイル (Compile)」を組み合わせた造語です。

皆さんは、既に「Pyhthon」「C」「Arduino」を学んできているので推測はつくと思いますが hoge.js に記述されるプログラムは、Python で書けば以下のようなものとなります。

def add(a, b):
  c = a + b
  print(f'{a}{b} を足すと {c} です。')
add(10, 20)
add(50, -30)

Pythonプログラムは、覚えてますよね?

3.2 もうひとつの JavaScript の実行環境

先のセクションで「JavaScripthはウェブブラウザ上で実行される」と解説しましたが、実は、もうひとつ Node.js という「ウェブブラウザとは異なるJavaScript実行環境」が存在します。

Node.js (ノード・ジェーエス) は、Windows や Linux などの OS にインストールして利用するJavaScript実行環境です。Node.jsがインストールされている環境では、先ほどの hoge.js を次のようにターミナル (PowerShellやコマンドプロンプト) から実行できます。HTMLの内部から呼び出すことなく直接的に実行できる点に注意してください。

PS C:\Users\xxxx\Desktop> node hoge.js
10 と 20 を足すと 30 です。
50 と -30 を足すと 20 です。

ウェブブラウザを使えば手軽に実行できる JavaScript を わざわざ Node.js 環境で実行する需要はどこにあるのでしょうか。需要は「大きく2つ」あります (ここから非常にややこしい話になるので注意してください)。

まず、1つは、ウェブアプリの バックエンド (サーバサイド) の実行環境 としての需要があります。既に皆さんは 前期の「知能情報実験実習1」のなかで Flask (Python) を使ってウェブアプリのバックエンド開発 を体験していますが、それと同様に JavaScript/TypeScript でもバックエンド開発 ができます。

具体的にはExpress.jsKoa.jsといったフレームワークを利用して JavaScript/TypeScript 言語でバックエンド開発が可能なのです。そして、そのための実行環境として Node.js が使われます (フロントエンドも、バックエンドも同じ言語で開発できるのはメリットですよね)。

参考

PythonではFlaskを用いて次のようにウェブアプリ (バックエンド) を構築できました。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
  return 'hello'

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=8000)

JavaScriptではExpress.jsというフレームワークを使って、次のようにウェブアプリのバックエンドを構築できます。このプログラムは、Node.js がインストールされた環境で node app.js というコマンドで実行ができます。ウェブブラウザ上では実行できないタイプの JavaScriptプログラム となっています。

const express = require('express');
const app = express();
const port = 8000;

app.get('/', (req, res) => {
  res.send('hello');
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

なお、Pythonで本格的なバックエンド開発を際には、Flask ではなくDjango (ジャンゴ)という多機能な (フルスタックな) フレームワークが利用されます。

次に、2つめですが「ウェブブラウザを実行環境として動作するフロントエンドのJavaScriptプログラム」を開発するときに、そのビルド (TypeScript から JavaScript へのトランスパイルを含む) や、開発ツールの実行のために Node.js 環境が使われます

たとえば、React を使ったフロントエンド開発典型的な Node.js の利用シーンとなります。Reactは、あくまでも「ウェブブラウザを実行環境として機能するフロントエンド用のJavaScriptライブラリ」ですが、その React を使った JavaScriptプログラム を効率的に開発するために Node.js という JavaScriptの実行環境 が必要になってきます (ややこしいですよね)。

簡単にまとめると Reactでつくられたフロントエンドのウェブアプリはウェブブラウザで動作するが、開発中のビルドやツールの利用のために Node.js が必要になる ということです。

・・・とはいえ、いまの段階で、上記の文章だけを読んでイメージを掴むことは極めて難しいと思います。これらは、この先の授業のなかで実例を示しながら解説していきます。いますぐ解決したいときは、生成AIを活用してください。

(プロンプト例)

Reactはウェブブラウザで動作するフロントエンドのライブラリなのに、その開発に何故 Node.js が必要なのですか?Node.jsを使わずに開発はできないのですか?

なお、後半 (第06回講義以降?) で登場する「Next.js」は、上記で説明した 2つの Node.js の用途を統合したようなフレームワーク になっています。つまり、Node.jsによって「フロントエンド開発の効率化」と「バックエンド機能の提供」を同時に実現し、総合的なフルスタック開発・実行環境を提供しています (ここの部分も現段階で理解する必要はありません)。

3.2.1 定着確認

4 Node.js のインストール

理由はさておき、React や Next.js を使用したウェブウェブアプリの開発 (TyepScript から JavaScriptへの変換を含む) には Node.js 環境が事実上必須である ことが分かったと思います。

ここでは、Windows PC に Node.js をインストールする手順について示します。なお、この講義資料に記載するプログラムは Node.js v20 (LTS) で動作確認をしています。特段の理由がない限り v20 のバージョンを使用してください。

なお、既に Node.js をインストール済みの場合、再インストールする必要はありません。

4.1 インストーラのダウンロード

Node.js の公式ページ (https://nodejs.org/en/download/prebuilt-installer) から Node.js の v20 (LTS) をダウンロードしてインストールしてください。LTSlong-term support の略語で「長期サポート」を意味します。v20 は 2026年4月30日 までサポートが予定されています。

img

2024年9月12日現在、Node.js v20 系列の最新リリースは v20.17.0 です。もし、より新しいマイナーバージョンが公開されている場合は、そちらを利用してください。また、講義資料に記載されているバージョン番号を読み替えてください。

4.2 インストーラの実行

ダウンロードしたインストーラ node-v20.17.0-x64.msi を実行してください。インストーラからの要求があれば管理者権限を与えてください。インストールに関する設定は「全てデフォルトのまま」で問題ありません (特に変更必要とする項目はありません)

4.3 インストールできたことの確認

PowerShell から以下のコマンドを実行し「Node.js が問題なくインストールされていること」「Node.js に パス (path) が通っていること」を確認してください。コマンドプロンプト (cmd) を使用すると、一部の操作やレスポンスが違ってくるので注意してください。

PS C:\Users\xxxx> node -v
v20.17.0

なお、以下のコマンドで node のパス (=Node.jsの本体が配置されているフォルダ位置) が確認できます。

PS C:\Users\xxxx> where.exe node
C:\Program Files\nodejs\node.exe

5 npm 関連の初期設定

Node.js では「npm (Node Package Manager)」というツール使ってパッケージ (ライブラリ) の管理をします。ここでのパッケージとは「JavaScript でアプリの開発するために使用する各種ライブラリのこと」と考えてください。なお、パッケージは、ウェブ経由で取得するので npm を実行するときにはインターネットに接続している必要があります。

Node.js における npm は、Python における pip のようなもの と考えてください。

5.1 npm のバージョンアップ

次のコマンドで、グローバル環境での npm の最新版へのアップグレードと、そのバージョン確認を実行してください。 2024年9月12日現在、npm の最新リリースは 10.8.3 です。

PS C:\Users\xxxx> npm install -g npm
PS C:\Users\xxxx> npm -v
10.8.3

ここで npm install は、npmパッケージをインストールするコマンドです。-g オプションは「グローバル環境」を指定しています。上記のコマンドは複数回実行しても問題ありません。

なお、グローバル環境には 最低限のパッケージだけをインストールすることが推奨 されます。個別の開発で必要なパッケージは、後述する方法でプロジェクトフォルダのなかの node_modules フォルダに ローカルインストール することが推奨されます。

明示的に -g (または --global) オプションを付けない限りnpm を実行したときはプロジェクトフォルダ内のローカル環境にインストールされます。

5.2 TypeScript のインストール

次のコマンドにより、TypeScript をグローバル環境にインストールしてください。これにより、TypeScript を JavaScript にトランスパイルする tsc などのコマンドが使用可能になります。

PS C:\Users\xxxx> npm install -g typescript

ここが、うまくいかないときは、Volta などの他のパッケージマネージャがインストールされている可能性があります。Volta をアンインストールするか、あるいは、以降のパッケージ管理を全て Volta に読み替えるなどで対応してください。

5.3 グローバル環境にインストールされたパッケージの確認

グローバル環境にインストールされたパッケージの一覧は、次のようなコマンドで確認できます。

PS C:\Users\xxxx> npm list -g --depth=0
C:\Users\wada\AppData\Roaming\npm
+-- npm@10.8.3
`-- typescript@5.6.2

5.4 トランスパイルとJavaScriptプログラムの実行

ここまでの環境構築により、Node.js環境で「トランスパイル」と「JavaScriptプログラムの実行」ができるようになりました。実際に、これらを試していきます。

以下のTypeScriptプログラムをtest.tsという名前でデスクトップ (C:\Users\xxxx\Desktop>) に保存してください。

function greetAndCalculate(name: string, a: number, b: number): string {
  const sum: number = a + b;
  return `Hello, ${name}! The sum of ${a} and ${b} is ${sum}.`;
}

const userName: string = "Alice";
const x: number = 10;
const y: number = 20;

const result: string = greetAndCalculate(userName, x, y);
console.log(result);

デスクトップ画面で [Shift] を押下しながら右クリックして「ターミナルで開く」を選択して PowerShell か コマンドプロンプト を開いてください。lsdir のコマンドで test.ts が存在することを確認してください。

img

以下のコマンドで test.tstest.js にトランスパイルしてください。ここで --target es6 オプションは、ES6 (ES2015) の使用に準拠した JavaScript (ECMASCript) に変換することを明示したものです。

PS C:\Users\xxxx\Desktop> tsc --target es6 test.ts

デスクトップに test.js (JavaScriptプログラム) が生成されているので、適当なテキストエディタで開いて内容を確認してください。

次に、以下のコマンド (node test.js) で実行してください。

PS C:\Users\wada\Desktop> node test.js
Hello, Alice! The sum of 10 and 20 is 30.

ここで失敗する場合は、「PowerShellから、スクリプトが実行できるように設定されていない可能性」があります。以下のコマンドでスクリプトの実行設定を変更して、ターミナルを開きなおして tsc ... を再実行してみてください。

C:\Users\xxxx> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force

5.4.1 演習

--target e6 のようにオプションを指定しない場合、「ES5」という古い仕様に準拠した JavaScriptプログラム (= Internet Explorer 11 のようなレガシーなブラウザでも動作する JavaScript プログラム) が出力されます。実際に確認してみてください。

また、そのプログラムでも、同様の実行結果 (=Hello, Alice! The sum of 10 and 20 is 30.) が得られることを確認してください。

5.4.2 定着確認

6 TypeScriptの基礎学習のための環境構築

TypeScriptの基礎学習用のプロジェクトフォルダを作成して「環境の構築」を行ないます。次回以降の授業でも継続的に使用していく予定なので (課題として提出してもらう可能性もあるので)、プロジェクトフォルダの位置や名前などには、十分に注意してください。

6.1 プロジェクトフォルダの作成

適切な位置 (OneDrive管理下はお勧めしません) に、learn-ts-basics というプロジェクトフォルダを作成して VSCode で開いてください。なお、必ず learn-ts-basicsVSCodeのワークスペースのトップフォルダ(ルートフォルダ) となるようにしてください。

img

ターミナルから実行するのであれば、以下のようにしてください。この方法であれば、learn-ts-basics が確実に VSCodeのワークスペースのトップフォルダになります。

mkdir learn-ts-basics
cd learn-ts-basics
code .

6.2 TypeScriptの設定 (1)

実際のReact開発に近しい環境を構築して、そこで TypeScript の基礎学習をしていきます。具体的には npm によるパッケージ追加や、ファイル変更を監視してのホットリロード設定 (=自動的にトランスパイル、ビルドして再読み込みして実行すること) などを行なった環境を構築して、TypeScript の基礎を学んでいきます。

まずは、TypeScript に関する基本設定 から行なっていきます。

VSCodeで [Ctrl]+[j] のショートカットでターミナル (PowerShell) を開いて、以下のコマンドを実行してください。

tsc --init

tsc は先ほどのトランスパイルに使ったコマンドです。tsc --init のようにオプションをつけて実行すると、トランスパイルに関する各種設定が記述された tsconfig.json という雛形ファイルが作成されます。

コマンド実行後、プロジェクトフォルダに tsconfig.json が作成されているはずなので、VSCode上で開いてください。大量の設定が羅列されていますが、大半がコメントアウトで無効になっています。

コメントアウトを含んでいると分かりずらいので コメントされた文は全て「削除」して保存 してください。以下のような内容だけが残ると思います。これらは tsc コマンドによるトランスパイル (コンパイル) のオプション設定となります。

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

JSONファイルでは 最後の項目以外の各項目の末尾にカンマ (,) が必要です。これを忘れるとエラーの原因となるので注意してください (VSCodeでエラーを表す波線が表示されます)。

6.2.1 演習

tsconfig.json の各項目が意味することを「生成AI」を利用して簡単に把握してください (詳細に理解する必要はありません、ざっくりと理解してください)。

(プロンプトの例)

TypeScript の設定ファイル tsconfig.json を以下に示します。各項目の意味について TypeScript 初心者向けに概要を説明してください。

esModuleInteropの設定について

"esModuleInterop":true は、プロジェクトフォルダに含まれるTypeScriptファイルを「独立したモジュールとして扱うように TypeScript コンパイラに指示する設定」です。

各ファイルがモジュールとして扱われることで「ファイル間のグローバルスコープの共有が防止」されます。例えば、これを設定していないと foo.ts に記述した cosnt hoge="hoge" と、別ファイル bar.ts に記述した cosnt hoge="hoge" で競合が発生することになります。

6.3 TypeScriptの設定 (2)

Typescriptの基礎学習用に tsconfig.json を次のようにカスタマイズしてください。

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "outDir": "./dist" /* 追加 */,
    "rootDir": "./src" /* 追加 */,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  } /* カンマをつけないとダメ!!! */,
  "include": ["src/**/*"] /* 追加 */
}

ここで追加した設定が項目の意味は次のとおりです。

6.3.1 定着確認

6.4 フォルダの作成

現時点でプロジェクトフォルダのなかに srcdist のフォルダが存在していないので作成してください。

img

なお、VSCodeの フォルダアイコンファイルアイコン をいい感じにしたいときは、拡張機能の Material Icon Theme (識別子:pkief.material-icon-theme) をインストールしてください。プログラミング1の授業でも紹介ずみです。

6.5 TSファイルの作成とトランスパイルによるJSファイルの出力と実行

ここまでの環境構築が問題なくできているかを確認していきます。src フォルダに prac00.ts というファイル (Practiceの略語) を作成して、以下の TypeScriptプログラム を貼り付けて保存してください。

function greetAndCalculate(name: string, a: number, b: number): string {
  const sum: number = a + b;
  return `Hello, ${name}! The sum of ${a} and ${b} is ${sum}.`;
}

const userName: string = "Alice";
const x: number = 10;
const y: number = 20;

const result: string = greetAndCalculate(userName, x, y);
console.log(result);

次に、トランスパイルして動作確認します。VSCodeのターミナル ([Ctrl]+[J]でオープン) で以下のコマンドを実行してください。

tsc
node dist/prac00.js

先ほどは tsc --target es6 prac00.ts のように引数を指定しましたが カレントフォルダに tsconfig.json があり、その設定が参照される ので引数は不要です。

node dist/prac00.js によって、Hello, Alice! The sum of 10 and 20 is 30. のような文字列が出力されれば、ここまでの設定が正しくできています。

6.6 開発を効率的に行なうためのパッケージの追加

ここまでの設定で「TypeScriptを書いて実行する最低限の環境」が構築できました。

ここからは 効率的にTypeScript開発を進める ための環境構築をしていきます。React や Next.js を開発するときにも関係してくる内容となります (package.jsonなど)。

まず、開発に必要なパッケージ (ライブラリ) として typescriptts-nodenodemon@types/node を、プロジェクトのローカル環境にインストールしていきます。なお、typescript については既にグローバル環境にインストール済みですが、改めてローカル環境にもインストールしておきます。

以下のコマンドで 4つのパッケージをまとめてインストールすること ができます。

npm i -D typescript ts-node nodemon @types/node

また、以下のコマンドでも同じことができます。

npm install --save-dev typescript ts-node nodemon @types/node

ここで i または install はパッケージの「インストール操作」を意味します。-D または --save-dev は、開発のときだけに使うパッケージ (=プロダクトとしての出力には含めないパッケージ) としてインストールすることを意味します。

コマンド実行後、プロジェクトフォルダのなかに node_modules フォルダと、package.jsonpackage-lock.json という2個のファイルが自動作成されたことを確認してください。

img

node_modules フォルダには、npm install コマンドで インストールされたパッケージ (本体) と、そのパッケージと依存関係にあるパッケージ (本体) が格納されています。基本的に、皆さんがこの node_modules フォルダを操作することはありません。

package.jsonpackage-lock.json自分のプロジェクトが依存するパッケージ (=外部ライブラリ) を管理するため のファイルになります。Pythonでいうところの requirements.txt \(+\ \alpha\) が記述されたファイルと考えてください。

6.6.1 定着確認

6.7 ホットリロードの設定

先のセクションでインストールした nodemon (ノードモン) を利用して src フォルダ以下の TypeScriptファイル (.tsファイル) を監視し、変更があればプログラムが自動的に再実行されるように設定します。この設定により プログラムを変更後に、ターミナルで tsc ***.tsnode dist/***.js のようにコマンド入力をする必要がなくなります。

React や Next.js 開発においても(nodemon とは異なる仕組みですが)ファイルの変更を監視してホットリロードする環境を構築して開発を進めます。

まずは、package.json を次のように変更 ("scripts" セクションを追記) してください。追記するする際には カンマ (,) に注意してください。

{
  "devDependencies": {
    "@types/node": "^22.7.4",
    "nodemon": "^3.1.7",
    "ts-node": "^10.9.2",
    "typescript": "^5.6.2"
  }
}
{
  "devDependencies": {
    "@types/node": "^22.7.4",
    "nodemon": "^3.1.7",
    "ts-node": "^10.9.2",
    "typescript": "^5.6.2"
  },
  "scripts": {
    "start": "node dist/index.js",
    "build": "tsc",
    "dev": "nodemon --watch src --ext ts --verbose --exec ts-node src/index.ts"
  }
}

ここで package.json に追加した "scripts" セクションは プロジェクトで頻繁に使用するコマンドをショートカットとして定義 する場所になります。これにより、多数のオプションをつけた複雑なコマンドも簡単に実行できるようになります。

具体的には npm run start とコマンド入力すると node dist/index.js が実行されるようになります。

また npm run dev とコマンド入力すると nodemon --watch src --ext ts --verbose --exec ts-node src/index.ts が実行されるようになります。

なお、npm run start だけは npm start のように省略できますが、他のスクリプト (npm run dev) などは省略できません。

ここでは、各スクリプトを以下のような処理をするように割り当てました。

6.8 index.ts に prac00.ts を読み込む

TypeScriptの基礎学習では prac00.tsprac01.tsprac02.ts のようにファイルを追加作成して、課題 (練習問題) に取り組んでもらいます。

これらのファイルを追加した際も npm run dev のコマンドで実行確認できるように index.ts というファイルをつくって、そこに各ファイル (prac00.tsprac01.tsprac02.ts・・・) を読み込ませるようにしていきます。

例えば prac00.ts に記述したプログラムの実行確認をしたいときは、以下のように index.ts を記述します。

console.log("■ prac00.ts の実行");
import "./prac00";

また、次の課題 prac01.ts に取り組むときは以下のようにします。TypeScript/JavaScript は // でコメントアウトします。

// console.log("■ prac00.ts の実行");
// import "./prac00";

console.log("■ prac01.ts の実行");
import "./prac01";

実際の開発では、上記の import "./prac00"; のように ファイル名のみでインポートすること はほとんどありません。実践での import の使用法方法については、それが必要になったタイミングで解説します。

6.9 練習

ここまでに構築した環境を実際に使ってみたいと思います。src フォルダに、次のような index.tsprac01.ts を作成してください。

// console.log("■ prac00.ts の実行");
// import "./prac00";

console.log("■ prac01.ts の実行");
import "./prac01";
const userName: string = "Bob";
console.log(`Hi, ${userName}.`);

このようにすると、(環境にもよると思いますが) 以下のように prac00.tsprac01.ts の両方で記述されている userName という変数について「ブロック スコープの変数 ‘userName’ を再宣言することはできません」のようなエラーがでると思います。

img

これは、package.json のなかで "esModuleInterop": true (=各ファイルを独立したモジュールとして扱うように TypeScript コンパイラに指示する設定) を記述しているものの、それが VSCode でうまく認識されていないことに起因します。

つまり、VSCode に「prac00.ts prac01.ts に記述されているプログラムが、同じスコープにある (=同じスコープのなかで userName という変数が再宣言されている)」と判断されてエラーとなっています。

これを解決するためには prac00.tsprac01.ts の先頭に export {}; を記述します。これにより、VSCode においても、各ファイルがモジュールとして正しく認識されます。

具体的には、以下のようにファイルを書き換えて、再保存してください。

export {}; // ファイルをモジュールとして扱いスコープを分離するために必要

function greetAndCalculate(name: string, a: number, b: number): string {
  const sum: number = a + b;
  return `Hello, ${name}! The sum of ${a} and ${b} is ${sum}`;
}

const userName: string = "Alice";
const x: number = 10;
const y: number = 20;

const result: string = greetAndCalculate(userName, x, y);
console.log(result);
export {}; // ファイルをモジュールとして扱いスコープを分離するために必要
const userName: string = "Bob";
console.log(`Hi, ${userName}.`);

以上で、index.tsprac00.tsprac01.ts についてエディタ上のエラーは消えたと思います。

スコープとは

変数の スコープ (Scope) とは その変数が有効・参照可能な範囲 を表す概念です。前期の「プログラミング2」で学習済みのC言語を例に (念のために) スコープを復習しておきます。

#include <stdio.h>

int global_var = 10;

void func() {
  int func_var = 20;
  printf("global_var = %d, func_var = %d\n", global_var, func_var);
}

int main() {
  int main_var = 30;
  printf("global_var = %d, main_var = %d\n", global_var, main_var);
  for (int loop_var = 0; loop_var < 3; loop_var++) {
    printf("global_var = %d, main_var = %d, loop_var = %d\n", 
            global_var, main_var, loop_var);
  }
  func();
  return 0;
}

上記のプログラムの各変数 (global_varmain_varfunc_varloop_var) のスコープは、次のようになります。

6.10 開発モードでプログラムの実行

実際に「開発モード」でプログラムを実行していきます。

VSCodeでターミナルを開いて npm run dev を実行してください。以下のような文字列が出力されるはずです (実際には 以下の文字列の前後には [nodemon] のマークがついたログ もあわせて出力されます)。

■ prac01.ts の実行
Hi, Bob.

つづいて、prac01.ts第03行目console.log(`Hey, ${userName}.`);に書き換えて 保存 してください。nodemon がファイル変更 (更新) を検知して、自動的にプログラムが再実行され、以下のように出力されるはずです。

■ prac01.ts の実行
Hey, Bob.

さらに、index.ts第01行目第02行目 のコメントアウトを解除して保存してください。今度は、次のような出力が得られると思います。

■ prac00.ts の実行
Hello, Alice! The sum of 10 and 20 is 30
■ prac01.ts の実行
Hi, Bob.

nodemon を停止するには、ターミナルで [Ctrl]+[C] を押下します。バッチ ジョブを終了しますか (Y/N)? と聞かれるので Y を入力するか、再度 [Ctrl]+[C] を押下すれば nodemon が停止します。

6.11 本番モードでプログラムの実行

次に「本番モード」でプログラムを実行してみます。

ターミナルからの次のようにコマンドを入力してください。なお npm run start については、npm start に省略して実行も可能です。

npm run build
npm run start

dist フォルダに JavaScriptファイル が出力され、それが実行されます。

7 Git/GitHub管理

ここまで作成してきたプロジェクトフォルダについてGit管理を有効化し、さらに GitHub に公開していきます。Git / GitHub 基本設定は既に完了しているものとします。未設定の場合はPG1の講義資料を参照して設定してください。

7.1 .gitignore の設定

プロジェクトフォルダのトップ階層に .gitignore を作成して node_modules フォルダを Gitの管理対象外 に設定します。node_modules には (パッケージのインストール状況によっては) 何千ものファイルが含まれるため、必ず .gitignore に含めるようにしてください。

以下のように .gitignore を作成して保存してください。

/node_modules

現状で以下のようなプロジェクトフォルダの構成になっているはずです。

img

以下の手順で、このプロジェクトフォルダを GitHub に Public なリポジトリとして発行してください。

img
img

問題なく発行できれば、以下のようにウェブブラウザからリポジトリが確認できるハズです。

img

あとは、定期的にファイルの変更、ステージング、コミット、プッシュを行なってください。

7.1.1 演習

開発環境の構築は、一度操作しただけでは理解も定着もしないので (授業時間外に) 再度構築してみてください

ローカル環境 (ローカルリポジトリ) は、エクスプローラからプロジェクトフォルダを削除すれば完全に消去できます。GitHubリポジトリはウェブブラウザから操作して削除することができます。

7.2 補足: フォーマッタのインストール と おまけ

TypeScript/JavaScript および HTML/CSS の コード整形 (フォーマット) のために Prettier (識別子: esbenp.prettier-vscode) という VSCode の拡張機能をインストールしておいてください。

img

vscode-pets (識別子: tonybaloney.vscode-pets) は、役に立ちませんがおすすめです。ペットの種類や背景は、VCCodeの設定項目の ここから 変更できます。

img

8 モダンTypeScript入門

TypeScript の 開発環境が構築できたので、ここから (本格的には次週の講義から) モダンTypeScript について学んでいきます 。

8.1 コンソールメソッド

コンソールメソッドは console.log("Hello, World!") のように使用するもので 主にデバッグや開発時の情報出力に利用します。Pythonの print 関数、C言語の printf 関数 に相当するものと考えてください。

コンソールメソッドには console.log()console.error()console.warn()console.info()console.debug() などの種類が存在します。これらは、C言語の fprintf(stdout, ...)fprintf(stderr, ...) のように使い分けます。

実行環境によっては、ログレベル (log, error, warn…) に応じて、色分けや装飾付きで出力されたり、フィルタリングする機能 (=特定のレベル以上のメッセージのみを表示) が提供されます。しかし、最初のうちは使い分けは考えずに console.log() だけの使用 (もしくは console.error() との2つの使い分け) で十分です。

例えば、namepriority という2つの変数を出力したいときは、以下のように カンマ区切り で記述します。実際にprac01.ts に記述して実行確認してください。ターミナルから npm run dev もしくは、tsc のあとに node dist/index.js で実行できます (基本操作として覚えておいてください)。

export {};
// 文字列型 (string type) の変数 name の宣言と初期化
let name: string = "TypeScriptの勉強";
// 数値型 (number type) の変数 priority の宣言と初期化
let priority: number = 3;
console.log(name, priority);

(すこし分かりづらいですが) 以下のようにスペースで区切られて name と priority が出力されます。

■ prac01.ts の実行
TypeScriptの勉強 3

8.1.1 演習 (15分)

次のような Date型 (日付・日時型) の変数 deadline を追加して、コンソールメソッドで出力してください。

// Date型の変数 deadline の宣言と初期化
let deadline: Date = new Date(2024, 10, 2, 11, 45);

Month (月) の扱いに注意が必要なことに気づいたでしょうか?また、コンソールメソッドで出力される時刻フォーマットが ISO 8601形式 であることに注意してください。

上記の prac01.ts は、次のようなC言語プログラムに相当します。C言語では 型名 変数名 = 初期値; のように変数宣言しましたが、TypeScriptでは 変数名 : 型名 = 初期値; のようにするので注意してください (順番が逆になることに慣れてください)。

#include <stdio.h>
int main() {
  char name[50] = "TypeScriptの勉強";
  int priority = 3;
  fprintf(stdout, "%s, %d\n", name, priority);
  return 0;
}

8.2 変数宣言キーワード

TypeScript において、変数宣言のキーワードとしては letconstvar が使用でます。このうち、var は、原則として使用しません (この背景や理由は「ウェブ検索」もしくは「生成AI」で解決してください)。

また、初期化後、変更予定のない変数 (定数) については const を使用してください。

この科目で扱う範囲のウェブアプリ開発では、9割以上の変数は const で対応可能です。さきほどの prac01.ts においても namepriority は、初期化以降、変更される予定がないので、以下のように記述することが強く推奨されます (モダンTypeScript においてコード品質や可読性を高めるためのガイドラインとなっています)。

export {};
const name: string = "TypeScriptの勉強";
const priority: number = 3;
console.log(name, priority);

小テストや課題においても、変更されることがない変数 (定数) については const で宣言してください。letvar による冗長な変数宣言は誤答または減点とします。

8.3 テンプレート文字列

TyepScriptにおける「テンプレート文字列」とは、Pythonにおける f文字列 に相当するものです。バッククォートで囲んで「$マーク」と「波括弧」を組わせて使用します。

テンプレート文字列の使用例を以下に示します。

export {};
const name: string = "TypeScriptの勉強";
const priority: number = 3;
console.log(`Todo 1 => ${name}(優先度:${priority})`); // テンプレート文字列

以下のような出力が得られます。

■ prac01.ts の実行
Todo 1 => TypeScriptの勉強(優先度:3)

Pythonとは異なり、$マークをつけなければいけない点に、十分に注意してください。

8.4 オブジェクトのコンソール出力 (1)

ウェブアプリ開発では 複数の変数をオブジェクトにまとめて扱うこと が非常に多いです。ここでのオブジェクトとは、プログラミング1で「オブジェクト指向プログラミング」を学んだときの「オブジェクト」と同じものです。

ただ、TypeScript (特にフロントエンド開発) では クラス は定義・使用せずに オブジェクトを直接記述してプログラムのなかで使うケース が多いです。その場合、メソッドを持たないプロパティ(属性)のみで構成されるオブジェクトになることが多いです (その意味では、C言語の「構造体」に近いと思います)。

さきほどの prac01.ts は、以下のような オブジェクトリテラル記法 (オブジェクトを直接的に記述する方法) で、以下のように書き換えることができます。

export {};
const todo = {
  name: "TypeScriptの勉強", // name = "..." ではない点に要注意
  priority: 3, // priority = "..." ではない点に要注意
};
console.log(`Todo 1 => ${todo.name}(優先度:${todo.priority})`);

オブジェクトリテラル記法では = ではなく : で値を与えること に注意してください (初心者がよく間違える/混乱するところです)。

また、オブジェクトのプロパティ (属性、フィールド) には、第06行目 のようにドット (.) を使ってアクセスができます。

8.5 オブジェクトのコンソール出力 (2)

オブジェクト全体を出力したいとき (オブジェクトの内容確認したいとき) は console.log(todo); のようにします。例えば、上記の todo は以下のように出力されます。

{ name: 'TypeScriptの勉強', priority: 3 }

ただし、オブジェクトが 多数のプロパティを持つとき配列を含むときconsole.log() にオブジェクトを与えるだけでは非常に見づらくなります。このようなときは console.log(JSON.stringify(todo, null, 2)); のようにすることで、次のように整形された出力が得られます。

{
  "name": "TypeScriptの勉強",
  "priority": 3
}

ここで、JSON.stringify() は、オブジェクトをJSON (=JavaScript Object Notation) 文字列に変換するメソッドです。第1引数にオブジェクトを与え、第2引数を null、第3引数を 2 を与えると、上記のように改行とインデント (スペース2文字で字下げ) された文字列を得ることができます。

なお、JSON文字列に変換するとプロパティ (例えば name ) が ダブルクォーテーションで囲まれて出力される など、直接出力した場合と差異があるので注意してください。

8.5.1 定着確認

9 授業時間外学習