[JavaScript講座] Node.jsの基本

当ページのリンクには広告が含まれています。
目次

Node.jsとは何か ─ ブラウザとの決定的な違い

そもそも Node.js は何者?

一言でいうと「ブラウザの外で JavaScript を動かすための実行環境(ランタイム)」です。

  • 中身は主に
    • Google Chrome と同じ V8 JavaScriptエンジン
    • 非同期I/Oまわりなどを提供する libuv などのネイティブライブラリ
  • これをまとめて、OS上で
    • ファイル操作
    • ネットワーク通信
    • プロセス管理
      などができるようにしたものが Node.js です。

よく使われる用途:

  • Web API サーバ(REST / GraphQL など)
  • CLIツール(ビルドツール、コード整形、Lint、スクリプト)
  • バッチ処理、スクリプト自動化
  • 開発用ツール(Webpack, Vite, ESLint…など、ほとんど Node 製)

ブラウザとの環境差分

同じ JavaScript でも 環境(ホスト)が違うと、使える API が変わります。

ブラウザにあって Node にないもの(代表例)

  • window / document / navigator など
  • DOM操作(document.querySelector など)
  • alert, confirm, prompt
  • <canvas> / WebGL, Geolocation(※一部Node向けライブラリはあるが別物)

→ Node.js には DOM がないので、
「画面を直接いじる」「ボタンがクリックされたら…」といった処理はできません。

Node にあって ブラウザにないもの(代表例)

  • ファイルシステム:fs モジュール
  • ネットワークソケット:net, http, https など
  • プロセス情報:process(環境変数、引数、終了コード…)
  • OS情報:os モジュール(CPU数、メモリ量 など)
  • パス操作:path モジュール

→ サーバ側・CLI側の処理は Node のお仕事 というイメージです。

どちらも「イベントループ+非同期I/O」で動く

ブラウザのJSは

  • シングルスレッド
  • イベントループ+タスクキュー+マイクロタスクキュー

で動いていました。

Node.js も基本は同じ考え方で、

  • メインスレッド上で JS を実行
  • ネットワークやファイルI/Oは libuv のスレッドプールで非同期にやってもらう
  • 完了したらイベントループ経由でコールバックや Promise を実行

という構造です。

なので「非同期処理の書き方(Promise / async/await)はブラウザと同じ」で、
対象API(DOMかfsか)が違うだけ、と捉えると理解しやすいです。

Node.jsのグローバルオブジェクト

globalglobalThis

ブラウザでは「グローバルオブジェクト」は通常 window でしたが、
Node.js では global がそれに相当します。

// Node.js 環境で
console.log(global);

ただし、最近の標準仕様では 環境を問わない「共通のグローバル」 として
globalThis が導入されました。

  • ブラウザ:window === globalThis が基本
  • Node.js:global === globalThis

→ 「どの環境でも動くコード」を書くなら globalThis を使うのが綺麗です。

globalThis.foo = 123;

console.log(globalThis.foo); // 123
console.log(global.foo);     // Nodeでは同じものを参照

※ ただし「グローバルに何でも作成する」のは設計上あまり良くないので、
実務的にはモジュールスコープを大事にするのがよいです。

process オブジェクト ─ Nodeの「実行プロセス」情報

process は Node に特有の 「いま動いているプロセス」の情報や操作 をまとめたオブジェクトです。

代表的なプロパティ・メソッド:

process.argv(コマンドライン引数)

node script.js foo bar
// script.js
console.log(process.argv);

たとえば上のように実行すると、出力はイメージとして:

[
  "/usr/local/bin/node",  // Node実行ファイル
  "/path/to/script.js",  // 実行中スクリプトのパス
  "foo",
  "bar"
]
  • process.argv[2] 以降が、ユーザが渡した引数
  • CLIツールを作るときの基本となる情報です

process.env(環境変数)

MY_NAME=COCCO node script.js
// script.js
console.log(process.env.MY_NAME); // "COCCO"
  • APIキーや接続先URLなど機密性のある情報を「コードに直書きせず」環境変数で渡すのが一般的
  • process.env.NODE_ENV === "production" かどうかで挙動を変えたりもよくあります

process.cwd()(カレントディレクトリ)

console.log(process.cwd()); // 現在の作業ディレクトリ(カレントディレクトリ)
  • ファイルパスを相対パスで扱いたい時に基準として使ったりします

process.exit([code])(プロセス終了)

console.log("処理中...");

if (何か致命的なエラー条件) {
  console.error("致命的エラー");
  process.exit(1); // エラー終了コードで終了
}

console.log("ここには到達しない");
  • 0:正常終了
  • 0以外:異常終了(慣習的に 1 が多い)

CLIツールでは終了コードによって「成功 / 失敗」を他のプロセスに知らせます。

5. process.stdout / process.stderr

process.stdout.write("標準出力に書く\n");
process.stderr.write("エラー出力に書く\n");
  • console.log は内部的に stdout を使っているイメージ
  • ログとエラーの出力先を明確に分けたい場面で直接使うこともあります

Node.jsでの簡単なCLIスクリプト例

Hello, CLI

  1. 適当なフォルダで hello.js を作る: console.log("Hello from Node.js!");
  2. ターミナルで: node hello.js

→ コンソールに Hello from Node.js! と表示されます。

ポイント:

  • これは「ブラウザのコンソール」ではなく、OSのターミナルに出ている
  • JSコードは同じでも、「どこに何を出しているのか」がブラウザと違う

引数を取るスクリプト

greet.js

// greet.js
const args = process.argv.slice(2); // 2つ飛ばしてユーザ引数だけ取得

const name = args[0] ?? "World";

console.log(`Hello, ${name}!`);

実行例:

node greet.js
# => Hello, World!

node greet.js COCCO
# => Hello, COCCO!
  • process.argvslice(2) して、["COCCO"] のようにして扱うのが定番
  • ??(Null合体演算子)は「未指定ならデフォルト」を書くのにちょうど良い

簡単なオプション解析

実務では yargs, commander などのライブラリを使うことが多いですが、
仕組み自体は単純です。

// cli.js
const args = process.argv.slice(2);
// 例: ["--name", "COCCO", "--debug"]

let name = "World";
let debug = false;

for (let i = 0; i < args.length; i++) {
  if (args[i] === "--name") {
    name = args[i + 1];
    i++;
  } else if (args[i] === "--debug") {
    debug = true;
  }
}

if (debug) {
  console.log("Debug mode ON");
}

console.log(`Hello, ${name}!`);
node cli.js --name COCCO --debug
# => Debug mode ON
# => Hello, COCCO!

「Node.jsでCLIが作れる」という感覚がここで一気に掴めるはずです。

簡単な標準入力の読み取り

// echo.js
process.stdin.setEncoding("utf8");

process.stdin.on("data", (chunk) => {
  console.log("あなたが入力したのは:", chunk.trim());
});
node echo.js
# ここで文字を打って Enter すると、そのまま返ってくる
  • stdindata イベントリスナを付けて、入力が来たら処理する
  • ブラウザの addEventListener とは「対象とイベント名」が違うだけで、
    発想としてはかなり近いのが分かると思います。

Node.js とモジュール

古くからの CommonJS(require / module.exports

従来、Node 独自のモジュールシステムは CommonJS でした:

// add.js
function add(a, b) {
  return a + b;
}

module.exports = { add };
// main.js
const { add } = require("./add");
console.log(add(1, 2));

近年の ES Modules(import / export

最近の Node では、ブラウザと同じ ES Modules (ESM) も使えます。

  • package.json"type": "module" を書く
  • ファイル拡張子を .mjs にする など、いくつかのルールあり
// add.mjs
export function add(a, b) {
  return a + b;
}
// main.mjs
import { add } from "./add.mjs";

console.log(add(1, 2));

ここを掘り下げると長くなるので、
「Nodeには歴史的に CommonJS があり、今はESMも使える」 くらいの認識でOKです。
(実務で触るときに、プロジェクト設定に合わせて import / require を選ぶ、という流れになります)


<<前へ(イベントとブラウザAPI)

>>次へ(Node.js標準モジュール)

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次