Node.jsは、JavaScriptをサーバーサイドで実行するためのランタイム環境です。2009年にRyan Dahlによって開発されて以来、Node.jsはWebアプリケーション開発の風景を一変させました。本記事では、Node.jsの基本概念から実際のインストール、REPL操作までを体系的に解説します。

実行環境

項目 バージョン
Node.js 20.x LTS以上
npm 10.x以上
OS Windows/macOS/Linux

前提条件

  • JavaScriptの基礎文法を理解していること
  • コマンドライン(ターミナル)の基本操作ができること

Node.jsとは

Node.jsは、オープンソースかつクロスプラットフォームのJavaScriptランタイム環境です。Google ChromeのV8 JavaScriptエンジンをベースに構築されており、ブラウザ外でJavaScriptを実行できます。

graph TD
    A[JavaScript コード] --> B[Node.js ランタイム]
    B --> C[V8 エンジン]
    B --> D[libuv]
    C --> E[JavaScript 実行]
    D --> F[非同期I/O]
    D --> G[イベントループ]
    D --> H[スレッドプール]

Node.jsは単一プロセスで動作し、リクエストごとに新しいスレッドを作成しません。標準ライブラリで提供される非同期I/Oプリミティブにより、JavaScriptコードがブロッキングすることを防ぎます。

Node.jsの歴史と設計思想

誕生の背景

2009年、Ryan DahlはJSConf EUでNode.jsを発表しました。当時のサーバーサイド開発では、ApacheのようなWebサーバーがリクエストごとにスレッドを生成する「スレッドベース」のモデルが主流でした。しかし、このモデルには以下の課題がありました。

  • 大量の同時接続でメモリ消費が増大する
  • スレッド間のコンテキストスイッチによるオーバーヘッド
  • デッドロックや競合状態などの並行処理の複雑さ

Ryan Dahlは、これらの課題を解決するために「イベント駆動」と「ノンブロッキングI/O」を核とした新しいアプローチを提案しました。

設計思想

Node.jsの設計は、以下の原則に基づいています。

原則 説明
シングルスレッド メインスレッドは1つで、イベントループがすべてを管理
ノンブロッキングI/O I/O操作を待機せず、コールバックで結果を受け取る
イベント駆動 イベントの発生を監視し、適切なハンドラを実行
モジュラー設計 小さなモジュールを組み合わせてアプリケーションを構築

V8エンジンとは

V8は、Google Chromeを動かすJavaScriptエンジンです。C++で記述されており、JavaScriptコードを解析して実行します。

V8の特徴

V8エンジンが他のJavaScriptエンジンと異なる点は、JIT(Just-In-Time)コンパイルを採用していることです。

graph LR
    A[JavaScript ソースコード] --> B[パース]
    B --> C[AST生成]
    C --> D[Ignition<br/>インタプリタ]
    D --> E[バイトコード]
    E --> F{ホットコード?}
    F -->|Yes| G[TurboFan<br/>最適化コンパイラ]
    G --> H[最適化された<br/>マシンコード]
    F -->|No| I[バイトコード実行]

V8は、以下の2つのコンパイラを持っています。

  • Ignition: ベースラインインタプリタ。JavaScriptをバイトコードに変換して実行
  • TurboFan: 最適化コンパイラ。頻繁に実行されるコード(ホットコード)を高度に最適化されたマシンコードにコンパイル

この仕組みにより、JavaScriptは「インタプリタ言語」でありながら、コンパイル言語に匹敵するパフォーマンスを発揮できます。

libuvとは

libuvは、Node.jsの非同期I/Oを実現するためのC言語ライブラリです。イベントループの実装とクロスプラットフォームの非同期I/O操作を提供します。

libuvの役割

graph TD
    subgraph "Node.js"
        A[JavaScript API]
        B[Node.js バインディング]
    end
    
    subgraph "libuv"
        C[イベントループ]
        D[スレッドプール]
        E[非同期I/Oハンドル]
    end
    
    subgraph "OS"
        F[epoll/kqueue/IOCP]
        G[ファイルシステム]
        H[ネットワーク]
    end
    
    A --> B
    B --> C
    C --> D
    C --> E
    D --> G
    E --> F
    F --> H

libuvは以下の機能を提供します。

機能 説明
イベントループ 非同期イベントの監視と処理
スレッドプール ファイルI/O等のブロッキング操作を別スレッドで実行
非同期DNS解決 ホスト名解決を非同期で実行
非同期ファイルI/O ファイル操作を非同期で実行
子プロセス 外部プロセスの生成と管理
シグナルハンドリング OSシグナルの処理

ブラウザJavaScriptとの違い

ブラウザとNode.jsは、どちらもJavaScriptを実行しますが、利用可能なAPIと実行環境が大きく異なります。

主な違い

項目 ブラウザ Node.js
実行環境 ブラウザ内 OS上
DOM操作 可能(document, window 不可
ファイルシステム 制限あり(Web APIs経由) 完全アクセス(fsモジュール)
ネットワーク Fetch API, XMLHttpRequest http, https, netモジュール
モジュールシステム ES Modules CommonJS, ES Modules両対応
グローバルオブジェクト window global, globalThis
ECMAScriptバージョン ブラウザ依存 Node.jsバージョンで決定

コード例で見る違い

ブラウザではwindowオブジェクトがグローバルスコープですが、Node.jsではglobalオブジェクトを使用します。

1
2
3
4
5
6
7
// ブラウザ環境
console.log(window.location.href);
console.log(document.title);

// Node.js環境
console.log(process.cwd());
console.log(__filename);

Node.jsでは、documentwindowは存在しません。代わりに、processオブジェクトを通じて環境変数やコマンドライン引数にアクセスできます。

1
2
3
4
5
6
7
8
// 環境変数の取得
console.log(process.env.NODE_ENV);

// コマンドライン引数の取得
console.log(process.argv);

// 現在の作業ディレクトリ
console.log(process.cwd());

ES2020で導入されたglobalThisを使用すると、環境を問わずグローバルオブジェクトにアクセスできます。

1
2
// ブラウザでもNode.jsでも動作
console.log(globalThis);

シングルスレッドとイベントループモデル

Node.jsの最も重要な特徴は、シングルスレッドでありながら高い並行処理能力を持つことです。これはイベントループモデルによって実現されています。

イベントループとは

イベントループは、Node.jsがノンブロッキングI/O操作を実行できる仕組みです。JavaScriptはシングルスレッドで実行されますが、I/O操作はOSカーネルにオフロードされます。

graph TD
    A[スクリプト開始] --> B[同期コード実行]
    B --> C{イベントキューに<br/>タスクあり?}
    C -->|Yes| D[コールバック実行]
    D --> C
    C -->|No| E{待機中の<br/>タイマー/I/Oあり?}
    E -->|Yes| F[待機]
    F --> C
    E -->|No| G[プロセス終了]

イベントループのフェーズ

イベントループは、以下の6つのフェーズで構成されています。

   ┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │
   └───────────────────────────┘

各フェーズの役割は以下の通りです。

フェーズ 説明
timers setTimeout()setInterval()のコールバックを実行
pending callbacks 前回のループで延期されたI/Oコールバックを実行
idle, prepare 内部処理用(通常は使用しない)
poll 新しいI/Oイベントを取得し、I/O関連のコールバックを実行
check setImmediate()のコールバックを実行
close callbacks クローズイベントのコールバック(例:socket.on('close'))を実行

ノンブロッキングI/Oの仕組み

従来のブロッキングI/Oモデルでは、I/O操作が完了するまでスレッドがブロックされます。

1
2
3
4
5
// ブロッキングI/O(同期)
const fs = require('node:fs');
const data = fs.readFileSync('/path/to/file'); // ここで待機
console.log(data);
console.log('ファイル読み込み完了');

Node.jsのノンブロッキングI/Oモデルでは、I/O操作を開始した後、即座に制御を返します。

1
2
3
4
5
6
7
// ノンブロッキングI/O(非同期)
const fs = require('node:fs');
fs.readFile('/path/to/file', (err, data) => {
  if (err) throw err;
  console.log(data);
});
console.log('ファイル読み込みを開始しました');

この非同期モデルにより、Node.jsは単一のスレッドで数千の同時接続を処理できます。

バージョン管理(LTS vs Current)

Node.jsには、2つのリリースラインがあります。適切なバージョンを選択することは、安定した開発環境を維持するために重要です。

リリースサイクル

gantt
    title Node.js リリースサイクル
    dateFormat  YYYY-MM
    section v20
    Current     :2023-04, 6M
    Active LTS  :2023-10, 12M
    Maintenance :2024-10, 18M
    section v22
    Current     :2024-04, 6M
    Active LTS  :2024-10, 12M
    Maintenance :2025-10, 18M
    section v24
    Current     :2025-05, 6M
    Active LTS  :2025-12, 12M

LTS(Long Term Support)とは

LTSは、長期サポート版を意味します。以下の特徴があります。

項目 LTS Current
対象者 本番環境での利用者 新機能を試したい開発者
サポート期間 30ヶ月 6ヶ月
安定性 高い 変更が多い
新機能 控えめ 積極的に追加
バージョン番号 偶数(20, 22, 24) 奇数(21, 23, 25)

2026年1月時点の最新バージョン

バージョン コードネーム ステータス 初回リリース
v25 - Current 2025年10月
v24 Krypton Active LTS 2025年5月
v22 Jod Maintenance LTS 2024年4月
v20 Iron Maintenance LTS 2023年4月

本番環境では、Active LTSまたはMaintenance LTSバージョンの使用を推奨します。

Node.jsのインストール

公式サイトからのインストール

Node.js公式サイト(https://nodejs.org/)から、お使いのOSに対応したインストーラをダウンロードできます。

Windowsの場合

  1. https://nodejs.org/ にアクセス
  2. LTS版のWindowsインストーラ(.msi)をダウンロード
  3. インストーラを実行し、画面の指示に従う
  4. インストール完了後、コマンドプロンプトまたはPowerShellで確認
1
2
node --version
npm --version

macOSの場合

  1. https://nodejs.org/ にアクセス
  2. LTS版のmacOSインストーラ(.pkg)をダウンロード
  3. インストーラを実行し、画面の指示に従う
  4. ターミナルで確認
1
2
node --version
npm --version

Linuxの場合(Ubuntu/Debian)

Node.jsの公式リポジトリを使用してインストールします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 必要なパッケージをインストール
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

# NodeSourceのGPGキーを追加
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

# Node.js 20.xのリポジトリを追加
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

# Node.jsをインストール
sudo apt-get update
sudo apt-get install nodejs -y

# バージョン確認
node --version
npm --version

インストールの確認

インストールが成功したかどうかを確認するには、以下のコマンドを実行します。

1
2
3
4
5
node --version
# 出力例: v20.10.0

npm --version
# 出力例: 10.2.3

バージョン番号が表示されれば、インストールは成功です。

Node.js REPLの使い方

REPLは、Read-Eval-Print Loopの略で、対話的にJavaScriptコードを実行できる環境です。コードの動作確認やプロトタイピングに便利です。

REPLの起動

ターミナルでnodeコマンドを引数なしで実行すると、REPLが起動します。

1
node

プロンプト(>)が表示されたら、JavaScriptコードを入力できます。

> 1 + 1
2
> 'Hello, ' + 'Node.js'
'Hello, Node.js'
>

基本的な操作

REPLでは、入力したコードが即座に評価され、結果が表示されます。

> const greeting = 'Hello, World!'
undefined
> greeting
'Hello, World!'
> greeting.toUpperCase()
'HELLO, WORLD!'

undefinedは、変数宣言文の戻り値です。式の場合は、その評価結果が表示されます。

複数行のコード入力

関数定義など、複数行にわたるコードも入力できます。REPLは、コードが完結していない場合、自動的に複数行モードに入ります。

> function greet(name) {
... return `Hello, ${name}!`;
... }
undefined
> greet('Node.js')
'Hello, Node.js!'

特殊変数

REPLには、便利な特殊変数があります。

変数 説明
_ 直前の式の評価結果を保持
_error 直前に発生したエラーを保持
> 5 * 10
50
> _ + 10
60
> 'result: ' + _
'result: 60'

ドットコマンド

REPLには、.で始まる特殊コマンドがあります。

コマンド 説明
.help ヘルプを表示
.editor エディタモードを開始(複数行入力に便利)
.break 現在の入力をキャンセル
.clear コンテキストをリセット
.load ファイルからコードを読み込み
.save セッションの履歴をファイルに保存
.exit REPLを終了
> .help
.break    Sometimes you get stuck, this gets you out
.clear    Alias for .break
.editor   Enter editor mode
.exit     Exit the REPL
.help     Print this help message
.load     Load JS from a file into the REPL session
.save     Save all evaluated commands in this REPL session to a file

エディタモード

.editorコマンドを使用すると、複数行のコードを快適に入力できます。

> .editor
// エディタモード開始
// コードを入力し、Ctrl+Dで実行
function calculateArea(width, height) {
  return width * height;
}

const area = calculateArea(5, 10);
console.log(`面積: ${area}`);
// Ctrl+D を押して実行
面積: 50
undefined

REPLの終了

REPLを終了するには、以下のいずれかの方法を使用します。

  • .exitコマンドを入力
  • Ctrl+Cを2回押す
  • Ctrl+Dを押す
> .exit

最初のNode.jsスクリプト

REPLでの動作確認ができたら、スクリプトファイルを作成して実行してみましょう。

Hello Worldスクリプト

hello.jsという名前のファイルを作成します。

1
2
3
4
5
6
7
8
9
// hello.js
console.log('Hello, Node.js!');

// 現在のNode.jsバージョンを表示
console.log(`Node.js version: ${process.version}`);

// 実行環境の情報を表示
console.log(`Platform: ${process.platform}`);
console.log(`Architecture: ${process.arch}`);

ターミナルでスクリプトを実行します。

1
node hello.js

実行結果は以下のようになります。

Hello, Node.js!
Node.js version: v20.10.0
Platform: win32
Architecture: x64

HTTPサーバーの作成

Node.jsの典型的なユースケースとして、HTTPサーバーを作成してみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// server.js
const http = require('node:http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  res.end('Hello, Node.js!\n');
});

server.listen(port, hostname, () => {
  console.log(`サーバーが http://${hostname}:${port}/ で起動しました`);
});

スクリプトを実行します。

1
node server.js

ブラウザで http://127.0.0.1:3000/ にアクセスすると、「Hello, Node.js!」と表示されます。

サーバーを停止するには、ターミナルでCtrl+Cを押します。

まとめ

本記事では、Node.jsの基礎について解説しました。

  • Node.jsとは: V8エンジンを使用したサーバーサイドJavaScriptランタイム
  • 歴史と設計思想: 2009年にRyan Dahlが開発。イベント駆動・ノンブロッキングI/Oを採用
  • V8エンジン: JITコンパイルにより高速なJavaScript実行を実現
  • libuv: クロスプラットフォームの非同期I/Oライブラリ
  • ブラウザとの違い: DOM操作不可、ファイルシステムアクセス可能、モジュールシステムの違い
  • イベントループ: シングルスレッドで高い並行処理能力を実現する仕組み
  • バージョン管理: LTS版(偶数)を本番環境で使用、Current版(奇数)は新機能検証用
  • REPL: 対話的なJavaScript実行環境

次のステップとして、nvmやfnmを使用したNode.jsのバージョン管理や、package.jsonを使用したプロジェクト管理について学ぶことをおすすめします。

参考リンク