by MintJams

Node.js 22 LTSの最新APIを「既存アプリにちょい足し」する実践ガイド:ビルトインnode:sqliteとWeb標準で始めるモダン化

Node.js 22 LTSのビルトインSQLiteとFetch APIを既存アプリに導入する実践ガイド。外部依存を減らし、モダンな開発に移行する手順を解説します。

Node.js 22 LTSがリリースされ、待望の機能が続々と標準化されました。特に注目すべきは、ビルトインのnode:sqliteモジュールと、Fetch APIをはじめとするWeb標準APIの進化です。これまでのNode.js開発では、外部モジュールに頼るしかなかった機能が、コアでサポートされるようになりました。しかし、新規プロジェクトでこれらを使うのは簡単でも、既に稼働中の大規模なアプリケーションにどうやって「小さく」導入していくか、その実践的な手順に悩む方も多いのではないでしょうか。

この記事では、既存のNode.jsアプリケーションに、最新のNode.js 22の機能を少しずつ取り入れていくための具体的なアプローチを解説します。外部ライブラリを安易に導入せず、Node.jsの進化の恩恵を安全に享受する方法を学びましょう。


この記事でわかること

  • Node.js 22で標準化されたnode:sqliteモジュールの同期APIの使い方
  • 既存アプリにnode:sqliteモジュールを「ちょい足し」する具体的な手順
  • Node.js 22で進化したWeb標準API(Fetch APIなど)の活用方法
  • node:sqliteを試す上での注意点(フラグ、ランタイム環境)

Node.js 22、ビルトインnode:sqliteで外部モジュールから脱却する

Node.js v22.5.0以降で追加されたnode:sqliteモジュールは、同期APIを提供します。これにより、外部ライブラリに依存せず軽量なデータ永続化が可能になります。従来のnpmパッケージsqlite3と異なり、ネイティブビルドが不要なため、環境構築がシンプルになる利点があります。

注意点:同期APIとnpmパッケージとの混同

node:sqliteはPromiseベースではなく、同期(synchronous)で動作します。イベントループをブロックするため、重い処理には向いていませんが、シンプルなスクリプトや起動時のデータロードには適しています。APIの互換性がないため、npmのsqlite3パッケージを使用している場合は、npm uninstall sqlite3でパッケージを削除し、コードをnode:sqliteのAPIに合わせて修正する必要があります。

サンプルコード:同期APIでSQLiteを試す

まずは、ファイルに書き出さずメモリ上で動作するSQLiteデータベースを作成し、簡単な操作を試してみましょう。既存のアプリケーションの特定の機能だけ、一時的なキャッシュやセッション情報の保存にSQLiteを使いたい場合に便利です。

// db-example.js
import { DatabaseSync } from 'node:sqlite';

const db = new DatabaseSync(':memory:'); // 同期的にメモリ上のデータベースを開く

// 補足:オンディスクDBにしたい場合は、`'./sample.db'`のようにパスを指定します。
// const db = new DatabaseSync('./sample.db');

try {
  // テーブル作成 (execは同期実行)
  // STRICTを指定することで、型厳格なテーブルを作成できます。
  db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT) STRICT');
  console.log('Table "users" created.');

  // データの挿入 (prepareとrunは同期実行)
  const insertStmt = db.prepare('INSERT INTO users (name) VALUES (?)');
  insertStmt.run('Alice');
  console.log('Inserted Alice.');
  insertStmt.run('Bob');
  console.log('Inserted Bob.');
  
  // 全件取得 (allは同期実行)
  const rows = db.prepare('SELECT id, name FROM users').all();
  for (const row of rows) {
    console.log(`User ID: ${row.id}, Name: ${row.name}`);
  }
} catch (e) {
  console.error('An error occurred:', e);
} finally {
  db.close(); // 同期的にデータベース接続を閉じる
  console.log('Database connection closed.');
}

実行コマンド:

node --experimental-sqlite db-example.js

出力例:

Table "users" created.
Inserted Alice.
Inserted Bob.
User ID: 1, Name: Alice
User ID: 2, Name: Bob
Database connection closed.

ワンポイント --experimental-sqliteフラグは、2025年現在も実験段階であり必須です。今後のNode.jsバージョンアップにより、このフラグが不要になる可能性があります。


Web標準API、既存コードにFetch APIを挿入する

Node.js 22では、fetchResponseRequestといったWeb標準APIが安定版として利用できます。これは、HTTPリクエストを扱うためにnode-fetchのような外部ライブラリを使っていた既存コードを、標準機能に置き換える大きなチャンスです。特にマイクロサービス間の通信や、外部APIとの連携部分を修正する際に、依存ライブラリを一つ減らすことができます。

サンプルコード:GET以外のメソッド(POST)を試す

fetchはGETリクエストだけでなく、POSTやPUTなどあらゆるHTTPメソッドに対応しています。ここでは、JSONデータをPOSTする例を示します。

async function postData(url, data) {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  });
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  return await response.json();
}

const newData = { title: 'foo', body: 'bar', userId: 1 };
postData('https://jsonplaceholder.typicode.com/posts', newData)
  .then(data => console.log('Posted data:', data))
  .catch(err => console.error(err));

トラブル時のチェックポイント

  • --experimental-* フラグを忘れていませんか? node:sqliteモジュールは、現時点では--experimental-sqliteフラグが必要です。このフラグを忘れると、Error: No such built-in module: node:sqliteといったエラーが発生します。
  • node:sqliteとnpmパッケージsqlite3を混同していませんか? node:sqliteはビルトインモジュールであり、import { DatabaseSync } from 'node:sqlite'のようにnode:プレフィックス付きで呼び出す必要があります。npmパッケージsqlite3とはAPIが異なるため、両方を同時に使用することはできません。
  • Node.jsのfetchでCORSエラーは発生しません ブラウザのfetchとは異なり、サーバー側のNode.jsでfetchを使用する場合、CORS(Cross-Origin Resource Sharing)によるリクエストのブロックは基本的に発生しません。これは、Node.jsがサーバー用途であるため、ブラウザのようなセキュリティ制約を持たないためです。ただし、API提供側がCORSポリシーを厳格に設定している場合、リクエストの挙動が異なる可能性もあるため、挙動の確認は必要です。

チェックリスト

  • Node.jsのバージョンが22 LTS以降であることを確認したか
  • node:sqliteモジュールを使用する場合、node --experimental-sqliteで実行したか
  • コードがESMで記述されており、.mjs拡張子を使用するか、package.json"type": "module"が適切に設定されているか
  • node:sqliteが同期APIであることを理解し、適切なAPI(DatabaseSync)を使用しているか
  • Fetch APIのエラーハンドリング(response.okのチェック)を適切に実装したか

まとめ

Node.js 22 LTSの標準機能は、外部依存を減らし、開発をよりシンプルでモダンなものにしてくれます。この記事で紹介したnode:sqliteとWeb標準APIへの移行は、一見手間がかかるように思えるかもしれません。しかし、これによりアプリケーションの保守性が向上し、将来のNode.jsのアップグレードにも強くなります。

node:sqliteはNode.jsコアの実験的モジュールであり、Node.jsランタイム外(Cloudflare WorkersやVercel Edge Runtimeなど)では利用できません。これらの環境では、別のデータストアや専用のSDKを利用する必要があります。今から段階的にこれらの最新APIをNode.js環境に取り入れることで、あなたのプロジェクトはより長く、安全に運用できるようになるでしょう。

この記事が、あなたのNode.jsアプリケーションのモダン化を進める一助となれば幸いです。ご覧いただきありがとうございました。


参考資料