Node.js チートシート

cheatsheet

基本的なコマンドライン操作

Node.js環境での基本的なコマンドライン操作です。

目的 コマンド 説明
REPL起動 node Read-Eval-Print Loop を起動し、対話的にJavaScriptを実行できます。
スクリプト実行 node [ファイル名].js 指定したJavaScriptファイルを実行します。
バージョン確認 node -v または node --version インストールされているNode.jsのバージョンを表示します。
コード片の評価 node -e "[コード]" または node --eval "[コード]" コマンドラインから直接JavaScriptコードを実行します。例: node -e "console.log(1+1)"
入力コードのチェック node -c [ファイル名].js または node --check [ファイル名].js スクリプトを実行せずに構文エラーがないかチェックします。

モジュールシステム CommonJS & ES Modules

Node.jsでは主にCommonJSが使われてきましたが、ES Modules (ESM) も標準でサポートされています。

CommonJS (デフォルト)

操作 コード例 説明
モジュールのエクスポート
// myModule.js
const myFunction = () => { console.log('Hello!'); };
module.exports = { myFunction };
// または
exports.myFunction = () => { console.log('Hello!'); };
module.exports または exports を使って外部に公開する機能を定義します。module.exportsは直接オブジェクトや関数を代入できます。
モジュールのインポート
// main.js
const myModule = require('./myModule');
myModule.myFunction(); // 'Hello!'
require() 関数を使って他のモジュールを読み込みます。パスは相対パスまたはモジュール名を指定します。同期的に読み込まれます。
コアモジュールのインポート
const fs = require('fs');
const path = require('path');
Node.jsに組み込まれているモジュール(ファイルシステム、パス操作など)を読み込みます。

ES Modules (ESM)

ESMを使用するには、ファイル拡張子を .mjs にするか、package.json"type": "module" を追加します。

操作 コード例 説明
名前付きエクスポート
// myModule.mjs
export const myFunction = () => { console.log('Hello!'); };
export const myVariable = 123;
export キーワードを使って関数や変数を個別に公開します。
デフォルトエクスポート
// myDefaultModule.mjs
const myClass = class { /* ... */ };
export default myClass;
export default を使って、モジュールから単一の主要な値を公開します。各モジュールに1つだけ設定できます。
名前付きインポート
// main.mjs
import { myFunction, myVariable } from './myModule.mjs';
myFunction(); // 'Hello!'
console.log(myVariable); // 123
import { ... } from '...' 構文で、名前付きエクスポートされた要素を読み込みます。
デフォルトインポート
// main.mjs
import MyClass from './myDefaultModule.mjs';
const instance = new MyClass();
import AnyName from '...' 構文で、デフォルトエクスポートされた値を読み込みます。AnyName は任意の名前にできます。
すべての名前付きインポート (Namespace Import)
// main.mjs
import * as Utils from './myModule.mjs';
Utils.myFunction();
console.log(Utils.myVariable);
import * as Name from '...' 構文で、すべての名前付きエクスポートを単一のオブジェクトにまとめて読み込みます。
CommonJS モジュールのインポート (ESM内から)
// main.mjs
import fs from 'fs'; // コアモジュール
import _ from 'lodash'; // npm パッケージ (CommonJS)

// CommonJSファイルを動的にインポート (非推奨、可能なら避ける)
// const { someFunction } = await import('./commonjs-module.cjs');
ESM内からCommonJSモジュールを import できます (Node.jsが変換)。コアモジュールも同様です。Dynamic import import() は Promise を返します。
⚠️ CommonJS と ESM には相互運用性の制約があります。特に ESM から CommonJS の名前付きエクスポートを直接 import { ... } で読み込むことは難しい場合があります。package.json"type" フィールドの設定に注意してください。

ファイルシステム操作 (fs) 📂

fs モジュールはファイルシステムの操作を提供します。多くのメソッドには同期版 (Sync) と非同期版 (コールバック、Promise) があります。非同期版の使用が推奨されます。

基本的なファイル操作 (Promiseベース)

require('fs').promises または import { promises as fs } from 'fs'; で利用可能です。

目的 コード例 (async/await) 説明
ファイル読み込み
import { promises as fs } from 'fs';

async function readFileContent(filePath) {
  try {
    const data = await fs.readFile(filePath, 'utf8');
    console.log('ファイル内容:', data);
  } catch (err) {
    console.error('読み込みエラー:', err);
  }
}
ファイルを非同期に読み込みます。第二引数でエンコーディングを指定しない場合、Bufferオブジェクトが返ります。
ファイル書き込み
import { promises as fs } from 'fs';

async function writeFileContent(filePath, content) {
  try {
    await fs.writeFile(filePath, content, 'utf8');
    console.log('書き込み成功!');
  } catch (err) {
    console.error('書き込みエラー:', err);
  }
}
ファイルに非同期に書き込みます。ファイルが存在しない場合は新規作成、存在する場合は上書きされます。
ファイル追記
import { promises as fs } from 'fs';

async function appendFileContent(filePath, content) {
  try {
    await fs.appendFile(filePath, content, 'utf8');
    console.log('追記成功!');
  } catch (err) {
    console.error('追記エラー:', err);
  }
}
ファイルに非同期に追記します。ファイルが存在しない場合は新規作成されます。
ファイル/ディレクトリ存在確認
import { promises as fs } from 'fs';
import { constants } from 'fs'; //定数をインポート

async function checkExists(path) {
  try {
    await fs.access(path, constants.F_OK); // F_OK: 存在確認
    console.log(`${path} は存在します。`);
    // constants.R_OK (読み取り可能か), constants.W_OK (書き込み可能か) も使える
  } catch (err) {
    if (err.code === 'ENOENT') {
      console.log(`${path} は存在しません。`);
    } else {
      console.error('アクセスエラー:', err);
    }
  }
}
ファイルやディレクトリの存在やアクセス権を確認します。存在しない場合やアクセス権がない場合にエラーがスローされます。非推奨: 古い `fs.exists` は使わないでください。
ファイル情報取得
import { promises as fs } from 'fs';

async function getStats(path) {
  try {
    const stats = await fs.stat(path); // シンボリックリンクの場合は fs.lstat
    console.log('ファイル情報:', stats);
    console.log('ファイルですか?:', stats.isFile());
    console.log('ディレクトリですか?:', stats.isDirectory());
    console.log('サイズ:', stats.size);
  } catch (err) {
    console.error('情報取得エラー:', err);
  }
}
ファイルやディレクトリのメタ情報 (サイズ、作成日時、最終アクセス日時など) を取得します。
ファイル削除
import { promises as fs } from 'fs';

async function deleteFile(filePath) {
  try {
    await fs.unlink(filePath);
    console.log('ファイル削除成功!');
  } catch (err) {
    console.error('削除エラー:', err);
  }
}
ファイルを非同期に削除します。
ディレクトリ作成
import { promises as fs } from 'fs';

async function createDirectory(dirPath) {
  try {
    // recursive: true で親ディレクトリもまとめて作成
    await fs.mkdir(dirPath, { recursive: true });
    console.log('ディレクトリ作成成功!');
  } catch (err) {
    console.error('作成エラー:', err);
  }
}
ディレクトリを非同期に作成します。recursive: true オプションが便利です。
ディレクトリ読み込み
import { promises as fs } from 'fs';

async function readDirectory(dirPath) {
  try {
    const files = await fs.readdir(dirPath);
    console.log('ディレクトリ内容:', files); // ファイル名とディレクトリ名の配列
  } catch (err) {
    console.error('読み込みエラー:', err);
  }
}
ディレクトリ内のファイル名とサブディレクトリ名のリストを非同期に取得します。
ディレクトリ削除
import { promises as fs } from 'fs';

async function removeDirectory(dirPath) {
  try {
    // recursive: true で中身ごと削除 (Node.js v14.14.0以降)
    // それ以前は中のファイル/ディレクトリを再帰的に削除する必要あり
    await fs.rm(dirPath, { recursive: true, force: true }); // force: true はエラーを無視
    // または await fs.rmdir(dirPath, { recursive: true }); (古いAPI, 非推奨)
    console.log('ディレクトリ削除成功!');
  } catch (err) {
    console.error('削除エラー:', err);
  }
}
ディレクトリを非同期に削除します。空でないディレクトリを削除するには recursive: true が必要です (fs.rm 推奨)。
名前の変更/移動
import { promises as fs } from 'fs';

async function renamePath(oldPath, newPath) {
  try {
    await fs.rename(oldPath, newPath);
    console.log('名前変更/移動 成功!');
  } catch (err) {
    console.error('エラー:', err);
  }
}
ファイルやディレクトリの名前を変更したり、別の場所に移動したりします。

パス操作 (path)

ファイルパスの操作には path モジュールを使います。OS間の互換性を保つのに役立ちます。

目的 コード例 説明
パスの結合
import path from 'path';
const fullPath = path.join('/users', 'joe', 'notes.txt');
// Windows: \users\joe\notes.txt
// Linux/macOS: /users/joe/notes.txt
複数のパスセグメントを結合して、プラットフォームに適したパス文字列を生成します。... も解釈されます。
絶対パスの解決
import path from 'path';
const absolutePath = path.resolve('myfile.txt');
// カレントディレクトリからの絶対パスを返す
// 例: /path/to/current/directory/myfile.txt
相対パスから絶対パスを解決します。引数なしだとカレントワーキングディレクトリを返します。
ディレクトリ名取得
import path from 'path';
const dir = path.dirname('/users/joe/notes.txt'); // '/users/joe'
パス文字列からディレクトリ部分を取得します。
ファイル名取得
import path from 'path';
const base = path.basename('/users/joe/notes.txt'); // 'notes.txt'
const baseWithoutExt = path.basename('/users/joe/notes.txt', '.txt'); // 'notes'
パス文字列からファイル名部分(拡張子含む)を取得します。第二引数で拡張子を指定すると、それを取り除いた名前を取得できます。
拡張子取得
import path from 'path';
const ext = path.extname('/users/joe/notes.txt'); // '.txt'
パス文字列から拡張子(ドット.を含む)を取得します。
パスの正規化
import path from 'path';
const normalized = path.normalize('/users/joe/.././notes.txt'); // '/users/notes.txt'
パス文字列を正規化します(余分な/...を解決)。
プラットフォーム固有の区切り文字
import path from 'path';
console.log(path.sep); // Windows: '\', Linux/macOS: '/'
現在のOSのパス区切り文字を取得します。

非同期処理 ⏳

Node.js の中心的な概念です。I/O操作などは基本的にノンブロッキング(非同期)で行われます。

コールバック関数

非同期操作が完了したときに呼び出される関数です。エラーファーストコールバック (Error-first Callback) が一般的です。

import fs from 'fs';

fs.readFile('example.txt', 'utf8', (err, data) => {
  if (err) {
    // エラー処理
    console.error('エラーが発生しました:', err);
    return;
  }
  // 成功時の処理
  console.log('ファイル内容:', data);
});

console.log('ファイル読み込み開始...'); // これは readFile より先に実行される
🤯 コールバックが多重にネストすると「コールバック地獄」と呼ばれる読みにくいコードになることがあります。

Promise

非同期操作の最終的な結果(成功または失敗)を表すオブジェクトです。.then() で成功時、.catch() で失敗時の処理をチェーンできます。

import { promises as fs } from 'fs';

fs.readFile('example.txt', 'utf8')
  .then(data => {
    console.log('ファイル内容:', data);
    // さらに非同期処理を繋げることも可能
    return fs.writeFile('copy.txt', data);
  })
  .then(() => {
    console.log('コピー完了!');
  })
  .catch(err => {
    console.error('エラーが発生しました:', err);
  });

console.log('ファイル操作開始...');

async/await

Promise をより同期的なコードのように書けるようにするシンタックスシュガーです。async 関数内で await を使って Promise の解決を待ちます。エラーハンドリングには try...catch を使います。

import { promises as fs } from 'fs';

async function processFiles() {
  console.log('ファイル操作開始...');
  try {
    const data = await fs.readFile('example.txt', 'utf8');
    console.log('ファイル内容:', data);

    await fs.writeFile('copy.txt', data);
    console.log('コピー完了!');

    const stats = await fs.stat('copy.txt');
    console.log('コピーファイルのサイズ:', stats.size);
  } catch (err) {
    console.error('エラーが発生しました:', err);
  } finally {
    console.log('ファイル操作終了。');
  }
}

processFiles(); // async関数を実行
👍 現代の Node.js 開発では、非同期処理には async/await を使うのが最も一般的で推奨されています。

Promise Combinators

メソッド コード例 説明
Promise.all()
const p1 = fs.readFile('file1.txt');
const p2 = fs.readFile('file2.txt');

try {
  const results = await Promise.all([p1, p2]);
  // results は [file1の内容, file2の内容] の配列
} catch (err) {
  // いずれか一つでも失敗したら catch へ
}
複数の Promise がすべて成功するのを待ちます。結果は配列で返されます。一つでも失敗すると全体が失敗(reject)します。並列実行したい場合に便利です。
Promise.allSettled()
const p1 = fs.readFile('file1.txt');
const p2 = fs.unlink('nonexistent.txt'); // これは失敗する

const results = await Promise.allSettled([p1, p2]);
// results は以下のような配列:
// [
//   { status: 'fulfilled', value:  },
//   { status: 'rejected', reason: Error(...) }
// ]
複数の Promise の結果(成功・失敗問わず)を待ちます。各 Promise の結果が { status: 'fulfilled', value: ... } または { status: 'rejected', reason: ... } の形式で配列に格納されます。
Promise.race()
const p1 = new Promise(resolve => setTimeout(resolve, 500, 'one'));
const p2 = new Promise(resolve => setTimeout(resolve, 100, 'two'));

try {
  const first = await Promise.race([p1, p2]);
  console.log(first); // 'two' (p2が先に解決するため)
} catch (err) {
  // 最初に失敗した Promise のエラー
}
複数の Promise のうち、最初に成功または失敗したものの結果を返します。
Promise.any()
const p1 = Promise.reject('エラー1');
const p2 = new Promise(resolve => setTimeout(resolve, 100, '成功2'));
const p3 = Promise.reject('エラー3');

try {
  const firstSuccess = await Promise.any([p1, p2, p3]);
  console.log(firstSuccess); // '成功2'
} catch (err) {
  // すべての Promise が失敗した場合 AggregateError
  console.error(err.errors); // ['エラー1', 'エラー3']
}
複数の Promise のうち、最初に成功したものの結果を返します。すべてが失敗した場合のみ、AggregateError で失敗します。

ストリーム (Streams) 💧

ストリーム は、大きなデータを扱う際や、データを少しずつ処理する際にメモリ効率良く扱うための仕組みです。ファイル操作、HTTPリクエスト/レスポンス、プロセス間通信などで使われます。

Readable Writable Duplex Transform

基本的なストリーム操作

目的 コード例 説明
Readable Stream からのデータ読み込み
import fs from 'fs';

const readableStream = fs.createReadStream('large-file.txt', 'utf8');

readableStream.on('data', (chunk) => {
  console.log('データ受信:', chunk.length, 'bytes');
  // ここで chunk を処理
});

readableStream.on('end', () => {
  console.log('読み込み完了🏁');
});

readableStream.on('error', (err) => {
  console.error('読み込みエラー:', err);
});
'data' イベントでデータの断片 (chunk) を受け取ります。'end' イベントで完了、'error' イベントでエラーをハンドリングします。
Writable Stream へのデータ書き込み
import fs from 'fs';

const writableStream = fs.createWriteStream('output.txt');

writableStream.write('最初のデータ\n');
writableStream.write('次のデータ\n');
writableStream.end('最後のデータ'); // end() で書き込みを終了

writableStream.on('finish', () => {
  console.log('書き込み完了🏁');
});

writableStream.on('error', (err) => {
  console.error('書き込みエラー:', err);
});
write() メソッドでデータを書き込みます。end() を呼び出すと、残りのデータを書き込んでストリームを終了します。完了は 'finish' イベントで検知します。
パイプ (pipe())
import fs from 'fs';
import zlib from 'zlib'; // 圧縮・解凍モジュール

const readable = fs.createReadStream('large-file.txt');
const writable = fs.createWriteStream('output.txt.gz');
const gzip = zlib.createGzip(); // Transform Stream

readable.pipe(gzip).pipe(writable);

// エラーハンドリングは各ストリームに設定推奨
readable.on('error', handleError);
gzip.on('error', handleError);
writable.on('error', handleError);

function handleError(err) {
  console.error('ストリームエラー:', err);
  // 必要ならストリームを破棄するなど
}
Readable Stream の出力を Writable Stream の入力に繋ぎます。データの流れを簡単に記述でき、背圧(バックプレッシャー)も自動で処理されます。複数のストリームを連結できます。非常に効率的です。
stream.pipeline()
import fs from 'fs';
import zlib from 'zlib';
import { pipeline } from 'stream/promises'; // Promise版を使う

async function processStream() {
  const readable = fs.createReadStream('large-file.txt');
  const writable = fs.createWriteStream('output.txt.gz');
  const gzip = zlib.createGzip();

  try {
    await pipeline(readable, gzip, writable);
    console.log('パイプライン完了🏁');
  } catch (err) {
    console.error('パイプラインエラー:', err);
  }
}
processStream();
pipe() と似ていますが、エラーハンドリングが改善されており、最後のコールバック(またはPromise)ですべてのストリームのエラーをまとめて扱えます。ストリームのクリーンアップも自動で行われます。pipe() よりも推奨されます。

HTTPサーバー/クライアント (http, https) 🌐

http および https モジュールで、HTTP通信を扱います。通常、Webフレームワーク (Express, Fastify など) を使うことが多いですが、基本的な動作を理解しておくことは重要です。

HTTPサーバーの作成

import http from 'http';

const server = http.createServer((req, res) => {
  // req: IncomingMessage (リクエスト情報)
  // res: ServerResponse (レスポンスを書き込む)

  console.log(`リクエスト受信: ${req.method} ${req.url}`);

  if (req.method === 'GET' && req.url === '/') {
    res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
    res.end('こんにちは、世界!🌍');
  } else if (req.method === 'GET' && req.url === '/json') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ message: 'これはJSONです' }));
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
    res.end('ページが見つかりません。');
  }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`サーバーがポート ${PORT} で起動しました: http://localhost:${PORT}`);
});

// エラーハンドリング
server.on('error', (err) => {
  console.error('サーバーエラー:', err);
});

createServer にリクエストハンドラ関数を渡します。listen でサーバーを指定ポートで起動します。

HTTPクライアント (リクエスト送信)

Node.js v18以降では、標準で fetch API が利用可能になり、より簡単にHTTPリクエストを送信できます。

fetch API (推奨)

async function fetchData() {
  const url = 'https://api.github.com/users/octocat';
  try {
    const response = await fetch(url, {
      method: 'GET', // 'POST', 'PUT', 'DELETE' など
      headers: {
        'User-Agent': 'Node.js-Fetch-Example',
        // 'Content-Type': 'application/json', // POST/PUT の場合
        // 'Authorization': 'Bearer YOUR_TOKEN' // 認証が必要な場合
      },
      // body: JSON.stringify({ key: 'value' }) // POST/PUT の場合
    });

    if (!response.ok) { // ステータスコードが 200-299 でない場合
      throw new Error(`HTTPエラー: ${response.status} ${response.statusText}`);
    }

    const data = await response.json(); // レスポンスボディをJSONとしてパース
    // const textData = await response.text(); // テキストとして取得
    // const bufferData = await response.arrayBuffer(); // ArrayBufferとして取得

    console.log('取得データ:', data);
  } catch (error) {
    console.error('リクエスト失敗:', error);
  }
}

fetchData();

従来の http.request / https.request

より低レベルな操作が必要な場合や古いNode.jsバージョンで利用します。

import https from 'https'; // HTTPSの場合

const options = {
  hostname: 'api.github.com',
  port: 443,
  path: '/users/octocat',
  method: 'GET',
  headers: {
    'User-Agent': 'Node.js-HTTPS-Example'
  }
};

const req = https.request(options, (res) => {
  console.log(`ステータスコード: ${res.statusCode}`);
  let data = '';

  res.on('data', (chunk) => {
    data += chunk;
  });

  res.on('end', () => {
    try {
      const jsonData = JSON.parse(data);
      console.log('取得データ:', jsonData);
    } catch (e) {
      console.error('JSONパースエラー:', e);
    }
  });
});

req.on('error', (error) => {
  console.error('リクエストエラー:', error);
});

// req.write(postData); // POST/PUT の場合、データを書き込む
req.end(); // リクエストを終了(送信実行)
💡 fetch API は Promise ベースで async/await との相性が良く、ブラウザ環境の `fetch` と似たインターフェースを持つため、学習コストが低く、コードも簡潔になります。可能な限り fetch の利用を検討しましょう。

イベント (Events) 🎉

Node.js の多くのオブジェクトは EventEmitter を継承しており、イベント駆動型のプログラミングが可能です。ストリーム、HTTPサーバー、プロセスなどがイベントを発行します。

EventEmitter の利用

import { EventEmitter } from 'events';

// EventEmitterを継承するか、インスタンスを作成
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// または const myEmitter = new EventEmitter();

// イベントリスナー登録 ('on' または 'addListener')
myEmitter.on('myEvent', (arg1, arg2) => {
  console.log('myEventが発生しました!🎉', arg1, arg2);
});

// 一度だけ実行されるリスナー ('once')
myEmitter.once('oneTimeEvent', () => {
  console.log('これは一度だけ実行されます。');
});

// イベントを発行 ('emit')
console.log('イベントを発行します...');
myEmitter.emit('myEvent', '引数A', 123);
myEmitter.emit('myEvent', '引数B', 456); // 再度発行可能
myEmitter.emit('oneTimeEvent');
myEmitter.emit('oneTimeEvent'); // これはもう実行されない

// リスナー削除 ('removeListener' または 'off')
const listenerFunc = () => console.log('このリスナーは削除されます');
myEmitter.on('tempEvent', listenerFunc);
myEmitter.emit('tempEvent');
myEmitter.off('tempEvent', listenerFunc);
myEmitter.emit('tempEvent'); // 実行されない

// エラーイベントの特別扱い
// 'error' イベントはリスナーが登録されていないと例外をスローしてプロセスが終了する
myEmitter.on('error', (err) => {
  console.error('エラーイベント発生:', err.message);
});
myEmitter.emit('error', new Error('何か問題が発生しました!'));

// すべてのリスナーを削除
// myEmitter.removeAllListeners('myEvent'); // 特定のイベント
// myEmitter.removeAllListeners(); // すべてのイベント
⚠️ 'error' イベントには必ずリスナーを登録するようにしましょう。予期せぬプロセス終了を防ぐことができます。

プロセス管理 (Process) ⚙️

Node.js の process オブジェクトは、現在実行中の Node.js プロセスに関する情報を提供し、制御するためのグローバルオブジェクトです。

プロパティ/メソッド コード例 説明
process.argv
// 実行: node app.js arg1 arg2=value
console.log(process.argv);
// 出力例:
// [
//   '/path/to/node',       // Node.js実行可能ファイルのパス
//   '/path/to/app.js',     // 実行スクリプトのパス
//   'arg1',                // 引数1
//   'arg2=value'           // 引数2
// ]
コマンドライン引数の配列を取得します。最初の2つはNode実行ファイルとスクリプトファイルパスです。
process.env
console.log('NODE_ENV:', process.env.NODE_ENV);
console.log('PATH:', process.env.PATH);
// 環境変数を設定して実行: MY_VAR=abc node app.js
console.log('MY_VAR:', process.env.MY_VAR); // 'abc'
環境変数を格納したオブジェクトです。NODE_ENV はよく ‘development’ や ‘production’ を設定するのに使われます。
process.cwd()
console.log('カレントワーキングディレクトリ:', process.cwd());
現在のワーキングディレクトリ(Node.jsプロセスが起動されたディレクトリ)のパスを返します。
process.exit([code])
if (someErrorCondition) {
  console.error('致命的なエラーが発生しました。終了します。');
  process.exit(1); // 0以外のコードは通常エラーを示す
}
console.log('正常終了します。');
process.exit(0); // 正常終了
プロセスを同期的に終了させます。終了コードを指定できます (デフォルトは0)。注意: 実行中の非同期処理は完了しない可能性があります。通常は自然に終了させるのが望ましいです。
process.pid
console.log('プロセスID:', process.pid);
現在のプロセスのIDを返します。
process.platform
console.log('実行プラットフォーム:', process.platform);
// 'darwin' (macOS), 'win32' (Windows), 'linux' など
実行中のオペレーティングシステムプラットフォームを示す文字列を返します。
process.uptime()
console.log('起動からの経過時間 (秒):', process.uptime());
Node.js プロセスが起動してからの経過時間を秒単位で返します。
process.memoryUsage()
console.log('メモリ使用状況:', process.memoryUsage());
// { rss: ..., heapTotal: ..., heapUsed: ..., external: ..., arrayBuffers: ... }
プロセスのメモリ使用状況をバイト単位で返します (rss: Resident Set Size、heapTotal/Used: V8ヒープ)。
process.on('uncaughtException')
process.on('uncaughtException', (err, origin) => {
  console.error(`キャッチされなかった例外: ${err}\n` +
                `発生源: ${origin}`);
  // ここでログ記録などを行い、プロセスを終了するのが一般的
  process.exit(1);
});
// throw new Error('テスト例外'); // これが発生すると上記リスナーが呼ばれる
try...catch でキャッチされなかった例外が発生したときにトリガーされるイベント。最後の手段であり、実行後にプロセスを終了することが強く推奨されます。
process.on('unhandledRejection')
process.on('unhandledRejection', (reason, promise) => {
  console.error('処理されなかったPromise Rejection:', reason);
  // 将来的には uncaughtException 同様、プロセス終了がデフォルトになる可能性あり
  // process.exit(1);
});
// Promise.reject('テストリジェクション'); // これが発生すると上記リスナーが呼ばれる
.catch() で処理されなかった Promise の rejection が発生したときにトリガーされるイベント。ログ記録などに使用します。

子プロセスの生成 (child_process)

外部コマンドや他のスクリプトを実行するために子プロセスを生成します。

メソッド 特徴 主な用途
exec() シェル経由でコマンド実行。出力をバッファリング。非同期。 簡単なコマンド実行、シェルの機能(パイプ、リダイレクトなど)を利用したい場合。出力が大きすぎると問題になる可能性あり。
execFile() 直接実行ファイルを実行(シェルを介さない)。出力をバッファリング。非同期。 特定の実行ファイルを直接実行したい場合。execより若干効率的で安全。出力サイズに注意。
spawn() 直接実行ファイルを実行。ストリームで入出力を扱う。非同期。 出力が大きい場合、リアルタイムでデータを処理したい場合、プロセスとの対話が必要な場合。最も柔軟で推奨される方法。
fork() 新しいNode.jsプロセスを生成 (spawnの特殊版)。IPCチャネルが組み込まれる。非同期。 CPU負荷の高いタスクを別プロセスに分離したい場合、プロセス間通信を行いたい場合。
execSync()
execFileSync()
spawnSync()
上記メソッドの同期版。完了するまでNode.jsのイベントループをブロックする。 簡単なスクリプトやビルドプロセスなど、ブロッキングが許容される場合。サーバーアプリケーションなどでは避けるべき。

spawn の例

import { spawn } from 'child_process';

const ls = spawn('ls', ['-lh', '/usr']); // ls -lh /usr を実行

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`); // 標準出力を受け取る
});

ls.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`); // 標準エラー出力を受け取る
});

ls.on('close', (code) => {
  console.log(`子プロセスが終了しました。終了コード: ${code}`);
});

ls.on('error', (err) => {
  console.error('子プロセスの起動に失敗しました:', err);
});

エラーハンドリング ✋

堅牢なアプリケーションのためには、適切なエラーハンドリングが不可欠です。

種類 ハンドリング方法 説明・注意点
同期エラー try...catch JSONのパースエラー (JSON.parse)、未定義プロパティへのアクセス試行など、同期的に発生するエラー。
try {
  const data = JSON.parse('{ invalid json');
} catch (e) {
  console.error('パースエラー:', e.message); // e は Error オブジェクト
}
非同期エラー (コールバック) エラーファーストコールバックの err 引数チェック Node.jsコアAPIの多くで使われるパターン。コールバック関数の最初の引数がエラーオブジェクト(エラーがなければ null or undefined)。
fs.readFile('...', (err, data) => {
  if (err) {
    // エラー処理
    return;
  }
  // 成功処理
});
非同期エラー (Promise) .catch() メソッド or try...catch (async/await内) Promiseチェーンの最後や、async関数内でawaitを使った箇所でエラーを捕捉。
// .catch()
somePromiseFunc()
  .then(...)
  .catch(err => { /* エラー処理 */ });

// async/await
async function myAsyncFunc() {
  try {
    await anotherPromiseFunc();
  } catch (err) {
    /* エラー処理 */
  }
}
非同期エラー (EventEmitter) 'error' イベントリスナー ストリーム、サーバーなどで発生するエラー。'error' イベントをリッスンしないと、uncaughtException になる場合がある。
const stream = fs.createReadStream(...);
stream.on('error', (err) => {
  console.error('ストリームエラー:', err);
});
未捕捉の例外 process.on('uncaughtException') どこでもキャッチされなかった同期・非同期エラー。最後の砦。 ログ記録後、プロセスを終了するのがベストプラクティス。アプリケーションを安全な状態に保てない可能性があるため、続行は非推奨。
未処理のPromise Rejection process.on('unhandledRejection') .catch() がない、または awaittry...catch がない Promise の reject。ログ記録推奨。将来的には uncaughtException 同様にプロセス終了がデフォルトになる可能性あり。

エラーオブジェクト

エラーハンドリング時には、エラーオブジェクトのプロパティを確認すると役立ちます。

  • error.message: エラーメッセージ文字列。
  • error.stack: エラースタックトレース。どこでエラーが発生したか追跡するのに役立つ。
  • error.code: (Node.jsのエラーなどで) 特定のエラーを示すコード文字列 (例: 'ENOENT' – ファイルが存在しない)。err.code をチェックすることで、特定のエラー状況に対応しやすくなる。
  • カスタムエラープロパティ: 自分で定義したエラークラスに独自のプロパティを追加することも可能。
class AppError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
    this.isOperational = true; // プログラミングエラーでない、運用上のエラーを示すフラグなど
    Error.captureStackTrace(this, this.constructor);
  }
}

try {
  throw new AppError('リソースが見つかりません', 404);
} catch (err) {
  console.error(`エラー: ${err.message}, ステータス: ${err.statusCode}`);
  if (err.isOperational) {
    // 運用エラーに対する処理
  } else {
    // プログラミングエラーに対する処理 (より深刻な場合が多い)
  }
  console.log(err.stack);
}

パッケージ管理 (npm / yarn) 📦

Node.js プロジェクトの依存関係(外部ライブラリ)を管理するためのツールです。npm は Node.js に同梱されています。yarn は代替ツールとして人気があります。

目的 npm コマンド yarn コマンド 説明
プロジェクト初期化 npm init [-y] yarn init [-y] package.json ファイルを作成します。-y オプションですべての質問にデフォルトで回答します。
依存パッケージのインストール npm install [pkg]
npm i [pkg]
yarn add [pkg] パッケージをインストールし、dependencies に追加します。[pkg]を省略すると package.json の依存関係をすべてインストールします。
開発時依存パッケージのインストール npm install [pkg] --save-dev
npm i [pkg] -D
yarn add [pkg] --dev
yarn add [pkg] -D
テストフレームワークやビルドツールなど、開発時にのみ必要なパッケージをインストールし、devDependencies に追加します。
グローバルインストール npm install [pkg] --global
npm i [pkg] -g
yarn global add [pkg] コマンドラインツールなどをシステム全体で利用可能にするためにインストールします。
パッケージのアンインストール npm uninstall [pkg]
npm un [pkg]
yarn remove [pkg] パッケージをアンインストールし、package.json から削除します。
パッケージのアップデート npm update [pkg] yarn upgrade [pkg] package.json のバージョン指定範囲内でパッケージを更新します。[pkg] を省略するとすべて更新します。
依存関係の確認 (旧バージョン/更新可能) npm outdated yarn outdated 現在のバージョン、package.json で要求されているバージョン、最新バージョンを表示します。
スクリプトの実行 npm run [script-name] yarn [script-name] package.json"scripts" セクションに定義されたコマンドを実行します。start, test など一部は run を省略可能です (npm)。
キャッシュクリア npm cache clean --force yarn cache clean ダウンロードされたパッケージのローカルキャッシュを削除します。問題発生時に試すことがあります。
パッケージ公開 (npmレジストリへ) npm publish yarn publish 自作のパッケージをnpmレジストリに公開します (npmアカウントとログインが必要です)。
インストール (ロックファイル基準) npm ci yarn install --frozen-lockfile package-lock.json または yarn.lock に基づいて依存関係をクリーンインストールします。CI/CD環境での再現性を高めるのに役立ちます。node_modules を削除してからインストールします。
package.json: プロジェクト名、バージョン、依存関係、スクリプトなどを記述する設定ファイル。
package-lock.json (npm) / yarn.lock (yarn): インストールされた各パッケージの正確なバージョンと依存関係ツリーを記録するロックファイル。これにより、異なる環境でも同じ依存関係を再現できます。バージョン管理に含めるべきです。

デバッグ 🐞

Node.js アプリケーションのデバッグにはいくつかの方法があります。

方法 コマンド/設定 説明
console デバッグ console.log()
console.error()
console.warn()
console.trace()
console.time() / console.timeEnd()
最もシンプル。コードの途中にログ出力ステートメントを挿入して、変数の値や処理の通過点を確認します。traceでスタックトレース、time/timeEndで時間計測ができます。
Node.js Inspector (内蔵デバッガ) node inspect [ファイル名].js
または
node --inspect [ファイル名].js
node --inspect-brk [ファイル名].js
Node.js に組み込まれているデバッグプロトコル (V8 Inspector) を利用します。
inspect: REPL風のコマンドラインデバッガを起動します。
--inspect: デバッグプロトコルを有効にし、実行を続けます。Chrome DevTools や VS Code などのデバッグクライアントから接続できます。
--inspect-brk: デバッグプロトコルを有効にし、スクリプトの最初の行で実行を一時停止します。クライアントからの接続を待機します。
Chrome DevTools でデバッグ 1. node --inspect-brk app.js などで起動。
2. Chrome ブラウザで chrome://inspect を開く。
3. “Remote Target” に表示される Node.js プロセスを選択。
使い慣れた Chrome DevTools のインターフェース (ブレークポイント、ステップ実行、変数監視、コンソール、プロファイリングなど) を使って Node.js アプリケーションをデバッグできます。非常に強力です。
VS Code デバッガ 1. VS Code でプロジェクトを開く。
2. “実行とデバッグ” (Run and Debug) サイドバーを開く。
3. launch.json 設定ファイルを作成 (Node.js 用のデフォルト設定あり)。
4. デバッグを開始 (F5)。
VS Code に統合された高機能なデバッガを利用できます。ブレークポイントの設定、ステップ実行、変数監視、コールスタック表示、デバッグコンソールなどがエディタ内で完結します。launch.json で起動設定を細かくカスタマイズ可能です (--inspect 相当の機能が内部で使われます)。
debugger ステートメント コード内に debugger; と記述。 コード内にこのステートメントがあると、デバッガ (Chrome DevTools や VS Code デバッガなど) が接続されている場合に、その箇所で実行が一時停止します。プログラム的にブレークポイントを設定するようなものです。
👍 Chrome DevToolsVS Code デバッガ を利用するのが、効率的で高機能なデバッグを行うための現代的な方法として強く推奨されます。console.log は手軽ですが、複雑な問題にはデバッガが適しています。

コメント

タイトルとURLをコピーしました