- 最近のNode.jsは、従来はnpmパッケージでしか実現できなかった機能をランタイムに内蔵しながら急速に進化している
- これにより、サプライチェーンのセキュリティリスク低減、コード移植性の向上、依存関係の縮小、保守の簡素化が可能になり、本番環境での性能と安定性の確保に寄与している
fetch(), WebSocket, node:test などのグローバルAPIが追加され、node-fetch, ws, mocha のような有名パッケージがなくても開発できる
- ファイルシステム機能の拡張により、
glob, rimraf, mkdirp を置き換える fs.glob(), fs.rm(), fs.mkdir() オプションが提供される
- ユーティリティおよび暗号化APIでは
crypto.randomUUID(), util.styleText(), atob/btoa などが標準で含まれ、uuid, chalk のようなパッケージが不要になっている
- 一部の機能(
node:sqlite, URLPattern, --env-file, TypeScript実行など)はまだ実験段階にとどまっている
- Node.js自体の進化によって、基本ランタイムだけでもモダンなアプリケーション開発が可能になっている点が重要である
Node.jsの組み込み機能で置き換えられた主要なnpmパッケージ
- Node.jsはこれまで、HTTPユーティリティやファイルシステムヘルパーなど、さまざまなnpmパッケージに依存してきた
- しかし最近のバージョン(v18〜v22)では、こうした機能を徐々にランタイムへ直接統合する流れが強まっている
- その結果、パッケージ管理の複雑さとセキュリティ露出リスクを減らせる効果がある
1. node-fetch → Global fetch()
- Node.js 18からブラウザと同じ
fetch() がグローバル関数として提供される
node-fetch なしでもHTTPリクエストを処理できる
- v17.5.0で実験的に導入され、v18.0.0で安定化した
- ただし、18以前のバージョンでは依然として
node-fetch が必要
2. ws → Global WebSocket
- Node.js 21からグローバル
WebSocket クラスによりクライアント側WebSocket接続をサポート
- サーバー側WebSocket実装には依然として
ws パッケージや関連ライブラリの利用が必要
3. テストフレームワーク → node:test
- Node.js 18から、
mocha, jest などを置き換える組み込みテストランナー node:test が提供される
- v18.0.0で実験的に導入され、v20.0.0で安定化
- 基本的なユニットテストの作成と実行をサポート
- スナップショット、モック、豊富なプラグインなどが必要な場合は、サードパーティ製フレームワークが依然として有用
- モジュールレベルのテストには十分だが、フルスタックアプリケーション開発では既存フレームワークの利点がある
4. sqlite3 / better-sqlite3 → node:sqlite
- Node.jsではSQLiteアクセス向けの実験的な
node:sqlite モジュールの導入が進んでいる
- 既存のネイティブバインディングパッケージで発生しがちなコンパイル問題やアップグレード時のエラーを解消
- インメモリデータベースの作成、テーブル作成などの基本操作をサポート
- まだ実験段階のため、高度な性能チューニングや追加機能が必要ならコミュニティ製パッケージの利用が推奨される
5. chalk / kleur → util.styleText()
- Node.js 20.12.0から**
util.styleText() でコンソールテキストのスタイリング**が可能
- v22.17.0で安定化
- 色、太字、下線など基本的なテキストスタイルを適用可能
- 複雑なテーマ、チェーン構文、下位互換性が必要なら
chalk などを引き続き利用できる
6. strip-ansi → util.stripVTControlCharacters()
- ANSIエスケープコード除去機能をNode.js組み込み関数として提供
- ほとんどのユースケースをネイティブでカバーでき、サードパーティ製パッケージは不要
7. glob → fs.glob()
- Node.js 22からファイルパターン検索のための組み込み
fs.glob() 機能が追加
- v22.0.0で追加され、v22.17.0 LTSで安定化
**/*.js のようなglobパターンでファイル検索が可能
- 旧バージョンのNode.jsとの互換性が必要な場合は
glob パッケージを使う
8. rimraf → fs.rm({ recursive: true })
- ディレクトリの再帰削除をNode.jsネイティブAPIでサポート
fs.rm() の recursive, force オプションで実装
- v12.10.0ごろから利用可能で、現在はすべてのLTSバージョンで安定化している
rimraf パッケージなしでも安全にディレクトリを削除できる
9. mkdirp → fs.mkdir({ recursive: true })
- ディレクトリの再帰作成を
fs.mkdir() の recursive オプションで提供
- v10.12.0から追加され、長期間にわたり安定している
- 別途パッケージなしでネストしたディレクトリを作成可能
10. uuid → crypto.randomUUID()
- Node.js 14.17.0からUUID生成関数
crypto.randomUUID() を提供
uuid パッケージなしで安全なランダムIDを生成できる
11. base64-js / atob → atob, btoa
- Node.js 20から**
atob, btoa グローバル関数**を提供
- ブラウザと同じBase64エンコード/デコードAPI
- 既存の
Buffer に加えて別の選択肢を提供
- ポリフィルなしでBase64処理が可能
12. url-pattern → URLPattern
- Node.js 20からグローバル
URLPattern API を実験的に提供
- ルートマッチング、パスパラメータ抽出などをサポート
- まだ実験段階で安定化が必要
- URLパターンマッチングを標準Web APIとして処理できる
13. dotenv → --env-file フラグ
- Node.js 20.10.0から**
--env-file フラグで環境変数の読み込み**をサポート
- 実行時に
.env ファイルを直接ロード
- まだ実験段階
- 変数展開、複数のenvファイルなど高度な機能には
dotenv パッケージが必要
14. event-target-shim → EventTarget
- Node.js 15.0.0からWeb標準の
EventTarget イベントシステムをグローバルに提供
- v15.4.0で安定化
- ブラウザと同じイベント処理モデルをサポート
EventEmitter の代替として利用可能
15. tsc → Node.js TypeScript実行
- Node.js 21から**
--experimental-strip-types フラグで .ts ファイルを直接実行**可能
- 型の除去のみを行い、完全な型チェックは未対応
- まだ実験段階
- 本番ビルド、静的型検査、宣言ファイル生成、完全な型チェックには依然として
tsc が必要
結論
- Node.jsの進化の方向性は、外部パッケージへの依存を減らし、プラットフォーム自体の完成度を高めることにある
- 最新LTSバージョン(v22)では、すでに多くのnpmパッケージが不要になっており、
これはセキュリティ・性能・保守性の面で大きな改善を意味する
- 企業向け運用環境では、こうした変化をリアルタイムで監視するために**N|Solid** のようなソリューションが活用されている
- 組み込み機能(
fetch, node:test, crypto.randomUUID() など)の実ワークロードにおける性能分析
- N|Sentinel AIエージェントが使用状況の監視とコードレベルの最適化提案を提供
6件のコメント
ランタイムが提供するAPIはますます増えている..
特にそれがネットワークAPI、URL、b64などの文字列処理APIなどだ...
これ完全に... PH..
Uuid v7 はまだ時期尚早のようですね
DBドライバーは、ほかの標準ライブラリに入るべき機能とは別の観点で見るべきだと思うのですが、Bunもそうですし、SQLiteドライバーをランタイムに組み込もうとする理由は何なのでしょうか?
Pythonが標準搭載しているからでしょうか?
SQLiteの機能を組み込むより、DBドライバーのインターフェース標準を作るほうが重要だと思います。
ドライバーごとにインターフェースが違うので、多種多様なDBをサポートしようとすると、ORMを使わない限り難しいのが問題ではありませんか
個人ブログ程度の小規模サービスなら、sqliteで十分なことが多いから入れたのではないかと思います。あると便利ですよね。
私の考えでは、sqlite はインターフェースが最もシンプルで、参考にしやすい良いリファレンスになると思ったので入れたのだと思います。
そして、おっしゃっていた DB Driver インターフェース標準を、なぜ作ってあげる必要があるのかはよく分かりません。似たようなものは PHP で見たことがある気もします。
ORM で処理できない複雑なクエリはいまだに RAW クエリを使っているので……
多機種の DB を使うことが多いようですね…… ライブラリを作ってみるのはいかがですか? :)
Python、Java、C#、Go などでは、ランタイムが DB ドライバのインターフェース標準を用意してくれるケースはかなり一般的です。
しかし Node では、同じ SQLite 向けドライバ同士でさえ statement の実行が
execute()だったりexec()だったりして、ドライバを差し替えるだけでもある程度の修正が必要になります。頻繁にあることではないですが、DB を変更する場合も不便です。
MySQL を使っていたけれど Oracle のやり方が気に入らないとか、あるいは PostgreSQL の拡張の中にどうしても必要なものがあるとかで PostgreSQL に移行すると仮定した場合、
JDBC のような標準インターフェースがあるなら SQL だけ検証すればよいのに、Node の界隈では DB 呼び出しロジックを全部作り直さなければならない副作用があります。
+ライブラリを作ってみたらどうかと勧めていただきましたが、共通インターフェースの標準があるほうがライブラリを作るときも楽なんですよね。
会社では Java を使っていますが、社内独自フレームワークで MySQL、DB2、Oracle、MSSQL をサポートしなければならず、DB ごとのアダプタを保守するときに JDBC 標準の恩恵をかなり受けました。