Node.js
Chrome V8 エンジン上で動作するサーバーサイド JavaScript ランタイム
JavaScriptランタイム
Node.js とは
Node.js は、Chrome の V8 JavaScript エンジンをベースにしたサーバーサイドランタイムである。2009 年に Ryan Dahl が開発し、ノンブロッキング I/O とイベントループによる高い並行処理性能が特徴。AWS Lambda のデフォルトランタイムの 1 つでもある。
シングルスレッド + イベントループ
Node.js はシングルスレッドだが、イベントループとノンブロッキング I/O で大量の同時接続を処理する。
リクエスト → イベントループ → I/O 操作 (非同期) → コールバック → レスポンス
↑ |
└────────────────────────────────────┘
CPU バウンドな処理 (画像変換、暗号計算) はイベントループをブロックするため、Worker Threads や外部サービスに委譲する。
Node.js vs Deno vs Bun
| 観点 | Node.js | Deno | Bun |
|---|---|---|---|
| エンジン | V8 | V8 | JavaScriptCore |
| パッケージ | npm | URL import / npm | npm |
| TypeScript | トランスパイル必要 | ネイティブ対応 | ネイティブ対応 |
| セキュリティ | 制限なし | パーミッション制御 | 制限なし |
| エコシステム | 最大 | 成長中 | 成長中 |
Node.js の最大の強みはエコシステムの規模。npm には 200 万以上のパッケージがあり、ほぼあらゆるユースケースにライブラリが存在する。
Lambda での Node.js
Lambda は Node.js ランタイムを公式サポートしており、コールドスタートが軽量 (Python と並んで最速クラス)。
| 観点 | Node.js | Python | Java |
|---|---|---|---|
| コールドスタート | 100〜300ms | 100〜300ms | 1〜5s |
| 実行速度 | 高速 | 中程度 | 高速 |
| メモリ効率 | 良好 | 良好 | 大きい |
CommonJS vs ES Modules
// CommonJS (従来)
const fs = require('fs');
module.exports = { handler };
// ES Modules (推奨)
import { readFile } from 'fs/promises';
export const handler = async (event) => { /* ... */ };
Lambda は ES Modules をサポートしており、package.json に "type": "module" を指定するか、ファイル拡張子を .mjs にする。
よくある落とし穴
- イベントループのブロック:
JSON.parseで巨大な JSON を処理すると他のリクエストが待たされる - メモリリーク: クロージャやグローバル変数にデータを蓄積し続けると Lambda の実行環境が肥大化する
- コールバック地獄:
async/awaitを使わずにコールバックをネストすると可読性が崩壊する node_modulesの肥大化: Lambda のデプロイパッケージが 250MB 制限に達する。Lambda Layer や Tree Shaking で対策する
関連書籍も参考になる。