Node.js: Node.js 入門

アリスはバックエンド開発者です。彼女が勤める会社では、2週間以内にモバイルアプリ用のREST APIバックエンドを構築する必要がありました。チームはJavaScriptしか知らないフロントエンド開発者だけで構成されており、新しい言語を学ぶ時間を割こうとする者は誰もいませんでした。プロジェクトマネージャーはPython開発者を採用することも検討しましたが、どうしても時間が足りませんでした。チームが不安を感じ始めていたちょうどその時、アリスはNode.js——サーバー上でJavaScriptを実行するランタイム——を発見しました。フロントエンド開発者は、すでに慣れ親しんだ構文を使ってバックエンドAPIを記述することができ、プロジェクトは2週間後に無事に公開されました。この経験を通じて、アリスはNode.jsが単なるツールではなく、フロントエンドとバックエンドをつなぐ架け橋であることに気づいたのです。

学習内容:


1. Node.js とは?

(1) 定義

Node.js は、Chrome の V8 エンジンを基盤とする JavaScript 実行環境です。これにより、ブラウザに依存することなく、サーバー上で直接 JavaScript を実行することが可能になります。Node.js は新しい言語でもフレームワークでもなく、JavaScript 用のサーバーサイド実行プラットフォームです。

(2) その起源の背景

2009年、ライアン・ダールはV8エンジンを基盤としてNode.jsを開発しました。彼の当初の目標は、サーバー側のI/O操作によって引き起こされるブロッキングの問題を解決することでした。従来のWebサーバーでは、ファイルの読み取りやネットワークリクエストなどのI/O操作を処理する際にスレッドがブロックされてしまいますが、Node.jsはイベント駆動型のアプローチを採用しており、単一のスレッドで多数の同時接続を効率的に処理することが可能です。

▶ サンプル:初めての Node.js スクリプト

ファイル hello.js を作成:

JAVASCRIPT
console.log('Hello, Node.js!');
console.log('Node.js version:', process.version);
console.log('Platform:', process.platform);
▶ 試してみよう

ターミナルで次のコマンドを実行してください:

BASH
node hello.js

期待される出力:

TEXT 📖 参照専用
Hello, Node.js!
Node.js version: v20.11.0
Platform: win32


2. V8エンジンとNode.jsのアーキテクチャ

(1) V8エンジンの役割

V8は、Googleが開発したJavaScriptエンジンであり、JavaScriptコードをマシンコードにコンパイルして実行します。Node.jsにはV8エンジンが組み込まれているため、これほど高いパフォーマンスを発揮するのです。V8のジャストインタイム(JIT)コンパイル技術により、JavaScriptはネイティブコードに近い速度で実行されます。

(2) Node.js のアーキテクチャ層

Node.jsのアーキテクチャは、下から順に4つの層に分かれています:

レベル 構成 機能
JavaScript コード層 ユーザーが作成した .js ファイル ビジネスロジック
Node.js API レイヤー fs、http、path などのモジュール サーバーサイドの機能を提供
Node.js バインディング層 C++ ブリッジコード JavaScript と基盤となる C ライブラリの連携
低レベルライブラリ V8、libuv、OpenSSL など エンジンとシステムコール

(3) libuvの重要な役割

libuv は Node.js の非同期 I/O ライブラリであり、イベントループ、スレッドプール、および非同期 I/O 向けのクロスプラットフォームな抽象化機能を提供します。これにより、Node.js はファイル I/O、ネットワーク操作、タイマーなどの非同期操作を、さまざまなオペレーティングシステム間で一貫した方法で処理できるようになります。

▶ サンプル:Node.js の依存関係情報の確認

JAVASCRIPT
console.log('V8 version:', process.versions.v8);
console.log('libuv version:', process.versions.libuv);
console.log('OpenSSL version:', process.versions.openssl);
console.log('Node.js version:', process.version);
▶ 試してみよう

出力:

TEXT 📖 参照専用
V8 version: 11.3.244.8
libuv version: 1.46.0
OpenSSL version: 3.0.12
Node.js version: v20.11.0

▶ サンプル:(4) アーキテクチャ図

100%
graph TB
    A["JavaScript Code<br/>(User-written .js Documents)"] --> B["Node.js API<br/>(fs / http / path / ...)"]
    B --> C["Node.js Bindings<br/>(C++ Bridge Layer)"]
    C --> D1["V8 Engine<br/>(JavaScript Compile and Run)"]
    C --> D2["libuv<br/>(Event Loop + Asynchronous I/O)"]
    C --> D3["Other C Libs<br/>(OpenSSL / zlib / c-ares)"]
    D2 --> E["Operating System<br/>(Documents / Internet / Process)"]


3. イベント駆動型およびノンブロッキングI/O

(1) イベント駆動型モデル

Node.js はイベント駆動型アーキテクチャを採用しています。つまり、プログラムは能動的にポーリングを行うのではなく、イベントコールバックを登録することで、さまざまな操作に応答します。I/O 操作が完了すると、イベントループは対応するコールバックをキューに入れ、実行を待ちます。

(2) ノンブロッキングI/Oの意味

従来のサーバーでは、ファイルの読み込み中は、ファイルが完全に読み込まれるまで現在のスレッドをブロックします。一方、Node.js では、I/O リクエストを開始した後、直ちに処理を返し、その後のコードの実行を継続し、I/O 操作が完了したらコールバックを介して結果を処理します。このアプローチにより、単一のスレッドで数百もの同時リクエストを同時に処理することが可能になります。

(3) イベントループの概要

イベントループは Node.js のコアとなるスケジューリング機構であり、以下のフェーズをループして実行されます:

  1. 時間:setTimeout / setInterval のコールバックを実行する
  2. 保留中のコールバック:システム操作を実行するコールバック
  3. アイドル、準備:内部用
  4. poll:新しいI/Oイベントを取得し、I/Oコールバックを実行します
  5. 確認:setImmediateのコールバックを実行する
  6. close コールバック:close イベントのコールバックを実行する

▶ サンプル:ブロッキングとノンブロッキングのファイル読み取り

ブロッキングモード(推奨されません):

JAVASCRIPT
const fs = require('fs');
const data = fs.readFileSync('/etc/hosts', 'utf8');
console.log('File read (blocking):', data.length, 'bytes');
console.log('This line runs after file is read');
▶ 試してみよう

ノンブロッキングモード(推奨):

JAVASCRIPT
const fs = require('fs');
fs.readFile('/etc/hosts', 'utf8', (err, data) => {
  if (err) throw err;
  console.log('File read (non-blocking):', data.length, 'bytes');
});
console.log('This line runs immediately');

出力(ノンブロッキングモード):

TEXT 📖 参照専用
This line runs immediately
File read (non-blocking): 250 bytes

なお、ノンブロッキングモードでは、最初に「This line runs immediately」と出力されます。これは、readFileが後続のコードをブロックしなかったことを示しています。



4. Node.js 対 ブラウザ用 JavaScript

(1) 主な相違点

Node.js とブラウザ上の JavaScript は、同じ言語仕様(ECMAScript)を使用していますが、その実行環境や利用可能な API はまったく異なります。

比較基準 Node.js ブラウザのJavaScript
実行環境 サーバー ブラウザ
モジュールシステム CommonJS / ESM ESM
グローバルオブジェクト グローバル / プロセス ウィンドウ / ドキュメント
ファイルシステム fs モジュールによる直接アクセス 直接アクセス不可
ネットワーク I/O HTTP / ネットワークモジュール fetch / XMLHttpRequest
DOMの操作 DOMなし DOM API
パッケージマネージャー npm なし(またはCDN経由)
主な用途 サーバーアプリケーション、CLIツール Webとのやり取り、UIのレンダリング

(2) 類似点

▶ サンプル:同じ構文、異なるAPI

ブラウザのコード:

JAVASCRIPT
document.getElementById('output').textContent = 'Hello from browser';
▶ 試してみよう

Node.js のコード:

JAVASCRIPT
const fs = require('fs');
fs.writeFileSync('output.txt', 'Hello from Node.js');

JavaScriptの構文は同じですが、操作対象となるオブジェクトはまったく異なります。ブラウザはDOMを操作するのに対し、Node.jsはファイルシステムを操作します。



5. Node.jsの代表的な活用例

(1) REST API サービス

Node.js は RESTful API の構築に最適です。そのノンブロッキング I/O モデルにより、多数の同時リクエストを効率的に処理でき、また JSON は JavaScript のネイティブなデータ形式であるため、シリアライゼーションのオーバーヘッドが排除されます。

(2) CLIツール

Webpack、Babel、ESLint、npm はすべて、Node.js を使用して構築された CLI ツールです。Node.js は、ファイルシステム、子プロセス、およびコマンドライン引数を扱うための豊富な API セットを提供しています。

(3) リアルタイムアプリケーション

チャットシステム、オンラインコラボレーション、リアルタイム通知といったシナリオでは、永続的な双方向接続が必要です。Node.jsのWebSocketサポートとイベント駆動型アーキテクチャは、こうしたニーズに当然ながら非常に適しています。

(4) マイクロサービス

Node.js は起動が速く、メモリ使用量も少ないため、軽量なマイクロサービスに最適です。各マイクロサービスは個別にデプロイおよびスケーリングが可能です。

(5) ウェブクローリングとデータ収集

Cheerioなどのライブラリと組み合わせることで、Node.jsはWebデータを効率的にクロールおよび解析することができ、非同期I/Oにより並行リクエストの処理が極めて効率的になります。

▶ サンプル:ユースケースの比較

シナリオ メリット 代表的なプロジェクト
REST API ノンブロッキングI/O + ネイティブJSON Express / Fastify / Koa
CLI ツール ファイル操作 + サブプロセス Webpack / Babel / ESLint
リアルタイムアプリケーション WebSocket + イベント駆動型 Socket.IO / ws
マイクロサービス 軽量でセットアップが簡単 NestJS / Seneca
ウェブスクレイピング 非同期並行処理 + DOM 解析 Puppeteer / Cheerio

▶ サンプル:5行のコードでHTTPサーバーを作成する

JAVASCRIPT
const http = require('http');
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({ message: 'Hello from Node.js API' }));
});
server.listen(3000, () => console.log('Server running on port 3000'));
▶ 試してみよう
BASH
node server.js
TEXT 📖 参照専用
Server running on port 3000

JSONレスポンスを確認するには、http://localhost:3000 にアクセスしてください。



6. Node.js のバージョンに関する方針

(1) LTS と現行版

Node.js はデュアルトラック方式のリリース戦略を採用しています:

比較 LTS(長期サポート) 現行
リリースサイクル 2年に1回のメジャーリリース 6ヶ月に1回のメジャーリリース
保守期間 30ヶ月 約6ヶ月
安定性 高;バグ修正とセキュリティパッチのみが含まれる 低;最新の機能が含まれる
ユースケース 本番環境 新機能の試用・テスト
バージョン番号の付け方 偶数(18、20、22…) 奇数(19、21、23…)

(2) バージョンの選び方に関する推奨事項

(3) バージョン管理ツール

Node.js のバージョンの管理や切り替えには、nvm(Node Version Manager)の使用をお勧めします。

▶ サンプル:nvm を使ったバージョンの管理

BASH
nvm install 20
nvm use 20
nvm ls
TEXT 📖 参照専用
       v18.17.0
->     v20.11.0
         system
default -> 20 (-> v20.11.0)

▶ サンプル:Node.js の現在のバージョンと状態を確認する

BASH
node -v
node -e "console.log(process.release.lts ? 'LTS: ' + process.release.lts : 'Current (non-LTS)')"
TEXT 📖 参照専用
v20.11.0
LTS: Iron

❓ よくある質問

Q Node.js は新しい言語ですか?
A いいえ。Node.js は、JavaScript をサーバー側で実行できるようにする JavaScript の実行環境であり、言語自体は依然として JavaScript です。
Q なぜNode.jsはI/O負荷の高いアプリケーションに適しているのですか?
A Node.jsはイベント駆動型のノンブロッキングI/Oモデルを採用しており、単一のスレッドが多数の同時I/Oリクエストを同時に処理できるため、1つの処理が遅いというだけでプロセス全体がブロックされることがありません。
Q Node.js はどのような用途には適していないのでしょうか?
A 動画エンコード、大規模な数学的計算、画像処理など、CPU を多用するタスクです。CPU が長時間使用されるとイベントループがブロックされ、すべてのリクエストがキューに蓄積されてしまいます。こうした種類のタスクは、ワーカースレッドや外部サービスで処理すべきです。
Q Node.js を学ぶ前に、JavaScript を学ぶ必要がありますか?
A はい。Node.js 自体は新しい言語ではなく、JavaScript を実行するものです。Node.js を効果的に活用するには、JavaScript の構文、関数、オブジェクト、および非同期プログラミング(Promises / async-await)の基礎を習得しておく必要があります。
Q What is the difference between Node.js and Deno?
A Deno is also a JavaScript/TypeScript runtime, created by Ryan Dahl, the original creator of Node.js. Key differences: Deno natively supports TypeScript, uses ES Modules instead of CommonJS, has a security sandbox (which disables file and network access by default), does not require a package.json or node_modules directory, and includes built-in formatting and testing tools in its standard library. The Deno ecosystem is still growing, while the Node.js ecosystem is more mature.
Q Node.js はシングルスレッドですか?
A JavaScript コードは単一のスレッドで実行されますが、Node.js は内部で libuv スレッドプール(デフォルトでは 4 スレッド)を使用して、ファイル I/O や DNS 検索、その他の操作を処理しています。また、CPU 負荷の高いタスクを処理するためのワーカースレッドもサポートしています。
Q Node.js を学ぶには何をインストールすればよいですか?
A Node.js(npm パッケージマネージャーが付属しています)とコードエディタ(VS Code を推奨します)をインストールするだけで十分です。インストール後、ターミナルで node -v を実行して、正常に動作するか確認してください。

📖 まとめ


📝 練習問題

  1. Node.js(LTS版を推奨)をインストールし、node -v を実行してインストールが正常に完了したことを確認した後、バージョン番号とLTS版であるかどうかをメモしておいてください。
  2. hello.js という名前のファイルを作成し、console.log を使って自分の名前と Node.js のバージョン番号を出力させ、それを実行してスクリーンショットを撮ってください
  3. process オブジェクトを使用して、Node.js のバージョン、OS のプラットフォーム、現在の作業ディレクトリ、および CPU アーキテクチャという情報を出力するスクリプトを作成してください。
  4. fs.readFile を使用して、テキストファイルをノンブロッキングモードで読み込み、その内容を出力し、コールバック関数の実行順序を確認する
  5. 同じファイルを読み込む際に、コールバックの前後でそれぞれタイムスタンプを出力し、fs.readFileSync(ブロッキング)とfs.readFile(ノンブロッキング)を比較して、両者の実行の違いを明らかにする。


7. 総合的な例:システム情報を読み取るスクリプト

以下のスクリプトは、Node.js の組み込みモジュールを使用してシステム情報を読み取り、出力するもので、サーバーサイドランタイムとしての Node.js の基本的な機能を示しています:

JAVASCRIPT
const os = require('os');
const fs = require('fs');
const path = require('path');

const sysInfo = {
  nodeVersion: process.version,
  platform: process.platform,
  arch: process.arch,
  hostname: os.hostname(),
  totalMemoryMB: Math.round(os.totalmem() / 1024 / 1024),
  freeMemoryMB: Math.round(os.freemem() / 1024 / 1024),
  cpuCores: os.cpus().length,
  cpuModel: os.cpus()[0].model,
  uptimeHours: (os.uptime() / 3600).toFixed(2),
  cwd: process.cwd(),
  homedir: os.homedir()
};

const output = JSON.stringify(sysInfo, null, 2);
console.log(output);

const filePath = path.join(os.homedir(), 'nodejs-sysinfo.txt');
fs.writeFile(filePath, output, 'utf8', (err) => {
  if (err) {
    console.error('Write failed:', err.message);
    return;
  }
  console.log('System info saved to:', filePath);
});

期待される出力:

TEXT 📖 参照専用
{
  "nodeVersion": "v20.11.0",
  "platform": "win32",
  "arch": "x64",
  "hostname": "DESKTOP-ABC123",
  "totalMemoryMB": 16384,
  "freeMemoryMB": 8192,
  "cpuCores": 8,
  "cpuModel": "Intel(R) Core(TM) i7-12700K",
  "uptimeHours": "48.32",
  "cwd": "C:\\projects\\node-demo",
  "homedir": "C:\\Users\\Alice"
}
System info saved to: C:\Users\Alice\nodejs-sysinfo.txt

このスクリプトは、Node.js の 3 つの主要な機能、すなわちオペレーティングシステム情報の取得 (os)、ファイルへの書き込み (fs)、およびパスの処理 (path) を実演しています。また、ファイルへの書き込みにはノンブロッキングI/Oが使用されています。fs.writeFileのコールバックはconsole.logの後に実行され、Node.jsのイベント駆動型の性質を示しています。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%