第7章 実践パターン

更新日:2025年12月17日

本章では、実務で必要となるNode.js開発のパターンを解説する。ログ設計、デバッグ手法、モック、設定管理といった、品質の高いシステムを構築するための基礎知識を整理する。

1. ログ

1.1 console.logの問題点

開発中は`console.log`でデバッグすることが多いが、実務では不十分である。

Table 1. console.logの問題点

問題 説明
残らない サーバー再起動で消える
いつか分からない タイムスタンプがない
どこか分からない ファイル名・行番号がない
重要度が分からない 警告なのかエラーなのか区別できない

1.2 ログレベル

ログには重要度を示す「レベル」がある。

Table 2. ログレベル一覧

レベル 意味
TRACE 最も詳細。メソッドの出入りまで login() メソッド開始
DEBUG 開発時の詳細情報 ユーザーID=123でログイン試行
INFO 正常な動作の記録 ログイン成功
WARN 警告(動作は継続) 応答に3秒かかりました
ERROR エラー(処理失敗) ログイン失敗
FATAL 致命的(システム停止) DB接続不可

1.3 出力レベルの設定

ログには2つの「レベル」の概念がある。

Table 3. 2つのレベル

種類 意味
コードで指定 「このログはDEBUGレベルです」
設定で指定 「INFOレベル以上だけ表示しなさい」

Fig. 1 フィルタリングの仕組み

設定:ログレベル = INFO(INFO以上を表示)

コードが出力しようとするログ:
[TRACE] ...  → 表示されない(INFO未満)
[DEBUG] ...  → 表示されない(INFO未満)
[INFO]  ...  → 表示される ✓
[WARN]  ...  → 表示される ✓
[ERROR] ...  → 表示される ✓
[FATAL] ...  → 表示される ✓

1.4 環境による切り替え

Table 4. 環境別設定

環境 設定レベル 表示されるログ
開発環境 DEBUG DEBUG, INFO, WARN, ERROR, FATAL
テスト環境 DEBUG DEBUG, INFO, WARN, ERROR, FATAL
本番環境 INFO INFO, WARN, ERROR, FATAL

コードは変えず、設定だけで表示されるログを切り替えられる。

1.5 Node.jsでの実装

const winston = require('winston');

// 環境変数でレベルを切り替え
const level = process.env.LOG_LEVEL || 'info';

const logger = winston.createLogger({
    level: level,
    format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.printf(({ timestamp, level, message }) => {
            return `[${level.toUpperCase()}] ${timestamp} - ${message}`;
        })
    ),
    transports: [
        new winston.transports.Console(),
        new winston.transports.File({ filename: 'app.log' })
    ]
});

// 使用例
logger.debug('詳細情報');    // DEBUGレベル
logger.info('ログイン成功');  // INFOレベル
logger.warn('応答が遅い');    // WARNレベル
logger.error('ログイン失敗'); // ERRORレベル

1.6 Javaのログ設定(参考)

Javaのログ設定は複雑である。歴史的経緯により複数のライブラリが存在する。

Table 5. Javaのログライブラリ

名前 種類 説明
java.util.logging 実装 Java標準
Log4j / Log4j2 実装 老舗。広く使われた
Logback 実装 Log4j作者の改良版
SLF4J インターフェース 統一API。実装は別途選ぶ

Fig. 2 SLF4Jと実装の関係

SLF4J(インターフェース)
    │
    │ どれか1つを選ぶ
    ↓
┌─────────┬─────────┬─────────┐
│ Logback │ Log4j2  │  JUL    │
│ (実装) │ (実装) │ (実装) │
└─────────┴─────────┴─────────┘

コードはSLF4Jで書き、実装は設定で差し替えられる。

2. デバッグ

2.1 デバッグの方法

Table 6. デバッグ方法の比較

方法 説明 用途
console.log 値を出力して確認 簡単な確認
デバッガ 1行ずつ実行して確認 複雑な問題
ログ分析 記録されたログを調べる 本番環境の問題

2.2 デバッガの利点

Table 7. デバッガの機能

機能 説明
ブレークポイント 任意の行で停止できる
ステップ実行 1行ずつ進められる
変数確認 全変数の値を一覧で見られる
コールスタック どの関数から呼ばれたか分かる
式の評価 停止中に任意の式を実行できる

2.3 デバッガの操作

Table 8. VS Codeのデバッグ操作

操作 キー 説明
続行 F5 次のブレークポイントまで進む
ステップオーバー F10 次の行へ(関数の中には入らない)
ステップイン F11 次の行へ(関数の中に入る)
ステップアウト Shift+F11 現在の関数を抜ける
停止 Shift+F5 デバッグ終了

2.4 デバッグパネル

Table 9. デバッグパネルの役割

パネル 役割 使うタイミング
VARIABLES 変数の値を見る 常に
CALL STACK 呼び出し階層を見る 「どこから来た?」
BREAKPOINTS ブレークポイント管理 複数設置時
WATCH 任意の式を評価 「この条件は?」

2.5 ステップイン問題の対処

F11(ステップイン)でライブラリの中に入ってしまい迷子になることがある。

Table 10. 対処方法

方法 操作
ステップアウト連打 Shift+F11を繰り返す
ブレークポイント+続行 戻りたい行にブレークポイント → F5
コールスタック利用 自分のコードをクリックして戻る

VS Codeでは`skipFiles`設定でnode_modules等をスキップできる。

// .vscode/launch.json
{
    "skipFiles": [
        "<node_internals>/**",
        "node_modules/**"
    ]
}

3. モック

3.1 モックとは

モックとは「本物の代わりになる偽物」である。テスト時に外部システムへの接続を避けるために使用する。

3.2 なぜモックが必要か

本物のシステムでテストする問題点を整理する。

Table 11. 本物のシステムでテストする問題

問題 説明
実際に実行される テストで発注 → 本当に届く
コストがかかる 実際の請求が発生
環境依存 メンテナンス中はテストできない
再現性がない 状態が毎回違う

3.3 Node.jsでのモック実装

// 本物の関数
async function order(productId, quantity) {
    const response = await fetch('https://api.example.com/order', {
        method: 'POST',
        body: JSON.stringify({ productId, quantity })
    });
    return response.json();
}

// モック(テスト用)
async function orderMock(productId, quantity) {
    return {
        success: true,
        orderId: 'TEST-001',
        message: '発注完了(モック)'
    };
}

// 環境変数で切り替え
const orderFunction = process.env.NODE_ENV === 'test' 
    ? orderMock 
    : order;

3.4 Playwrightでのモック

Playwrightにはネットワークリクエストをモックする機能がある。

// 特定のAPIをモック
await page.route('**/api/order', route => {
    route.fulfill({
        status: 200,
        body: JSON.stringify({
            success: true,
            orderId: 'MOCK-001'
        })
    });
});

// この後のページ操作では、/api/order への通信がモックされる
await page.click('#order-button');

3.5 モックの種類

Table 12. モックの種類

種類 説明 用途
モック 偽の実装を用意 外部API、DB
スタブ 固定値を返す 単純なテスト
スパイ 呼び出しを記録 「何回呼ばれたか」確認

4. 設定管理

4.1 ハードコードの問題

// 悪い例:ハードコード
const dbHost = 'localhost';
const dbPort = 3306;
const apiKey = 'abc123';

Table 13. ハードコードの問題

問題 説明
環境ごとに変えられない 開発と本番でDBが違う
セキュリティ APIキーがコードに残る
変更のたびにビルド 設定変更でデプロイが必要

4.2 環境変数

// 環境変数から読み込む
const dbHost = process.env.DB_HOST;
const dbPort = process.env.DB_PORT;
const apiKey = process.env.API_KEY;
# 開発環境
DB_HOST=localhost DB_PORT=3306 node app.js

# 本番環境
DB_HOST=prod-db.example.com DB_PORT=3306 node app.js

4.3 .envファイル

環境変数をファイルにまとめる方法である。

# .env
DB_HOST=localhost
DB_PORT=3306
API_KEY=abc123
// dotenvパッケージを使用
require('dotenv').config();

const dbHost = process.env.DB_HOST;

重要:.envはGitに含めない(.gitignoreに追加)。代わりに.env.exampleを用意する。

# .env.example(Gitに含める)
DB_HOST=
DB_PORT=
API_KEY=

4.4 設定管理の使い分け

Table 14. 設定方法の使い分け

方法 用途
環境変数 秘密情報(APIキー、パスワード)
.envファイル ローカル開発用の環境変数管理
config.json 秘密でない設定(ポート番号、URL等)

5. まとめ

Table 15. 第7章のまとめ

概念 内容
ログレベル TRACE/DEBUG/INFO/WARN/ERROR/FATAL
ログ設定 環境ごとに出力レベルを切り替え
デバッガ ブレークポイント、ステップ実行、変数確認
デバッグ操作 F5続行、F10オーバー、F11イン、Shift+F11アウト
モック 本物の代わりになる偽物
設定の外部化 環境変数、.env、config.json
参考・免責事項
本コンテンツは2025年12月時点の情報に基づいて作成されています。Node.jsおよび関連ツールは活発に開発が進められており、APIや機能が変更される可能性があります。最新情報は公式ドキュメントをご確認ください。