はい、承知いたしました。Node.jsの始め方と開発環境構築に焦点を当てた、約5000語の詳細な記事を作成します。
【初心者必見】Node.jsの始め方と開発環境構築ガイド
はじめに:Node.jsの世界へようこそ
プログラミングの世界へようこそ!特にWeb開発に興味がある方にとって、Node.jsは現代の技術スタックにおいて非常に重要なツールとなっています。しかし、初めてNode.jsに触れる方にとっては、「一体何から始めればいいのか」「開発環境ってどうやって作るの?」といった疑問が山積しているかもしれません。
この記事は、まさにそんなあなたのためのガイドです。Node.jsの基本的な概念から始まり、開発環境の構築、簡単なプログラムの作成、そして実際のWebアプリケーション開発の入り口まで、ステップバイステップで丁寧に解説していきます。約5000語にわたる詳細な説明を通じて、Node.jsの世界へ安心して踏み出せるよう、徹底的にサポートします。
さあ、私たちと一緒に、Node.jsを使った素晴らしい開発の旅を始めましょう!
Node.jsとは何か?
Node.jsは、Google ChromeのJavaScriptエンジンであるV8をベースに構築された、サーバーサイドJavaScript実行環境です。これだけでは少し難しく聞こえるかもしれませんね。もっと簡単に言うと、通常Webブラウザの中でしか動作しないJavaScriptというプログラミング言語を、Webサーバーやパソコン上で動かせるようにしたもの、と理解してください。
かつて、サーバーサイドのプログラミングにはPHP、Ruby、Python、Javaなどの言語が主流でした。しかしNode.jsの登場により、JavaScriptという単一の言語で、Webブラウザで動くフロントエンド(ユーザーが直接目にする部分)も、サーバーで動くバックエンド(データ処理やデータベース連携など見えない部分)も開発できるようになりました。これは、開発者にとって非常に大きなメリットをもたらします。
なぜNode.jsを学ぶべきなのか?
- フルスタック開発の可能性: JavaScriptだけでフロントエンドとバックエンドの両方を開発できるため、学習コストを抑えつつ、Webアプリケーション全体をカバーする「フルスタック開発」を目指せます。
- 高いパフォーマンス: Node.jsはノンブロッキングI/O(入出力)とイベント駆動モデルを採用しているため、多くの同時接続を効率的に処理できます。リアルタイムアプリケーション(チャット、オンラインゲームなど)との相性が抜群です。
- 巨大なエコシステム(npm): Node.jsには「npm (Node Package Manager)」という世界最大のパッケージマネージャーがあります。これにより、世界中の開発者が作成した便利なライブラリやツールを簡単に利用でき、開発効率を大幅に向上させることができます。
- 活発なコミュニティと豊富な学習リソース: Node.jsは世界中で広く利用されており、活発なコミュニティと豊富なドキュメント、チュートリアルが存在します。困ったときでも、解決策を見つけやすい環境です。
- 多様な用途: Webアプリケーションのバックエンドだけでなく、コマンドラインツール、デスクトップアプリケーション、APIサーバーなど、多岐にわたる開発に利用できます。
Node.jsで何ができるのか? (具体例)
- APIサーバー/Webサーバー: スマートフォンアプリやWebサイトのバックエンドとして、データの取得や保存を行うAPI(Application Programming Interface)サーバーを構築できます。人気のフレームワークにExpress.jsがあります。
- リアルタイムアプリケーション: チャットアプリ、オンラインゲーム、共同編集ツールなど、ユーザー間でリアルタイムに情報がやり取りされるアプリケーションを構築できます。Socket.ioなどが利用されます。
- コマンドラインツール (CLIツール): プロジェクトの自動化や開発作業を効率化するための便利なツールを自作できます。
- ストリーミングアプリケーション: 音楽や動画などのメディアを効率的に配信するサーバーを構築できます。
- マイクロサービス: 大規模なシステムを小さな独立したサービスに分割するアーキテクチャに適しています。
この記事の対象読者とゴール
対象読者:
* プログラミング初心者で、これからNode.jsを学びたい方。
* JavaScriptの基本的な構文(変数、関数、条件分岐、ループなど)は知っているが、Node.jsは初めてという方。
* 開発環境の構築につまづいている方。
ゴール:
* Node.jsの基本的な概念を理解する。
* 自分のPCにNode.jsの開発環境を構築できる。
* 簡単なNode.jsプログラムを作成し、実行できる。
* npmを使ったパッケージ管理の基礎を習得する。
* Node.jsを使ったWebアプリケーション開発の第一歩を踏み出す。
それでは、Node.jsの世界への第一歩を踏み出しましょう!
第1章:Node.jsを始める前に知っておくべきこと
Node.jsをスムーズに学習するために、いくつかの予備知識があると役立ちます。もし完全に初心者で、これらの概念がまだ朧げでも大丈夫です。この記事を読み進める中で徐々に慣れていきましょう。
プログラミングの基礎知識(あれば望ましい)
Node.jsはJavaScriptで書かれます。したがって、プログラミング全般、特にJavaScriptの基本的な概念を理解していると学習が捗ります。
- 変数: データに名前をつけて保存する箱のようなもの。
- データ型: 数値、文字列、真偽値(true/false)など、データの種類。
- 演算子: 計算や比較を行う記号(+, -, *, /, ==, === など)。
- 条件分岐: 特定の条件に基づいて処理を変える(if/else文)。
- 繰り返し(ループ): 同じ処理を何度も繰り返す(for文、while文)。
- 関数: 特定の処理をひとまとまりにして、名前をつけ再利用可能にするもの。
- 配列とオブジェクト: 複数のデータをまとめて扱うための構造。
これらの概念に不安がある方は、先にJavaScriptの入門書やオンラインチュートリアルで基本的な構文を学んでおくことをお勧めします。
JavaScriptの基礎(軽く触れる)
Node.jsはJavaScriptで書かれているため、JavaScriptの基礎知識は必須です。Webブラウザで動作するJavaScript(DOM操作など)と、Node.jsで動作するJavaScript(ファイルシステム操作、HTTPサーバー構築など)では、利用できる機能が異なりますが、基本的な言語構文は同じです。
Node.jsでは特に以下のJavaScriptの概念が頻繁に登場します。
- 非同期処理 (Asynchronous Programming): Node.jsの根幹をなす概念です。時間がかかる処理(ファイルの読み書き、ネットワーク通信など)を待たずに、次の処理を実行する仕組みです。これについては後ほど詳しく解説します。
- モジュール: コードを機能ごとに分割し、再利用可能にする仕組みです。Node.jsではCommonJSとES Modulesの2つのモジュールシステムが使われます。
- コールバック関数、Promise、Async/Await: 非同期処理を扱うための主要なパターンです。
コマンドライン(ターミナル/コマンドプロンプト)の基本操作
Node.js開発では、コマンドライン(CUI: Character User Interface)を頻繁に利用します。プログラムの実行、パッケージのインストール、プロジェクトの初期化など、多くの作業をコマンド入力で行います。
お使いのOSによって呼び名が異なります。
* Windows: コマンドプロンプト、PowerShell
* macOS: ターミナル
* Linux: ターミナル
最低限覚えておきたいコマンドは以下の通りです。
pwd
(macOS/Linux) /cd
(Windows): 現在のディレクトリ(フォルダ)を表示ls
(macOS/Linux) /dir
(Windows): 現在のディレクトリ内のファイルやフォルダを表示cd <directory_name>
: 指定したディレクトリに移動cd ..
: 一つ上のディレクトリに移動mkdir <directory_name>
: 新しいディレクトリを作成clear
(macOS/Linux) /cls
(Windows): 画面をクリア
これらのコマンドを使いこなすことで、開発作業の効率が格段に上がります。最初は少し難しく感じるかもしれませんが、繰り返し使ううちに慣れてきますので安心してください。
第2章:Node.jsの開発環境を構築しよう
いよいよNode.jsを動かすための環境を構築します。この章が最も重要なステップの一つです。焦らず、一つずつ確実に進めていきましょう。
Node.jsのインストール
Node.jsをインストールする方法はいくつかありますが、ここでは初心者の方にとって最も推奨される方法をいくつか紹介します。
1. 公式インストーラーを使った方法 (Windows/macOS)
Node.jsの公式サイトから提供されているインストーラーを使用する方法です。最も手軽で、特別な設定なしにNode.jsとnpmが同時にインストールされます。
- Node.js公式サイトにアクセス:
https://nodejs.org/ja/ - 推奨版をダウンロード:
サイトにアクセスすると、2種類のバージョンが表示されます。- LTS (長期サポート版): 安定しており、長期間サポートされるバージョン。初心者はこちらを選ぶのが安全です。
- Current (最新版): 最新の機能が追加されていますが、LTSより安定性に欠ける場合があります。
「推奨版」と書かれたLTSバージョンをダウンロードしてください。
- インストーラーを実行:
ダウンロードしたインストーラーファイル (.msi
for Windows,.pkg
for macOS) をダブルクリックして実行します。 - 画面の指示に従ってインストール:
基本的には「Next」や「同意」を選択していけば問題ありません。- Windowsの場合、必要なツール(Python, Visual Studio Build Toolsなど)のインストールを促されることがありますが、これはNode.jsモジュールの一部がC++などのネイティブコードに依存する場合に必要になります。必須ではありませんが、後々困らないためにチェックを入れてインストールしておくと良いでしょう。
2. バージョン管理ツール (NVM, Volta) の利用推奨
開発を進める上で、複数のNode.jsバージョンを切り替えて使いたい場面が出てくることがあります(例:古いプロジェクトはNode.js 16、新しいプロジェクトはNode.js 20など)。このような場合、バージョン管理ツールを使うと非常に便利です。
特に初心者の方には、将来を見越してこれらのツールを使ったインストールを強くお勧めします。
NVM (Node Version Manager)
NVMは、Mac/Linuxユーザーに人気のNode.jsバージョン管理ツールです。
Mac/LinuxでのNVMインストール手順:
- ターミナルを開く
- NVMをインストール
以下のコマンドのいずれかを実行します。curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
(バージョン番号は最新のものを確認してください)wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
インストールが完了したら、ターミナルを再起動するか、source ~/.bashrc
(または~/.zshrc
,~/.profile
など) を実行して設定を反映させます。
- NVMのインストール確認
command -v nvm
nvm
と表示されれば成功です。 - Node.jsのインストール
NVMを使って最新のLTS版をインストールします。
nvm install --lts
または、特定のバージョンを指定する場合(例: v20.10.0):
nvm install 20.10.0
- 使用するNode.jsバージョンの指定
インストールしたNode.jsを使用するように指定します。
nvm use --lts
または、特定のバージョンを指定する場合:
nvm use 20.10.0
このコマンドで指定されたバージョンが現在のターミナルセッションで使われます。永続的に設定したい場合は、nvm alias default --lts
を実行します。 - インストール確認 (次のセクションで詳しく説明)
Volta
Voltaは、Node.jsだけでなく、npmやYarnといったパッケージマネージャーのバージョンも管理できるツールです。Windows、macOS、Linuxに対応しており、シンプルで使いやすいのが特徴です。
Voltaでのインストール手順:
- Volta公式サイトにアクセス:
https://volta.sh/ - インストールコマンドを実行:
サイトに表示されているインストールコマンドをコピーして、ターミナル(またはコマンドプロンプト/PowerShell)で実行します。- Windows (PowerShell):
Invoke-WebRequest -Uri https://get.volta.sh -OutFile install-volta.ps1; .\install-volta.ps1
- macOS/Linux (Bash/Zsh):
curl https://get.volta.sh | bash
インストールが完了したら、ターミナルを再起動します。
- Windows (PowerShell):
- Voltaのインストール確認
volta --version
バージョン番号が表示されれば成功です。 - Node.jsのインストール
Voltaを使ってNode.jsをインストールします。最新のLTS版をインストールするには:
volta install node@lts
または、特定のバージョンを指定する場合:
volta install [email protected]
Voltaはデフォルトでインストールしたバージョンを使用するよう設定してくれます。 - インストール確認 (次のセクションで詳しく説明)
3. インストール確認
Node.jsとnpmが正しくインストールされたかを確認しましょう。
- ターミナル(コマンドプロンプト/PowerShell)を開く
- Node.jsのバージョン確認:
node -v
または
node --version
インストールしたNode.jsのバージョン(例:v20.10.0
)が表示されれば成功です。 - npmのバージョン確認:
npm -v
または
npm --version
npmのバージョン(例:10.2.3
)が表示されれば成功です。
もし「コマンドが見つかりません」といったエラーが出た場合は、パスが正しく設定されていないか、インストールに失敗しています。ターミナルを再起動してみる、またはインストールの手順を見直してみてください。
npm (Node Package Manager) の概要
Node.jsをインストールすると、npm
も一緒にインストールされます。npmは、Node.jsで開発する上で不可欠なツールです。
npmとは何か?
npmは、Node.jsのパッケージマネージャーです。パッケージとは、他の開発者が作った再利用可能なコードの集まり(ライブラリ、フレームワーク、ツールなど)のことです。
npmの主な役割は以下の通りです。
* パッケージの公開と共有: 開発者が自分の作ったパッケージを公開し、他の人が利用できるようにします。
* パッケージのインストール: 公開されているパッケージを自分のプロジェクトにインストールします。
* パッケージの管理: インストールしたパッケージのバージョン管理や依存関係の解決を行います。
世界中の開発者が、日夜npmに新しいパッケージを公開しており、その数は数十万に上ります。これにより、ゼロから全てを開発する必要がなくなり、効率的な開発が可能になります。
よく使うnpmコマンド
コマンド | 説明 |
---|---|
npm init |
新しいNode.jsプロジェクトを初期化し、package.json ファイルを作成します。 |
npm install |
package.json に記述されているすべての依存パッケージをインストールします。 |
npm install <package-name> |
指定したパッケージをプロジェクトにインストールします。 |
npm uninstall <package-name> |
指定したパッケージをプロジェクトからアンインストールします。 |
npm update |
インストール済みのパッケージを更新します。 |
npm start |
package.json のscripts.start に定義されたスクリプトを実行します。 |
npm run <script-name> |
package.json のscripts に定義された任意のスクリプトを実行します。 |
エディタの準備
コードを書くためのエディタも用意しましょう。プログラミングの効率を上げるには、機能的で使いやすいエディタを選ぶことが重要です。
Visual Studio Code (VS Code) の推奨とインストール
Node.js開発においては、Visual Studio Code (VS Code) を強く推奨します。Microsoftが開発している無料のテキストエディタで、以下の理由からデファクトスタンダード(事実上の標準)となっています。
- 軽量かつ高速: 起動も動作も非常に軽快です。
- 多機能: コード補完、構文ハイライト、デバッグ機能、Git連携など、開発に必要な機能が豊富に揃っています。
- 豊富な拡張機能: npmエコシステムと同様に、VS Codeには膨大な数の拡張機能があり、様々な言語やフレームワークに対応できます。
- 強力なJavaScript/TypeScriptサポート: Node.js開発に最適化されています。
- クロスプラットフォーム: Windows、macOS、Linuxで利用可能です。
VS Codeのインストール手順:
- VS Code公式サイトにアクセス:
https://code.visualstudio.com/ - ダウンロード:
お使いのOSに合ったダウンロードボタンをクリックし、インストーラーをダウンロードします。 - インストーラーを実行:
ダウンロードしたファイルをダブルクリックして実行し、画面の指示に従ってインストールを進めます。
VS Codeのおすすめ拡張機能
VS Codeの魅力の一つは拡張機能です。Node.js開発に役立つ、いくつか基本的な拡張機能を紹介します。VS Codeを起動し、左側のアクティビティバーにある「拡張機能」アイコン(四角が3つ並んだもの)をクリックして検索、インストールできます。
- ESLint: JavaScriptのコード規約チェックと自動修正。質の高いコードを書くための強力な味方です。
- Prettier – Code formatter: コードのフォーマットを自動で行い、コードスタイルを統一します。チーム開発では特に重要です。
- DotENV:
.env
ファイル(環境変数を記述するファイル)のシンタックスハイライト。 - JavaScript (ES6) code snippets: よく使うJavaScriptのコードスニペット(定型文)を素早く挿入できます。
- GitLens — Git supercharged: Gitの履歴や変更をVS Code上で視覚的に分かりやすく表示します。
これらの拡張機能をインストールすると、開発効率が飛躍的に向上します。
基本的なVS Codeの操作
- ファイルを開く/フォルダを開く:
File
>Open File...
またはOpen Folder...
- 新しいファイル/フォルダの作成: エクスプローラービューで右クリック
- 統合ターミナル:
Terminal
>New Terminal
またはCtrl + @
(Windows/Linux),Cmd + @
(macOS)
このターミナルでNode.jsのコマンドを実行できます。
第3章:初めてのNode.jsプログラム
開発環境が整ったら、いよいよ初めてのNode.jsプログラムを書いて実行してみましょう。まずは定番の「Hello, World!」から始め、Node.jsの基本的な入出力とモジュールについて学びます。
「Hello, World!」の実行
プログラミング学習の第一歩は、決まって「Hello, World!」の出力です。
-
プロジェクトフォルダの作成
まず、どこか作業しやすい場所に新しいフォルダを作成します。ここでは例としてmy_first_node_app
という名前のフォルダを作成します。
ターミナルで以下のコマンドを実行します。bash
mkdir my_first_node_app
cd my_first_node_app -
VS Codeでフォルダを開く
VS Codeを起動し、File
>Open Folder...
から今作成したmy_first_node_app
フォルダを選択して開きます。 -
JavaScriptファイルの作成
VS Codeのエクスプローラービュー(左側)で、my_first_node_app
フォルダの上で右クリックし、「New File…」を選択します。ファイル名をapp.js
と入力し、Enterキーを押します。 -
コードの記述
app.js
ファイルに以下のコードを記述します。javascript
// app.js
console.log("Hello, Node.js World!"); -
Node.jsでの実行方法
VS Codeの統合ターミナルを開きます。(Terminal
>New Terminal
)
カレントディレクトリがmy_first_node_app
であることを確認し(pwd
またはcd
コマンドで確認)、以下のコマンドを実行します。bash
node app.jsターミナルに以下のように表示されれば成功です!
Hello, Node.js World!
おめでとうございます!これであなたはNode.jsプログラムを実行することができました。node
コマンドの後にJavaScriptファイルのパスを指定することで、そのファイル内のコードをNode.jsが実行してくれるのです。
基本的なI/O (入出力)
Node.jsでよく使う基本的な入出力を見ていきましょう。
console.log()
先ほど使った console.log()
は、指定した値をコンソール(ターミナル)に出力する関数です。デバッグや情報の表示によく使われます。
“`javascript
// console_example.js
let message = “Node.jsは楽しい!”;
let number = 123;
let arr = [1, 2, 3];
let obj = { name: “Alice”, age: 30 };
console.log(message);
console.log(“数値:”, number);
console.log(“配列:”, arr);
console.log(“オブジェクト:”, obj);
console.log(テンプレートリテラルも使えます: ${message}
); // ES6のテンプレートリテラル
// 実行: node console_example.js
“`
ユーザー入力の受け取り
Node.jsでユーザーからコマンドライン入力を受け取るには、組み込みの readline
モジュールを使うのが一般的です。
“`javascript
// user_input.js
const readline = require(‘readline’); // readlineモジュールを読み込む
const rl = readline.createInterface({
input: process.stdin, // 標準入力 (キーボード)
output: process.stdout // 標準出力 (画面)
});
rl.question(‘お名前を入力してください: ‘, (name) => {
console.log(こんにちは、${name}さん!
);
rl.close(); // インターフェースを閉じる
});
// 実行: node user_input.js
// プロンプトが表示されたら名前を入力してEnterを押す
``
readline` モジュールは非同期的に動作するため、入力完了を待ってからコールバック関数が実行されます。
このコードを実行すると「お名前を入力してください: 」と表示され、入力した内容が「こんにちは、〇〇さん!」と返されます。
モジュールの概念
Node.js開発における最も重要な概念の一つがモジュールです。モジュールとは、関連する機能やデータをひとまとまりにしたファイルのことです。
なぜモジュールが必要なのか?
* コードの整理: 大規模なプログラムを小さな部品に分割し、管理しやすくする。
* 再利用性: 一度書いたコードを他の場所で簡単に再利用できる。
* 名前空間の衝突回避: グローバルな変数や関数の衝突を防ぐ。
Node.jsでは、デフォルトで複数のモジュールシステムがサポートされています。
require()
と module.exports
(CommonJS)
Node.jsの初期から使われているモジュールシステムで、現在でも多くのプロジェクトで使われています。
module.exports
: モジュールから外部に公開したい変数や関数を定義します。require()
: 他のモジュールから公開された機能を取り込みます。
例:
calculator.js
(計算モジュール)
“`javascript
// calculator.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a – b;
}
// 外部に公開する関数をmodule.exportsに代入
module.exports = {
add: add,
subtract: subtract
};
“`
app.js
(計算モジュールを利用する側)
“`javascript
// app.js
// calculator.jsモジュールを読み込む
const calculator = require(‘./calculator’); // 相対パスで指定
console.log(‘2 + 3 =’, calculator.add(2, 3)); // 出力: 2 + 3 = 5
console.log(’10 – 5 =’, calculator.subtract(10, 5)); // 出力: 10 – 5 = 5
“`
import
と export
(ES Modules)
ES Modules (ESM) は、ECMAScript 2015 (ES6) で導入されたJavaScript標準のモジュールシステムです。ブラウザでもNode.jsでも利用できますが、Node.jsで利用するには設定が必要です。
Node.js v14以降では、デフォルトでES Modulesをサポートしていますが、ファイル拡張子を .mjs
にするか、package.json
に "type": "module"
を記述する必要があります。
例:
calculator.mjs
(計算モジュール – ES Modules版)
“`javascript
// calculator.mjs
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a – b;
}
“`
app.mjs
(計算モジュールを利用する側 – ES Modules版)
“`javascript
// app.mjs
import { add, subtract } from ‘./calculator.mjs’; // 相対パスで指定
console.log(‘2 + 3 =’, add(2, 3));
console.log(’10 – 5 =’, subtract(10, 5));
“`
ファイル名を .js
のままES Modulesを使いたい場合は、package.json
に以下を追加します。
json
// package.json
{
"name": "my_app",
"version": "1.0.0",
"type": "module", // これを追加
"main": "app.js",
"scripts": {
"start": "node app.js"
}
}
この設定をすると、ファイル拡張子が.js
であっても import
/export
構文が利用可能になります。
組み込みモジュール
Node.jsには、ファイルシステム操作、HTTP通信、パス操作など、基本的な機能を提供する組み込みモジュールが多数用意されています。これらは require()
(CommonJS) または import
(ES Modules) で名前を指定して読み込むことで利用できます。
“`javascript
// builtin_modules.js
const fs = require(‘fs’); // ファイルシステムモジュール
const path = require(‘path’); // パス操作モジュール
const http = require(‘http’); // HTTPモジュール
// fsモジュールでファイルの内容を読み込む (非同期)
fs.readFile(‘app.js’, ‘utf8’, (err, data) => {
if (err) {
console.error(‘ファイルの読み込みエラー:’, err);
return;
}
console.log(‘app.jsの内容:\n’, data.substring(0, 50) + ‘…’); // 先頭50文字だけ表示
});
// pathモジュールでパスを結合する
const filePath = path.join(__dirname, ‘data’, ‘users.json’);
console.log(‘結合されたパス:’, filePath);
// httpモジュールでシンプルなサーバーを作成 (後述)
// http.createServer((req, res) => { / … / });
// 実行: node builtin_modules.js
``
__dirname` は、現在実行しているスクリプトファイルが存在するディレクトリの絶対パスを示すNode.jsのグローバル変数です。
第4章:npmを使いこなそう:パッケージ管理の基礎
Node.js開発において、npmは非常に重要な役割を担います。この章では、npmを使ったパッケージの管理方法について詳しく見ていきましょう。
package.json
とは何か?
package.json
ファイルは、Node.jsプロジェクトの設定ファイル兼メタデータファイルです。プロジェクトの名前、バージョン、説明、スクリプト、依存関係など、そのプロジェクトに関するあらゆる情報がJSON形式で記述されています。
npm init
新しいNode.jsプロジェクトを開始する際、まず最初に行うべきは package.json
ファイルの作成です。これは npm init
コマンドで行います。
- 新しいプロジェクトフォルダを作成し、移動
bash
mkdir my_npm_project
cd my_npm_project -
npm init
を実行
bash
npm init
このコマンドを実行すると、いくつかの質問(プロジェクト名、バージョン、説明、エントリポイントなど)が表示されます。ほとんどの質問はEnterキーを押してデフォルト値を受け入れるか、簡単に適当な値を入力しても問題ありません。package name
: プロジェクト名(デフォルトはフォルダ名)version
: バージョン番号(デフォルトは1.0.0)description
: プロジェクトの説明entry point
: プロジェクトのエントリファイル(デフォルトはindex.js
)test command
: テストコマンドgit repository
: GitリポジトリのURLkeywords
: 検索キーワードauthor
: 作者名license
: ライセンス(デフォルトはISC)
最後に「Is this OK? (yes) 」と表示されるので、
yes
と入力してEnterを押すと、package.json
ファイルが作成されます。json
// package.json (生成例)
{
"name": "my_npm_project",
"version": "1.0.0",
"description": "My first Node.js project using npm.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Your Name",
"license": "ISC"
}
依存関係 (dependencies
, devDependencies
)
package.json
の最も重要な役割の一つは、プロジェクトが依存する外部パッケージ(ライブラリ)の情報を管理することです。
-
dependencies
(本番環境での依存関係):
アプリケーションが実際に動作するために必要なパッケージが記述されます。例えば、WebアプリケーションフレームワークのExpress.jsや、データベースドライバなどがここに含まれます。 -
devDependencies
(開発環境での依存関係):
開発やテストの目的でのみ必要なパッケージが記述されます。例えば、テストフレームワーク(Jest)、コードフォーマッター(Prettier)、バンドラー(Webpack)などがここに含まれます。これらは、アプリケーションが本番環境で実行される際には不要です。
これらの依存関係は、後述の npm install
コマンドで自動的に解決・インストールされます。
スクリプト (scripts
)
scripts
フィールドには、よく使うコマンドをエイリアス(別名)として登録できます。これにより、複雑なコマンドを短い名前で実行できるようになります。
json
// package.json (scriptsの例)
{
"name": "my_npm_project",
"version": "1.0.0",
"description": "My first Node.js project using npm.",
"main": "index.js",
"scripts": {
"start": "node index.js", // アプリケーションを起動するコマンド
"test": "jest", // テストを実行するコマンド
"dev": "nodemon index.js", // 開発中にファイルを監視して自動再起動するコマンド (nodemonを別途インストールが必要)
"lint": "eslint . --fix" // コードのlintを実行し修正するコマンド
},
"author": "Your Name",
"license": "ISC"
}
これらのスクリプトは npm run <script-name>
で実行できます。
例: npm run dev
start
と test
は特別なスクリプト名で、それぞれ npm start
、npm test
と run
を省略して実行できます。
パッケージのインストールと管理
npm install
コマンドを使って、プロジェクトに必要なパッケージをインストールします。
npm install <package-name>
特定のパッケージをインストールします。
“`bash
例: WebフレームワークのExpressをインストール
npm install express
または npm i express (i は install のエイリアス)
``
node_modules
このコマンドを実行すると、以下のことが起こります。
1.フォルダが作成され、その中にExpressパッケージと、Expressが依存する他のパッケージがダウンロード・保存されます。
package.json
2.の
dependenciesセクションにExpressが追加されます。
package-lock.json` ファイルが作成または更新されます。これは、インストールされたパッケージの正確なバージョンと依存関係ツリーを記録するファイルで、他の開発者と全く同じ環境を再現するために重要です。
3.
開発用のパッケージをインストールする場合は、--save-dev
または -D
オプションを付けます。
“`bash
例: テストフレームワークのJestを開発用としてインストール
npm install jest –save-dev
または npm i jest -D
``
devDependencies` に追加されます。
これにより、Jestは
npm install
(一括インストール)
プロジェクトを他の人がクローンした際など、package.json
に記述されているすべての依存パッケージを一括でインストールしたい場合は、単に npm install
と実行します。
“`bash
package.jsonとpackage-lock.jsonに基づいて全ての依存パッケージをインストール
npm install
``
node_modules` フォルダがない場合に作成され、必要な全てのパッケージがダウンロードされます。
これにより、
npm uninstall <package-name>
不要になったパッケージをアンインストールします。
“`bash
Expressをアンインストール
npm uninstall express
または npm un express
``
node_modules
これにより、からパッケージが削除され、
package.jsonと
package-lock.json` も更新されます。
npm update
インストール済みのパッケージを更新します。
“`bash
全てのパッケージを更新
npm update
特定のパッケージを更新
npm update express
``
package.jsonに指定されたバージョン範囲(例:
“express”: “^4.18.2″`)内で、最新の互換性のあるバージョンに更新されます。
主要な人気パッケージの紹介
Node.jsのエコシステムは非常に広大で、様々な目的のパッケージが存在します。ここでは、代表的な人気パッケージをいくつか紹介します。
- Express.js: (Webフレームワーク) Node.jsで最も人気のあるWebアプリケーションフレームワーク。WebサーバーやAPIサーバーの構築に利用されます。
- Lodash: (ユーティリティライブラリ) 配列、オブジェクト、数値、文字列などの操作を簡単にする便利な関数を提供します。
- Axios / node-fetch: (HTTPクライアント) 外部のAPIにHTTPリクエストを送信するためのライブラリ。
- Chalk: (ターミナルスタイル) ターミナルに表示されるテキストに色やスタイルを付けることができます。コマンドラインツールの見栄えを良くするのに使われます。
- nodemon: (開発ツール) Node.jsアプリケーションのソースコードの変更を監視し、自動的にサーバーを再起動してくれるツール。開発効率を大幅に向上させます。
これらのパッケージは、npm install <package-name>
で簡単に導入し、あなたのプロジェクトをより強力にすることができます。
第5章:Node.jsプログラミングの基礎概念
この章では、Node.jsプログラミングを理解する上で不可欠な、より深い概念を掘り下げていきます。特に非同期処理はNode.jsの心臓部とも言える部分ですので、じっくりと理解を深めましょう。
非同期処理
Node.jsの最大の特徴は、非同期処理とノンブロッキングI/O(入出力)モデルを採用している点です。これにより、大量の同時接続やI/O処理を効率的にこなすことができます。
JavaScriptのシングルスレッドモデルとイベントループ
JavaScriptは基本的にシングルスレッドで動作します。つまり、一度に一つの処理しか実行できません。
「それだと、時間のかかる処理(例:ファイルの読み書き、データベースアクセス、ネットワーク通信など)が始まったら、その間他の処理は止まってしまうのでは?」と疑問に思うかもしれません。まさにその通りです。このような問題を解決するのが非同期処理とイベントループの仕組みです。
Node.jsは、I/O処理など時間のかかる処理をバックグラウンドに「投げ」、その結果を待たずに次の処理を実行します。バックグラウンドの処理が完了すると、その結果が「イベント」としてキューに追加され、Node.jsの「イベントループ」がそのイベントを検知し、適切なコールバック関数を実行します。
この仕組みにより、Node.jsはシングルスレッドでありながら、高い並行処理能力を発揮できるのです。
コールバック関数
非同期処理を扱う最も基本的な方法がコールバック関数です。非同期処理が完了したときに呼び出される関数を、あらかじめ引数として渡しておく形式です。
“`javascript
// callback_example.js
const fs = require(‘fs’);
console.log(‘1. ファイル読み込みを開始…’);
fs.readFile(‘non_existent_file.txt’, ‘utf8’, (err, data) => {
// この関数がコールバック関数
if (err) {
console.error(‘エラー発生:’, err.message);
return;
}
console.log(‘3. ファイル内容:’, data);
});
console.log(‘2. ファイル読み込みの完了を待たずに次の処理を実行…’);
// 実行: node callback_example.js
// 期待される出力順:
// 1. ファイル読み込みを開始…
// 2. ファイル読み込みの完了を待たずに次の処理を実行…
// エラー発生: ENOENT: no such file or directory, open ‘non_existent_file.txt’
``
readFile` が非同期なので、「2.」が「1.」の直後に実行されます。「3.」はファイル読み込みが完了してから実行されます(この場合はエラーが発生しますが)。
この例では、
コールバックはシンプルですが、非同期処理が複数重なると「コールバック地獄 (Callback Hell)」と呼ばれる、コードが深くネストして読みにくくなる問題が発生することがあります。
Promise (プロミス)
コールバック地獄の問題を解決するために導入されたのがPromise(プロミス)です。Promiseは、非同期処理の最終的な完了(または失敗)とその結果の値を表現するオブジェクトです。
Promiseには3つの状態があります。
* Pending (保留中): 初期状態。非同期処理がまだ完了していない。
* Fulfilled (成功): 非同期処理が成功し、結果が利用可能になった。
* Rejected (失敗): 非同期処理が失敗し、エラーが発生した。
Promiseは、.then()
メソッドで成功時の処理を、.catch()
メソッドで失敗時の処理をチェーンで記述できます。
“`javascript
// promise_example.js
const fs = require(‘fs/promises’); // fs/promises はPromiseベースのfsモジュール
async function readFilePromise(filename) {
try {
console.log(‘1. ファイル読み込みを開始…’);
const data = await fs.readFile(filename, ‘utf8’); // awaitを使ってPromiseの解決を待つ
console.log(‘3. ファイル内容:’, data);
return data;
} catch (err) {
console.error(‘エラー発生:’, err.message);
throw err; // エラーを再スローして後続のcatchで捕捉できるようにする
}
}
readFilePromise(‘app.js’)
.then(data => {
console.log(‘4. Promise成功!’);
})
.catch(error => {
console.log(‘4. Promise失敗!’);
});
console.log(‘2. Promise処理の完了を待たずに次の処理を実行…’);
// 実行: node promise_example.js
// 期待される出力順:
// 1. ファイル読み込みを開始…
// 2. Promise処理の完了を待たずに次の処理を実行…
// 3. ファイル内容: …
// 4. Promise成功!
“`
Async/Await (アシンク/アウェイト)
Async/Awaitは、Promiseをより同期的なコードのように記述できる、JavaScriptの構文糖衣(シンタックスシュガー)です。Promiseを使ったコードをさらに読みやすくします。
async
キーワード: 関数宣言の前にasync
を付けると、その関数は必ずPromiseを返します。await
キーワード:async
関数内でしか使えません。await
の後ろにPromiseを置くと、そのPromiseが解決されるまでコードの実行を一時停止し、解決された値を取得します。
“`javascript
// async_await_example.js
const fs = require(‘fs/promises’); // Promiseベースのfsモジュール
async function processFile() {
console.log(‘1. 処理を開始…’);
try {
// await を使うことで、ファイル読み込みが完了するまで次の行へ進まない
const data = await fs.readFile(‘app.js’, ‘utf8’);
console.log(‘3. ファイル内容 (一部):’, data.substring(0, 50) + ‘…’);
const anotherFile = await fs.readFile('package.json', 'utf8');
console.log('4. package.json の内容 (一部):', anotherFile.substring(0, 50) + '...');
console.log('5. 全ての非同期処理が完了しました。');
} catch (error) {
console.error(‘エラーが発生しました:’, error.message);
}
console.log(‘6. processFile関数の終わり。’);
}
processFile();
console.log(‘2. processFileの呼び出し後、すぐに実行される。’);
// 実行: node async_await_example.js
// 期待される出力順:
// 1. 処理を開始…
// 2. processFileの呼び出し後、すぐに実行される。
// 3. ファイル内容 (一部): …
// 4. package.json の内容 (一部): …
// 5. 全ての非同期処理が完了しました。
// 6. processFile関数の終わり。
``
processFile関数は非同期関数ですが、その中で
await` を使うことで、見た目上は同期的な処理のように記述でき、非常に読みやすくなります。Node.js開発では、このAsync/Awaitが非同期処理の主流となっています。
モジュールシステム (CommonJS と ES Modules の違いと使い分け)
第3章で触れたモジュールシステムについて、もう少し詳しく掘り下げます。
-
CommonJS (
require
/module.exports
):- 同期的にモジュールを読み込む:
require()
はファイルパスを指定すると、そのファイルの内容を同期的に読み込み、モジュールを返します。 - Node.jsの伝統的な形式: 多くの既存のnpmパッケージはCommonJS形式で書かれています。
- オブジェクトのコピーをエクスポート:
module.exports
でエクスポートされたオブジェクトは、require()
された時点でコピーされます。元モジュールの変数を外部から直接変更することはできません(ただし、オブジェクトのプロパティを変更することは可能)。 - 動的な読み込みが可能: 条件分岐の中で
require()
を使うなど、実行時に読み込むモジュールを動的に決定できます。
- 同期的にモジュールを読み込む:
-
ES Modules (
import
/export
):- 非同期的にモジュールを読み込む(原理上は): 静的な解析が可能で、依存関係を事前に解決できます。
- JavaScriptの標準: ブラウザでもNode.jsでも使える統一的なモジュール形式です。
- ライブバインディング:
import
された値は、元モジュールの値への参照(ライブバインディング)であり、元モジュールで値が変更されれば、インポート元でもその変更が反映されます。 - 静的な読み込み:
import
文はファイルのトップレベルに記述する必要があり、動的な読み込みは基本的にはできません(import()
関数による動的インポートは可能)。
使い分け:
- 既存のNode.jsプロジェクトや古いライブラリを扱う場合: CommonJSを使うのが一般的です。
- 新しいプロジェクトを開始する場合や、フロントエンドとバックエンドでモジュールシステムを統一したい場合: ES Modulesを使うことを検討しましょう。
package.json
に"type": "module"
を追加し、拡張子を.js
のままESMとして扱うか、.mjs
拡張子を使用します。
多くの現代的なNode.jsフレームワークやツールは、ES Modulesを推奨または採用し始めています。
イベントエミッター
Node.jsのコアAPIの多くは、非同期イベント駆動のアーキテクチャに基づいています。このイベント駆動モデルの中心にあるのが、EventEmitter
クラスです。
EventEmitter
は、特定のイベントが発生したときに、登録された関数(イベントリスナー)を呼び出す仕組みを提供します。
“`javascript
// event_emitter.js
const EventEmitter = require(‘events’);
// EventEmitterを継承したカスタムクラスを作成
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// イベントリスナーを登録
myEmitter.on(‘user_login’, (username) => {
console.log(${username} がログインしました。
);
});
myEmitter.on(‘user_login’, (username) => {
console.log(ログ記録: ${username} のログイン時刻: ${new Date().toLocaleTimeString()}
);
});
myEmitter.on(‘data_received’, (data) => {
console.log(‘データを受信しました:’, data);
});
// イベントを発火 (emit)
myEmitter.emit(‘user_login’, ‘Alice’);
myEmitter.emit(‘data_received’, { id: 1, value: ‘サンプルデータ’ });
myEmitter.emit(‘user_login’, ‘Bob’);
// 実行: node event_emitter.js
``
on()でイベントリスナーを登録し、
emit()` でイベントを発火させます。これは、Node.jsのストリーム(ファイルの読み書き、HTTPリクエストなど)や他の非同期処理の基盤となっています。
ファイルシステム (fsモジュール)
Node.jsの組み込みモジュールである fs
(File System) モジュールは、ファイルやディレクトリを操作するための機能を提供します。ファイルの読み書き、削除、移動、ディレクトリの作成などが可能です。
多くの fs
メソッドには、同期版と非同期版があります。非同期版が推奨されます。
“`javascript
// fs_example.js
const fs = require(‘fs’);
const fsPromises = require(‘fs/promises’); // Promiseベースのfs
const filePath = ‘example.txt’;
const content = ‘これはテストファイルの内容です。\nNode.jsで書き込みました。’;
// ファイルへの非同期書き込み
fs.writeFile(filePath, content, (err) => {
if (err) {
console.error(‘ファイル書き込みエラー:’, err);
return;
}
console.log('${filePath}' に正常に書き込みました。
);
// 書き込み完了後に非同期読み込み
fs.readFile(filePath, ‘utf8’, (readErr, data) => {
if (readErr) {
console.error(‘ファイル読み込みエラー:’, readErr);
return;
}
console.log('${filePath}' から読み込んだ内容:\n${data}
);
// Promiseベースの削除
fsPromises.unlink(filePath) // ファイルを削除
.then(() => {
console.log(`'${filePath}' を削除しました。`);
})
.catch((unlinkErr) => {
console.error('ファイル削除エラー:', unlinkErr);
});
});
});
console.log(‘ファイル操作の非同期処理が開始されました。’);
// 実行: node fs_example.js
“`
このように、ファイル操作も非同期で行うことで、他の処理をブロックせずに実行できます。
HTTPモジュール
Node.jsの真骨頂は、Webサーバーを簡単に構築できる点です。組み込みの http
モジュールを使えば、HTTPリクエストを処理するサーバーをすぐに立ち上げることができます。
“`javascript
// http_server.js
const http = require(‘http’);
const hostname = ‘127.0.0.1’; // ローカルホスト
const port = 3000; // 任意のポート番号
// HTTPサーバーを作成
const server = http.createServer((req, res) => {
// リクエスト(req)とレスポンス(res)オブジェクトを受け取るコールバック関数
// ステータスコード200 (OK) を設定
res.statusCode = 200;
// Content-Typeヘッダーを設定 (ブラウザにHTMLとして解釈させる)
res.setHeader(‘Content-Type’, ‘text/html; charset=utf-8’);
// URLパスによって異なるレスポンスを返す
if (req.url === ‘/’) {
res.end(‘
ようこそ、Node.jsの世界へ!
これはトップページです。
‘);
} else if (req.url === ‘/about’) {
res.end(‘
About Us
私たちはNode.jsを愛する開発者です。
‘);
} else if (req.url === ‘/api/data’) {
res.setHeader(‘Content-Type’, ‘application/json’);
res.end(JSON.stringify({ message: ‘JSONデータです’, timestamp: new Date() }));
} else {
res.statusCode = 404; // Not Found
res.setHeader(‘Content-Type’, ‘text/plain; charset=utf-8’);
res.end(‘404 Not Found’);
}
});
// サーバーを指定されたポートとホスト名でリッスン開始
server.listen(port, hostname, () => {
console.log(サーバーが http://${hostname}:${port}/ で起動しました
);
console.log(‘ブラウザでアクセスしてください!’);
});
// 実行: node http_server.js
``
node http_server.js
このファイルを保存し、を実行すると、あなたのPCでWebサーバーが起動します。ブラウザで
http://127.0.0.1:3000/や
http://127.0.0.1:3000/about、
http://127.0.0.1:3000/api/data` にアクセスしてみてください。
ただし、このように生の http
モジュールを使うのは非常に手間がかかります。実際のWebアプリケーション開発では、もっと便利なフレームワークであるExpress.jsなどを利用するのが一般的です。次の章でExpress.jsを学びましょう。
第6章:簡単なWebアプリケーションを作ってみよう (Express.js)
生のHTTPモジュールでのWebサーバー構築は手間がかかることを学びました。そこで、Node.jsでWebアプリケーションを開発する際に最も広く使われているフレームワーク、Express.jsを使ってみましょう。
Express.jsとは?
Express.jsは、Node.jsのための高速で、意見が少なく、柔軟なWebアプリケーションフレームワークです。WebアプリケーションやAPIの構築を劇的に簡素化します。ルーティング、ミドルウェア、テンプレートエンジンなど、Web開発に必要な多くの機能を提供しますが、強制する設計思想は少なく、開発者の自由度が高いのが特徴です。
Expressプロジェクトの初期化
my_npm_project
フォルダがある場合は、それを使っても良いですし、新しく my_express_app
フォルダを作成しても構いません。
- 新しいプロジェクトフォルダを作成し、移動
bash
mkdir my_express_app
cd my_express_app npm init
で初期化
bash
npm init -y
-y
オプションを付けると、すべての質問にデフォルトで「yes」と回答し、すぐにpackage.json
が生成されます。- Express.jsをインストール
bash
npm install express
package.json
のdependencies
にexpress
が追加されたことを確認してください。
基本的なルーティング
Express.jsの基本的なWebサーバーを作成してみましょう。index.js
ファイルを作成します。
“`javascript
// index.js
const express = require(‘express’); // Expressモジュールを読み込む
const app = express(); // Expressアプリケーションのインスタンスを作成
const port = 3000; // サーバーをリッスンするポート番号
// ルートパス (/) へのGETリクエストを処理
app.get(‘/’, (req, res) => {
res.send(‘
ExpressでHello World!
これはトップページです。
‘);
});
// /aboutパスへのGETリクエストを処理
app.get(‘/about’, (req, res) => {
res.send(‘
About Us
ExpressはNode.jsのWebフレームワークです。
‘);
});
// /api/usersパスへのGETリクエストを処理 (JSONデータを返すAPIエンドポイント)
app.get(‘/api/users’, (req, res) => {
const users = [
{ id: 1, name: ‘Alice’, email: ‘[email protected]’ },
{ id: 2, name: ‘Bob’, email: ‘[email protected]’ }
];
res.json(users); // JSON形式でレスポンスを送信
});
// サーバーを起動
app.listen(port, () => {
console.log(Expressサーバーが http://localhost:${port} で起動しました
);
console.log(‘ブラウザでアクセスしてください!’);
});
“`
このファイルを保存し、VS Codeの統合ターミナルで以下のコマンドを実行します。
bash
node index.js
または、package.json
の scripts
に start
コマンドを追加し、npm start
で起動します。
json
// package.json
{
// ...
"main": "index.js",
"scripts": {
"start": "node index.js"
},
// ...
}
ブラウザで http://localhost:3000/
、http://localhost:3000/about
、http://localhost:3000/api/users
にアクセスして、それぞれのレスポンスを確認してみてください。
app.METHOD(PATH, HANDLER)
の形式でルーティングを定義します。
* METHOD
: get
, post
, put
, delete
など、HTTPメソッドを指定します。
* PATH
: リクエストURLのパスを指定します。
* HANDLER
: リクエストが来たときに実行されるコールバック関数です。req
(リクエストオブジェクト) と res
(レスポンスオブジェクト) を引数に取ります。
* res.send()
: HTML文字列などをクライアントに送信します。
* res.json()
: JSONデータをクライアントに送信します。
ミドルウェアの概念
Express.jsの強力な機能の一つがミドルウェアです。ミドルウェアは、リクエストがサーバーに到着してからレスポンスがクライアントに送られるまでの間に、順次実行される関数群です。各ミドルウェアは、リクエストオブジェクト (req
)、レスポンスオブジェクト (res
)、そして次のミドルウェア関数 (next
) を引数に取ります。
ミドルウェアは以下のような処理に使われます。
* リクエストデータの解析(JSON、URLエンコードなど)
* 認証・認可
* ロギング
* 静的ファイルの配信
* エラー処理
グローバルミドルウェアの例
“`javascript
// middleware_example.js
const express = require(‘express’);
const app = express();
const port = 3000;
// ① リクエストのたびに実行されるロガーミドルウェア
app.use((req, res, next) => {
console.log([${new Date().toISOString()}] ${req.method} ${req.url}
);
next(); // 次のミドルウェアまたはルートハンドラへ処理を渡す
});
// ② JSONボディパーサーミドルウェア (Express 4.16.0以降は組み込み)
app.use(express.json()); // リクエストボディがJSONの場合、req.bodyにパースして追加
// ルートハンドラ
app.get(‘/’, (req, res) => {
res.send(‘トップページ’);
});
app.post(‘/submit’, (req, res) => {
console.log(‘受信したデータ:’, req.body); // express.json()によってパースされたデータ
res.json({ message: ‘データを受信しました’, yourData: req.body });
});
app.listen(port, () => {
console.log(サーバー起動: http://localhost:${port}
);
});
``
app.use()
このコードでは、でミドルウェアを登録しています。ミドルウェアは登録した順に実行されます。
next()を呼び出すことで、次のミドルウェアに処理を渡します。もし
next()を呼び出さずに
res.send()や
res.json()` などでレスポンスを返すと、そこで処理が終了します。
express.json()
は、POST
リクエストなどで送信されるJSON形式のリクエストボディを自動的にパースし、req.body
オブジェクトとして利用可能にするミドルウェアです。
静的ファイルの配信
Webアプリケーションでは、HTML、CSS、JavaScriptファイル、画像などの静的ファイルをクライアントに配信する必要があります。Expressでは express.static
ミドルウェアを使って簡単に行えます。
プロジェクトフォルダ内に public
というフォルダを作成し、その中に静的ファイルを置きます。
bash
my_express_app/
├── node_modules/
├── public/
│ ├── index.html
│ └── style.css
├── package.json
├── package-lock.json
└── index.js
public/index.html
:
“`html
静的ファイルが配信されました!
このページは `public/index.html` です。
“`
public/style.css
:
“`css
body {
font-family: sans-serif;
background-color: #f0f0f0;
color: #333;
text-align: center;
padding-top: 50px;
}
h1 {
color: #007bff;
}
“`
index.js
を以下のように修正します。
“`javascript
// index.js
const express = require(‘express’);
const app = express();
const path = require(‘path’); // pathモジュールを読み込む
const port = 3000;
// publicフォルダを静的ファイルとして配信
// http://localhost:3000/index.html で public/index.html が、
// http://localhost:3000/style.css で public/style.css がアクセス可能になる
app.use(express.static(path.join(__dirname, ‘public’)));
// (オプション) ルートパスへのアクセスを index.html にリダイレクト
app.get(‘/’, (req, res) => {
res.sendFile(path.join(__dirname, ‘public’, ‘index.html’));
});
// その他のAPIエンドポイントなど…
app.get(‘/api/greeting’, (req, res) => {
res.json({ message: ‘Hello from API!’ });
});
app.listen(port, () => {
console.log(Expressサーバーが http://localhost:${port} で起動しました
);
});
``
express.static(path.join(__dirname, ‘public’))を記述することで、
publicフォルダ以下のファイルが
http://localhost:3000/から直接アクセスできるようになります。例えば
public/index.htmlは
http://localhost:3000/index.htmlで、
public/style.cssは
http://localhost:3000/style.css` でアクセスできます。
APIの作成例 (GET, POST)
Expressを使えば、RESTful APIの作成も非常に簡単です。
“`javascript
// api_example.js (index.jsに追記してもOK)
const express = require(‘express’);
const app = express();
const port = 3000;
// JSONボディパーサーを有効にする (POSTリクエストのJSONデータをreq.bodyで受け取るため)
app.use(express.json());
// ダミーデータ (通常はデータベースから取得)
let todos = [
{ id: 1, title: ‘Node.jsを学ぶ’, completed: false },
{ id: 2, title: ‘Expressアプリを作る’, completed: true },
{ id: 3, title: ‘記事を読む’, completed: false }
];
let nextId = 4; // 次のID
// GET /api/todos: 全てのTODOを取得
app.get(‘/api/todos’, (req, res) => {
res.json(todos);
});
// GET /api/todos/:id: 特定のIDのTODOを取得
app.get(‘/api/todos/:id’, (req, res) => {
const id = parseInt(req.params.id); // URLパラメータからIDを取得
const todo = todos.find(t => t.id === id);
if (todo) {
res.json(todo);
} else {
res.status(404).json({ message: ‘Todoが見つかりません’ });
}
});
// POST /api/todos: 新しいTODOを作成
app.post(‘/api/todos’, (req, res) => {
const { title } = req.body; // リクエストボディからtitleを取得
if (!title) {
return res.status(400).json({ message: ‘タイトルが必要です’ });
}
const newTodo = {
id: nextId++,
title,
completed: false
};
todos.push(newTodo);
res.status(201).json(newTodo); // 201 Created を返す
});
// PUT /api/todos/:id: 特定のIDのTODOを更新
app.put(‘/api/todos/:id’, (req, res) => {
const id = parseInt(req.params.id);
const { title, completed } = req.body;
const todoIndex = todos.findIndex(t => t.id === id);
if (todoIndex === -1) {
return res.status(404).json({ message: ‘Todoが見つかりません’ });
}
if (title !== undefined) todos[todoIndex].title = title;
if (completed !== undefined) todos[todoIndex].completed = completed;
res.json(todos[todoIndex]);
});
// DELETE /api/todos/:id: 特定のIDのTODOを削除
app.delete(‘/api/todos/:id’, (req, res) => {
const id = parseInt(req.params.id);
const initialLength = todos.length;
todos = todos.filter(t => t.id !== id);
if (todos.length < initialLength) {
res.status(204).send(); // 204 No Content を返す (成功したが返す内容がない場合)
} else {
res.status(404).json({ message: ‘Todoが見つかりません’ });
}
});
app.listen(port, () => {
console.log(APIサーバー起動: http://localhost:${port}
);
});
``
req.params
この例では、でURLパスのパラメーター(例:
/api/todos/**
1** の
1)を取得し、
req.body` でPOST/PUTリクエストのJSONデータを受け取っています。
APIのテストには、ブラウザだけでなく、PostmanやInsomnia、VS CodeのREST Client拡張機能などのツールを使うと便利です。
環境変数 (dotenv
)
本番環境と開発環境でデータベースの接続情報やAPIキーなど、異なる設定値を使いたい場合があります。このような機密情報や環境ごとの設定は、コードに直接書き込むべきではありません。そこで環境変数が使われます。
Node.jsで環境変数を扱うには、dotenv
パッケージが非常に便利です。
dotenv
をインストール
bash
npm install dotenv-
.env
ファイルを作成
プロジェクトのルートディレクトリに.env
という名前のファイルを作成し、キーと値のペアで環境変数を記述します。// .env
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=my_secret_password
API_KEY=your_super_secret_api_key
PORT=3001 # サーバーのポートもここに定義できる
注意:.env
ファイルは機密情報を含むため、Gitなどのバージョン管理システムにコミットしないように、.gitignore
ファイルに追記してください。// .gitignore
node_modules/
.env -
Node.jsアプリケーションで環境変数を読み込む
アプリケーションのエントリポイント(通常はindex.js
またはapp.js
の一番上)でdotenv
を読み込みます。“`javascript
// index.js (ファイルの先頭に記述)
require(‘dotenv’).config(); // .envファイルを読み込むconst express = require(‘express’);
const app = express();
const port = process.env.PORT || 3000; // 環境変数PORTがなければ3000を使用console.log(‘データベースホスト:’, process.env.DB_HOST);
console.log(‘APIキー:’, process.env.API_KEY);// … Expressのルーティングなど …
app.get(‘/config’, (req, res) => {
res.json({
port: port,
db_host: process.env.DB_HOST,
api_key_status: process.env.API_KEY ? ‘設定済み’ : ‘未設定’
});
});app.listen(port, () => {
console.log(サーバーがポート ${port} で起動しました
);
});
``
dotenv.config()を呼び出すと、
.envファイルに記述された変数が
process.envオブジェクトに自動的にロードされ、JavaScriptコードから
process.env.変数名` でアクセスできるようになります。
第7章:デバッグとテスト
コードが複雑になるにつれて、意図しない挙動やエラーが発生することがあります。これを解決するために、デバッグとテストは非常に重要なスキルとなります。
Node.jsのデバッグ方法
1. console.log()
を使ったデバッグ
最も手軽で基本的なデバッグ方法です。変数の中身や処理の通過点を確認するために、console.log()
をコードの様々な場所に挿入します。
“`javascript
// debug_example.js
function calculateSum(a, b) {
console.log(‘calculateSum関数が呼び出されました。’); // 処理の通過点
console.log(‘引数 a:’, a, ‘引数 b:’, b); // 変数の値を確認
const sum = a + b;
console.log(‘計算結果 sum:’, sum); // 中間結果を確認
return sum;
}
let x = 10;
let y = 20;
let result = calculateSum(x, y);
console.log(‘最終結果:’, result);
“`
シンプルですが、大量のログが出たり、複雑なデータ構造の確認には向かない場合があります。
2. VS Codeのデバッガー
VS Codeには強力なデバッガーが組み込まれており、効率的なデバッグが可能です。
- ブレークポイントを設定:
デバッグしたいコードの行番号の左側をクリックすると、赤い丸が表示され、ブレークポイントが設定されます。プログラムはここに来ると一時停止します。 -
デバッグの開始:
VS Codeの左側のアクティビティバーにある「実行とデバッグ」アイコン(虫眼鏡と再生ボタンのような形)をクリックします。
もしlaunch.json
がない場合は、「ファイルを実行とデバッグ」ボタンをクリックするか、「launch.json ファイルを作成」を選択します。Node.js環境であれば、デフォルト設定でデバッグを開始できます。
通常、node
コマンドで起動するファイルを実行するには、以下のようなlaunch.json
設定があれば十分です。json
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "現在のファイルをデバッグ",
"skipFiles": [
"<node_internals>/**"
],
"program": "${file}" // 現在開いているファイルをデバッグ
},
{
"type": "node",
"request": "launch",
"name": "特定のファイル (index.js) をデバッグ",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/index.js" // プロジェクトのルートにあるindex.jsをデバッグ
}
]
}
保存後、デバッグビューのドロップダウンから適切な設定を選び、緑色の再生ボタンをクリックします。
3. デバッガーの操作:
プログラムがブレークポイントで停止すると、VS Codeのデバッグコントロールが表示されます。
* 続行 (Continue): 次のブレークポイントまで実行を継続。
* ステップオーバー (Step Over): 現在の行を実行し、次の行へ。関数呼び出しの中には入らない。
* ステップイン (Step Into): 現在の行を実行し、関数呼び出しがあればその関数の中に入る。
* ステップアウト (Step Out): 現在の関数から抜け出し、呼び出し元に戻る。
* 再起動 (Restart): デバッグセッションを再起動。
* 停止 (Stop): デバッグセッションを終了。左側のデバッグビューでは、ローカル変数、ウォッチ式、コールスタックなどを確認できます。これにより、プログラムの実行フローと変数の状態を詳細に把握できます。
単体テストの基礎
テストは、コードが期待通りに動作することを検証し、将来の変更が既存の機能を壊さないことを保証するために重要です。
Jestの紹介と基本的な使い方
Node.jsのテストフレームワークとして最も人気があるのがJestです。Facebookが開発しており、シンプルで高速、豊富な機能を備えています。
-
Jestをインストール:
開発用依存としてJestをインストールします。bash
npm install --save-dev jest -
package.json
にテストスクリプトを追加:json
// package.json
{
"name": "my_test_app",
"version": "1.0.0",
// ...
"scripts": {
"test": "jest" // npm test で Jest を実行
},
// ...
} -
テスト対象のモジュールを作成:
例として、簡単な計算関数を定義したsrc/math.js
を作成します。“`javascript
// src/math.js
function add(a, b) {
return a + b;
}function subtract(a, b) {
return a – b;
}module.exports = { add, subtract };
“` -
テストファイルを作成:
テスト対象のファイルと同じ階層か、__tests__
などの専用フォルダにテストファイルを作成します。ファイル名は通常*.test.js
または*.spec.js
とします。“`javascript
// src/math.test.js
const { add, subtract } = require(‘./math’); // テスト対象のモジュールを読み込む// add関数のテスト
test(‘add関数は2つの数値を加算する’, () => {
expect(add(1, 2)).toBe(3); // 1 + 2 は 3 になることを期待
expect(add(5, 5)).toBe(10);
expect(add(-1, 1)).toBe(0);
});// subtract関数のテスト
test(‘subtract関数は2つの数値を減算する’, () => {
expect(subtract(5, 2)).toBe(3); // 5 – 2 は 3 になることを期待
expect(subtract(10, 20)).toBe(-10);
});
``
test()
*または
it(): 個々のテストケースを定義します。第一引数はテストの説明、第二引数はテストロジックを含む関数。
expect()
*: テストしたい値(被験者)を指定します。
toBe()
*:
expect()で指定した値が、引数に指定した値と厳密に等しいことを検証します(プリミティブ型の場合)。他にも
toEqual()(オブジェクトや配列の比較),
toThrow()` (例外発生の確認) など、様々なマッチャーがあります。 -
テストを実行:
ターミナルで以下のコマンドを実行します。bash
npm test
Jestがテストファイルを検出し、テストを実行し、結果をレポートします。“`
PASS src/math.test.js
✓ add関数は2つの数値を加算する (5ms)
✓ subtract関数は2つの数値を減算する (1ms)Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 0.5s
Ran all test suites.
“`
このように表示されれば、テストは成功です。
単体テストを習慣化することで、コードの品質が向上し、自信を持って開発を進めることができるようになります。
第8章:Node.jsアプリケーションのデプロイ
開発したNode.jsアプリケーションを、インターネット上で公開し、誰でもアクセスできるようにすることを「デプロイ(Deploy)」と言います。
デプロイとは?
デプロイとは、開発環境で作成したアプリケーションのコードや関連ファイルを、Webサーバーなどの本番環境に配置し、実行可能な状態にすることです。これには通常、以下のステップが含まれます。
- ビルド (必要な場合): TypeScriptなど、トランスパイルが必要な言語を使っている場合や、フロントエンドのコードをバンドルする場合に実行します。
- 依存関係のインストール:
npm install --production
などで、本番環境で必要なパッケージのみをインストールします。 - コードの配置: アプリケーションのコードをサーバーにアップロードします。
- 環境設定: データベース接続情報などの環境変数をサーバーに設定します。
- プロセス管理: アプリケーションが常に稼働し続けるように、PM2やSupervisorなどのプロセス管理ツールを使ったり、DockerやKubernetesなどのコンテナ技術を利用します。
- ドメイン設定とSSL証明書: アプリケーションにアクセスするためのドメインを設定し、安全な通信のためにSSL証明書(HTTPS)を導入します。
一般的なデプロイ先
Node.jsアプリケーションをデプロイできるプラットフォームは数多くあります。
- PaaS (Platform as a Service):
- Heroku: 手軽にNode.jsアプリをデプロイできる人気のPaaS。無料枠もあるため初心者にもおすすめ。
- Vercel: フロントエンドフレームワーク(Next.jsなど)のデプロイに特化しているが、Node.jsのサーバーレス関数もサポート。
- Render: Herokuの代替として人気上昇中。無料枠あり。
- Railway: シンプルで高速なデプロイが魅力。無料枠あり。
- IaaS (Infrastructure as a Service) / クラウドプロバイダー:
- AWS (Amazon Web Services): EC2 (仮想サーバー), Lambda (サーバーレス), Elastic Beanstalk (PaaS的) など、豊富なサービス。学習コストは高いが、非常に柔軟でスケーラブル。
- Google Cloud Platform (GCP): Compute Engine, Cloud Functions, App Engine など。
- Microsoft Azure: Virtual Machines, Azure Functions, Azure App Service など。
- VPS (Virtual Private Server):
- ConoHa VPS, さくらのVPS, DigitalOcean, Linode: 仮想サーバーを借りて、OSから自分で設定・管理する。自由度が高いが、サーバー管理の知識が必要。
簡単なデプロイのステップ (Herokuを例に)
ここでは、Herokuを使ったシンプルなNode.js Expressアプリケーションのデプロイ方法を解説します。Herokuは無料枠があり、Gitと連携して簡単にデプロイできるため、初心者におすすめです。
前提:
* Herokuアカウントを持っていること (アカウント作成は無料)
* Gitがインストールされていること
* 第6章で作成したExpressアプリケーション (my_express_app
または同様のExpressアプリ)
-
Heroku CLIのインストール
Heroku CLI (Command Line Interface) をインストールします。これにより、ターミナルからHerokuを操作できるようになります。
公式ドキュメントに従ってインストールしてください: https://devcenter.heroku.com/articles/heroku-cliインストール後、以下のコマンドでログインします。
bash
heroku login
ブラウザが開き、ログインを促されます。ログインが成功するとターミナルに戻ります。 -
package.json
の設定確認
Expressアプリのpackage.json
にstart
スクリプトが正しく設定されていることを確認してください。Herokuはデフォルトでnpm start
を実行してアプリケーションを起動します。json
// package.json
{
"name": "my-express-app",
"version": "1.0.0",
"description": "A simple Express app for deployment.",
"main": "index.js",
"scripts": {
"start": "node index.js" // これが重要
},
"dependencies": {
"express": "^4.18.2"
}
}
また、Expressサーバーのポート番号を環境変数から取得するように修正します。Herokuは動的にポートを割り当てるため、固定ポートは使えません。javascript
// index.js (ポート設定部分)
const port = process.env.PORT || 3000; // 環境変数PORTがあればそれを使用、なければ3000
// ...
app.listen(port, () => {
console.log(`Expressサーバーがポート ${port} で起動しました`);
}); -
Gitリポジトリの初期化とコミット
プロジェクトフォルダ (my_express_app
) でGitリポジトリを初期化し、変更をコミットします。bash
cd my_express_app
git init
git add .
git commit -m "Initial commit of Express app" -
Herokuアプリケーションの作成
Herokuに新しいアプリケーションを作成します。bash
heroku create <アプリ名>
<アプリ名>
は省略可能ですが、省略するとHerokuがランダムな名前を生成します。アプリケーション作成後、GitリモートにHerokuが追加されます。 -
Herokuへのデプロイ
Gitのmain
(またはmaster
) ブランチをHerokuのリモートにプッシュすることでデプロイが開始されます。bash
git push heroku main
これでHerokuが自動的に依存関係をインストールし (npm install --production
)、アプリケーションを起動します。 -
アプリケーションの確認
デプロイが成功したら、以下のコマンドでアプリケーションを開けます。bash
heroku open
ブラウザであなたのNode.jsアプリケーションが開かれ、インターネット上からアクセスできるようになります!デプロイ中のログは
heroku logs --tail
で確認できます。
デプロイは最初難しく感じるかもしれませんが、一度経験すればその後の開発のモチベーションにもつながります。
第9章:次のステップへ:Node.jsでさらにスキルアップ
基本的なNode.jsの知識と環境構築、簡単なWebアプリの作成までできました。ここからは、Node.jsでさらに高度な開発を行うために、次に学ぶべきトピックや技術を紹介します。
データベースとの連携
ほとんどのWebアプリケーションはデータを永続的に保存するためにデータベースを使用します。Node.jsからデータベースを操作するためのライブラリを学びましょう。
- MongoDB (NoSQL) / Mongoose (ODM):
柔軟なドキュメント指向データベース。MongooseはMongoDBのためのODM (Object Data Modeling) ライブラリで、データのスキーマ定義や操作を容易にします。- インストール:
npm install mongoose
- インストール:
- PostgreSQL / MySQL (リレーショナルデータベース) / Sequelize (ORM):
構造化されたデータを扱うリレーショナルデータベース。SequelizeはPostgreSQL, MySQL, SQLite, MSSQLなどに対応したNode.jsのORM (Object-Relational Mapping) で、SQLを直接書かずにオブジェクト指向でデータベース操作ができます。- インストール:
npm install sequelize pg pg-hstore
(PostgreSQLの場合)
- インストール:
- Prisma (ORM):
次世代のORMとして注目されています。TypeScriptとの相性が良く、直感的で型安全なデータベース操作を提供します。
リアルタイム通信 (Socket.io)
チャットアプリやオンラインゲームなど、クライアントとサーバー間でリアルタイムに双方向通信を行いたい場合は、WebSocketプロトコルを利用します。Node.jsではSocket.ioがそのデファクトスタンダードです。
- インストール:
npm install socket.io
(サーバー側),npm install socket.io-client
(クライアント側) - 特徴: WebSocketの接続状況やフォールバック(WebSocketが使えない環境での代替通信)を自動で管理してくれます。
認証・認可 (Passport.js)
ユーザーのログイン機能や、特定のユーザーだけがアクセスできる機能(例: 管理画面)を実装する際には、認証と認可の仕組みが必要です。
- Passport.js: Node.jsで最も広く使われている認証ミドルウェア。ローカル認証(ユーザー名とパスワード)、Google、FacebookなどのOAuth認証、JWT認証など、様々な認証戦略(Strategy)をプラグイン形式で提供しています。
- JWT (JSON Web Tokens): 認証状態を安全にクライアントとサーバー間でやり取りするための標準的な方法。
TypeScriptの導入
JavaScriptは動的型付け言語ですが、大規模なプロジェクトになると型のミスによるバグが増えやすくなります。TypeScriptはJavaScriptに静的型付けを加えたスーパーセットであり、コードの可読性、保守性、堅牢性を大幅に向上させます。
- インストール:
npm install --save-dev typescript @types/node @types/express ts-node
- 特徴: コンパイル時に型チェックを行い、開発中のエラーを早期に発見できます。VS Codeなどのエディタでの強力なコード補完やリファクタリング支援も大きなメリットです。
サーバーレス開発 (AWS Lambda, Azure Functions, Google Cloud Functions)
サーバー管理の手間をなくし、使用した分だけ課金されるサーバーレスアーキテクチャもNode.jsと相性が良いです。特定のイベント(HTTPリクエスト、データベースの変更など)に応じて、コードの小さな断片(関数)が実行されます。
- AWS Lambda, Google Cloud Functions, Azure Functionsなどが主要なサーバーレスプラットフォームです。
- フレームワーク: Serverless Framework, Amplify, NestJSなど。
GraphQL
RESTful APIに代わる、新しいAPI設計思想としてGraphQLが注目されています。クライアントが必要なデータだけを一度のリクエストで取得できるため、オーバーフェッチやアンダーフェッチの問題を解決します。
- ライブラリ:
apollo-server
,graphql.js
など。
Node.jsのフレームワーク
Express.jsは軽量で自由度が高いですが、より大規模なアプリケーション開発には、より規約が厳しく、機能が豊富なフレームワークも検討されます。
- NestJS: TypeScriptファーストで、Angularのようなモジュール性、DI (Dependency Injection) などを取り入れた、堅牢でスケーラブルなアプリケーション構築に特化したフレームワーク。
- Next.js (API Routes): 主にReactのフロントエンドフレームワークですが、サーバーサイドのAPI機能 (API Routes) もNode.jsで動作するため、フルスタック開発が可能です。
- Koa.js: Express.jsの作者が開発した、より軽量でモダンなWebフレームワーク。Async/Awaitを全面的に活用しています。
Node.jsコミュニティと学習リソース
Node.jsの学習は、公式ドキュメント、オンラインチュートリアル、書籍、そして活発なコミュニティを活用することが重要です。
- Node.js公式ドキュメント: https://nodejs.org/ja/docs/
- npm Docs: https://docs.npmjs.com/
- MDN Web Docs: JavaScriptの基礎から最新機能まで網羅。
- Stack Overflow: プログラミングに関する質問と回答のコミュニティ。
- GitHub: オープンソースプロジェクトの宝庫。他の開発者のコードを読んで学ぶ。
- 技術ブログ、Udemy, Coursera, freeCodeCamp: 有料・無料の学習コンテンツ。
まとめ
この長いガイドを最後までお読みいただき、本当にありがとうございます!
私たちは、Node.jsの基本的な概念から始まり、開発環境のセットアップ、簡単なプログラムの実行、npmによるパッケージ管理、そして非同期処理やHTTPサーバーといったNode.jsの核心的な概念まで、広範囲にわたるトピックを網羅してきました。そして、Express.jsを使った簡単なWebアプリケーションの構築、デバッグとテストの重要性、さらにはHerokuを使ったデプロイの第一歩も経験しました。
学んだことの振り返り
- Node.jsの基本: JavaScriptをサーバーサイドで動かす実行環境であること。
- 開発環境構築: Node.js/npmのインストール(NVM/Volta推奨)、VS Codeと必須拡張機能のセットアップ。
- プログラムの実行:
node <file.js>
でJavaScriptファイルを実行する方法。 - npmの活用:
package.json
の役割、npm install
,npm start
などの基本コマンド。 - 非同期処理の理解: コールバック、Promise、Async/Awaitの仕組みとその重要性。
- モジュールシステム:
require
/module.exports
(CommonJS) とimport
/export
(ES Modules) の違い。 - Webアプリケーション開発の基礎: Express.jsのルーティング、ミドルウェア、静的ファイルの配信、API作成。
- デバッグとテスト:
console.log()
とVS Codeデバッガー、Jestによる単体テスト。 - デプロイの基礎: Herokuを使った簡単な公開方法。
- 次のステップ: データベース連携、リアルタイム通信、認証、TypeScriptなど、より高度なトピックへの道筋。
継続的な学習の重要性
プログラミング、特にWeb開発の世界は常に進化しています。今日学んだ知識が明日には古くなっている可能性もゼロではありません。しかし、最も重要なのは「学び続ける姿勢」と「手を動かし続けること」です。
このガイドはNode.jsの広大な世界への第一歩に過ぎません。今日得た知識を基盤として、様々なチュートリアルを試したり、小さなプロジェクトを自分で考えたり、オープンソースプロジェクトに参加したりして、積極的に経験を積んでください。
応援メッセージ
Node.jsは非常に強力で、現代のWeb開発において欠かせない技術の一つです。あなたがこのガイドを通してNode.js開発の楽しさや可能性を感じてくれたなら、これほど嬉しいことはありません。
最初は難しいと感じるかもしれませんが、一つずつ着実に学び、コードを書き続けることで、必ず素晴らしい開発者になれるでしょう。
あなたのNode.jsでの成功を心から願っています!
さあ、これからのNode.js開発ライフを楽しんでください!