JavaScriptはプログラミング言語で、Node.jsはランタイム、つまりブラウザの外でJavaScriptを動かすプログラムです。構文、型、標準オブジェクト(Array、Promise、JSON)はどちらでも同じです。変わるのはコードのまわりの環境です。ブラウザはWebページを扱うための window と document をくれますが、Node.jsはファイル、サーバー、OSを扱うための global、process、require、そして fs などのモジュールをくれます。
ブラウザのグローバルは undefined、Node.jsのものは object か function と表示され、最後の行は true でした。Node.jsでは globalThis と global が同じオブジェクトだからです。最初の6行をブラウザのコンソールに貼り付けると、結果が逆になります。
違いを1つの表で
| ブラウザのJavaScript | Node.jsのJavaScript | |
|---|---|---|
| 正体 | 言語。ブラウザのエンジンが実行する | 同じ言語。Node.jsのランタイム(V8)が実行する |
| グローバルオブジェクト | window | global |
| 扱う対象 | ページ:document、DOM、イベント | マシン:fs、http、process、os |
| モジュール | <script type="module">、import | require(CommonJS)と import(ESモジュール) |
| パッケージ | ページにバンドルする | npmで node_modules にインストールする |
| 入力 | クリック、フォーム、キーボードイベント | コマンドライン引数、標準入力、HTTPリクエスト |
Array、Promise、JSON、setTimeout、console | あり | あり |
いちばんつまずきやすいのはモジュールの行です。Node.jsは require と import の両方に対応していますが、ブラウザが理解するのは import だけです。どちらを選ぶかはCommonJSとESモジュールのページで説明しています。
言語は同じ
言語の機能だけを使う関数はどこでも動きます。このブロックにはNode.js特有のものが何もないので、ブラウザでも同じ行を表示します。
{"best":95,"average":85} と Passed: 2 of 3 が表示されました。スプレッド構文、reduce、テンプレート文字列、JSON はECMAScriptの標準で定められた言語の一部なので、どのランタイムにもあります。
Node.jsにしかないもの
Node.js特有なのは、OSとやり取りする組み込みモジュールとグローバルです。
ファイルを書き込み、それを読み戻して .txt 2 lines と表示し、続いて空の引数のリストを表示しました。ファイルへのアクセスも process.argv もブラウザにはありません。ページはディスクに触れられないからです。
どの言語機能が使えるか
言語にはバージョン(ES2015、ES2020、ES2024など)があり、新しい機能をどのくらいの速さで取り込むかはエンジンごとに違います。Node.jsはリリースごとに特定のV8エンジンを1つ同梱しているので、どの機能が動くかはNode.jsのバージョンで決まります。たとえば Object.groupBy や Array.prototype.findLast には新しめのバージョンが必要です。そのため機能の対応表では、Chrome、Firefox、Safariと並んでNode.jsが1つの列になっています。新しい構文が SyntaxError で失敗したり、メソッドが undefined だったりしたら、node --version を実行して、polyfillに手を出す前にアップグレードしましょう。
両方で動くコードを書く
ライブラリの作者は、環境固有のAPIを使う前に、コードがどこで動いているかを確認することがあります。
const isNode = typeof process !== 'undefined' && process.versions?.node != null;
const isBrowser = typeof window !== 'undefined';
できれば環境の名前ではなく、必要な機能そのものを確認してください。「これはNodeか」よりも typeof fetch === 'function' のほうが多くを語ります。今はどちらにも fetch、URL、TextEncoder、setTimeout、structuredClone があるので、確認が必要なコードは数年前より減っています。
よくある間違い
Node.jsのスクリプトで document や window を使う。 ReferenceError: document is not defined になります。そのコードはブラウザで動かすものです。
ブラウザで require を使う。 ブラウザにはありません。import を使うか、require の呼び出しを1つのファイルにまとめてくれるバンドラーを使います。
Node.jsを別の言語だと思う。 そうではありません。JavaScriptのチュートリアルで教わることは、DOMを使わない限りNode.jsでもそのまま動きます。
よくある質問
JavaScriptを学ばずにNode.jsを学べますか?
実際には無理です。Node.jsで書く行はすべてJavaScriptなので、まず言語からです。関数、オブジェクト、Promiseがわかれば、Node.jsは追加のAPIを覚えるだけです。
Node.jsで「document is not defined」と出るのはなぜですか?
document はブラウザのDOMで、Node.jsにはそれを用意してくれるページがありません。document や window に触れるコードは、ブラウザか、jsdomのようにDOMを再現するテスト環境で動かす必要があります。
TypeScriptとNode.jsは同じものですか?
違います。TypeScriptは型付きのJavaScriptで、JavaScriptにコンパイルされます。その結果はNode.jsでもブラウザでも動かせますし、最近のNode.jsは型を取り除くことで多くの .ts ファイルを直接実行することもできます。