Back

npm パッケージを置き換える5つの Node.js 組み込み API

npm パッケージを置き換える5つの Node.js 組み込み API

基本的な HTTP リクエスト、ファイル操作、テストのために npm パッケージをインストールしているなら、Node.js プロジェクトに不要な依存関係を追加していることになります。モダンな Node.js(v20 以降)には、多くの人気パッケージを不要にする強力な組み込み API が含まれており、バンドルサイズの削減、セキュリティの向上、メンテナンスの簡素化を実現できます。

現在おそらく使用している npm パッケージを置き換えることができる、5つの重要な Node.js 組み込み API を、実際の移行方法を示す実用的な例とともに見ていきましょう。

重要なポイント

  • ネイティブ fetch API は Node.js 18 以降、外部依存なしでほとんどの HTTP リクエストを処理可能
  • 組み込みテストランナーは、シンプルなアプリケーション向けにゼロ依存のテストソリューションを提供
  • モダンな fs メソッドは、再帰的な操作とパターンマッチングをネイティブにサポート
  • crypto.randomUUID() は追加パッケージなしで安全な UUID を生成
  • WebSocket クライアントサポートがネイティブで利用可能(Node.js 21 以降で実験的機能)

1. グローバル fetch() が axios と node-fetch を置き換える

Node.js 18 から安定版となったネイティブ fetch API は、外部依存なしでほとんどの HTTP リクエストを処理できます。axios のようなパッケージはインターセプターや自動リトライなどの便利な機能を提供しますが、fetch() は大半のユースケースをカバーします。

変更前(axios を使用):

const axios = require('axios');
const response = await axios.get('https://api.github.com/users/nodejs');
console.log(response.data);

変更後(ネイティブ fetch):

const response = await fetch('https://api.github.com/users/nodejs');
const data = await response.json();
console.log(data);

タイムアウトには AbortController を使用します:

const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
const response = await fetch(url, { signal: controller.signal });

axios を残すべき場合: 複雑なインターセプターチェーン、進捗トラッキング、自動リクエストリトライが必要な場合。

2. node:test ランナーが Jest と Mocha を置き換える

組み込みテストランナー(Node.js 20 以降で安定版として推奨)は、ライブラリやシンプルなアプリケーションに最適なゼロ依存のテストソリューションを提供します。

変更前(Jest を使用):

// jest のインストールと設定が必要
describe('Math operations', () => {
  test('adds numbers', () => {
    expect(2 + 2).toBe(4);
  });
});

変更後(ネイティブ node:test):

import { test } from 'node:test';
import assert from 'node:assert';

test('adds numbers', () => {
  assert.strictEqual(2 + 2, 4);
});

テストの実行: node --test または自動再実行には node --test --watch

Jest を残すべき場合: スナップショットテスト、充実したモック機能、コードカバレッジレポートが必要な場合。

3. ファイルシステムヘルパーが rimraf、mkdirp、glob を置き換える

モダンな fs メソッドは、再帰的な操作とパターンマッチングをネイティブに処理します。

変更前(複数のパッケージ):

const rimraf = require('rimraf');
const mkdirp = require('mkdirp');
const glob = require('glob');

await rimraf('dist');
await mkdirp('dist/assets');
const files = await glob('src/**/*.js');

変更後(ネイティブ fs):

import { rm, mkdir } from 'node:fs/promises';
import { glob } from 'node:fs';

await rm('dist', { recursive: true, force: true });
await mkdir('dist/assets', { recursive: true });

// 注意: glob() は Node.js 22 以降が必要
for await (const file of glob('src/**/*.js')) {
  console.log(file);
}

これらのネイティブ Node.js 機能により、同一の機能を持つ3つの依存関係を削減できます。

4. crypto.randomUUID() が uuid パッケージを置き換える

uuid パッケージ(週間 1 億 6100 万ダウンロード)なしで、暗号学的に安全な UUID を生成できます。

変更前:

const { v4: uuidv4 } = require('uuid');
const id = uuidv4();

変更後:

import { randomUUID } from 'node:crypto';
const id = randomUUID();

この組み込み API は、uuid パッケージと同じセキュリティ保証を持つ RFC-4122 バージョン 4 の UUID を生成します。

uuid を残すべき場合: v4 以外の UUID バージョン(v1、v3、v5)を生成する必要がある場合。

5. WebSocket クライアントが ws パッケージを置き換える

Node.js にはグローバル WebSocket クライアントが含まれています(Node.js 22 以降で安定版)。クライアント用途には適していますが、サーバーサイドの WebSocket サポートには依然として ws のようなパッケージが必要です。

変更前(ws を使用):

const WebSocket = require('ws');
const ws = new WebSocket('wss://echo.websocket.org');
ws.on('open', () => ws.send('Hello'));

変更後(ネイティブ WebSocket):

const ws = new WebSocket('wss://echo.websocket.org');
ws.onopen = () => ws.send('Hello');
ws.onmessage = (event) => console.log(event.data);

ws を残すべき場合: サーバーサイドの WebSocket 実装、または API が安定するまでの本番環境での使用。

移行の実践: 実用的な考慮事項

npm パッケージをネイティブ API に置き換える前に、以下を考慮してください:

  • Node.js バージョン要件: 本番環境が Node.js 20 以降(理想的には 22 LTS)で動作していることを確認
  • 機能の同等性: ネイティブ API には高度な機能(axios のインターセプター、Jest のスナップショット)が欠けている場合がある
  • チームの習熟度: 異なる API の学習曲線を考慮

まずは randomUUID() やファイルシステム操作のようなシンプルなユーティリティの置き換えから始めましょう。これらは最小限のリスクで即座にメリットをもたらします。テストフレームワークや HTTP クライアントのようなより複雑な置き換えについては、ネイティブ機能が特定の要件を満たすかどうかを評価してください。

まとめ

これら5つの Node.js 組み込み API は、プラットフォームが外部パッケージへの依存を減らすためにどのように進化してきたかを示しています。ネイティブ fetch、node:test、モダンな fs メソッド、crypto ユーティリティ、WebSocket サポートを活用することで、機能を維持または向上させながら、プロジェクトの依存関係を大幅に削減できます。

重要なのは、ネイティブ API で十分な場合と、特化した npm パッケージが依然として価値を提供する場合を知ることです。小さく始め、徹底的にテストし、ユースケースに適した場合に徐々にネイティブソリューションに移行してください。

よくある質問

ほとんどの機能は Node.js 18 以降が必要です。fetch API は v18 以降、node:test は v20 以降、glob は v22 以降が必要です。npm パッケージから移行する前に、本番環境の Node.js バージョンを確認してください。

慎重に移行すれば壊れません。ネイティブ API は npm パッケージとは異なる構文を持っています。開発環境で徹底的にテストし、新しい API パターンに合わせてコードを更新し、ネイティブ API がサポートしない高度な機能についてはパッケージを残すことを検討してください。

ネイティブ API は C++ 実装と抽象化オーバーヘッドがないため、多くの場合より優れたパフォーマンスを発揮します。ただし、特化したパッケージは特定のユースケースをより最適化している場合があります。パフォーマンスが重要なコードについては、実際のワークロードをベンチマークして情報に基づいた決定を行ってください。

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay