言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Node.js辞典

  1. トップページ
  2. Node.js辞典
  3. コメント(// と /* */)

コメント(// と /* */)

『Node.js』におけるコメントの書き方です。JavaScript と同じ記法で、一行コメント(『//』)・ブロックコメント(『/* */』)・JSDoc コメント(『/** */』)が使えます。Node.js の実装では、モジュール・関数・クラスに JSDoc コメントを書く慣習がよく見られます。TypeScript を使わない純粋な JavaScript プロジェクトでも JSDoc で型情報を補足できます。

構文

// 一行コメント — // から行末までがコメントになります。
const port = 3000; // 行末コメント — コードの後にも書けます。

/*
  ブロックコメント — /* から */ までの範囲がコメントになります。
  複数行にわたる説明を書くときに使います。
*/

/**
 * JSDoc コメント — /** で始めるブロックコメントです。
 * 関数・クラス・モジュールの直前に書き、型情報や説明を記述します。
 * @param {型} 引数名 - 引数の説明
 * @returns {型} 戻り値の説明
 */

コメントの種類

種類書き方概要
一行コメント// テキスト『//』から行末までがコメントになります。コードの右側に補足を添えるときにも使います。
ブロックコメント/* テキスト */複数行にまたがるコメントを書くときに使います。モジュールの概要やファイル冒頭の説明に使われます。
JSDoc コメント/** テキスト */『/**』で始まる特殊なブロックコメントです。エディタや自動ドキュメントツールが解析できる形式で型や説明を記述します。

JSDoc の主なタグ

Node.js の関数・クラス・モジュールに JSDoc コメントを書くと、VS Code などのエディタがホバー表示でドキュメントを表示します。TypeScript を使っていないプロジェクトでも、JSDoc だけで型チェックと補完が機能します。

タグ書き方の例概要
@param@param {string} name - ユーザー名関数の引数の型と説明を記述します。省略可能な引数は名前を『[ ]』で囲みます(例: @param {string} [label="default"])。
@returns@returns {number} 計算結果関数の戻り値の型と説明を記述します。非同期関数では @returns {Promise<number>} のように Promise の型を記述します。
@throws@throws {Error} ファイルが存在しない場合関数がスローする可能性のある例外の型と条件を記述します。
@async@async非同期関数であることを明示します。実際には async キーワードで判断できますが、明示するために書かれることがあります。
@example@example
const result = add(1, 2);
関数の使用例をコードとして記述します。エディタがホバー表示に含める場合があります。
@type@type {string[]}変数の型を記述します。TypeScript の型注釈を使わずに型情報を提供したいときに使います。
@typedef@typedef {Object} User独自の型(オブジェクトの形)を定義します。プロパティは @property タグと組み合わせます。
@property@property {string} name - 名前『@typedef』で定義したオブジェクト型のプロパティを記述します。
@callback@callback RequestHandlerコールバック関数の型を定義します。Node.js のエラーファーストコールバック((err, data))の記述に使われます。
@module@module utilsファイルがモジュールであることと、その名称を記述します。ファイル先頭の JSDoc に書きます。
@deprecated@deprecated v2.0 以降は getUser() を使用してください。非推奨であることと理由を記述します。エディタが取り消し線と警告を表示します。

コメントを書くべき場所・書かなくてよい場所

判断場面理由
書くべき「なぜこう実装したか」の理由コードを読むだけではわからない設計意図やトレードオフを残しておくと、将来の自分や他の開発者が助かります。
書くべき複雑なアルゴリズムや計算式何をしているか一見でわかりにくい処理には、動作の概要を補足します。
書くべき公開 API や再利用する関数引数・戻り値・副作用を JSDoc で明示しておくと、呼び出し側がドキュメントを参照しなくても使えます。
書くべきデバッグ中の一時的な無効化コメントアウトした理由や期限を残しておくと、後で削除し忘れるリスクが減ります。
書かなくてよいコードを読めば明らかな処理自明な説明はノイズになります。変数名・関数名をわかりやすくすれば不要になります。
書かなくてよい変更履歴・削除したコードバージョン管理(git)があるため、コメントに古いコードや変更日を残す必要はありません。

サンプルコード

基本的なコメントの使い方

math.js
/**
 * @module math
 * 数値計算に関するユーティリティ関数群です。
 */

/**
 * 2つの数値の合計を計算します。
 * @param {number} a - 加算する最初の数値
 * @param {number} b - 加算する2番目の数値
 * @returns {number} a と b の合計
 * @example
 * const result = add(3, 4);
 * // result === 7
 */
function add(a, b) {
  return a + b;
}

/**
 * 配列の数値の平均値を計算します。
 * @param {number[]} values - 平均を計算する数値の配列
 * @returns {number} 配列の平均値
 * @throws {Error} 配列が空の場合はエラーをスローします。
 */
function average(values) {
  if (values.length === 0) {
    // 空配列で割り算すると NaN になるため早期リターンします。
    throw new Error('values must not be empty');
  }

  var sum = values.reduce(function(acc, val) { return acc + val; }, 0);

  /*
    reduce の第2引数に 0 を渡しているのは、
    空配列への対応と初期値を明示するためです。
  */
  return sum / values.length;
}

module.exports = { add: add, average: average };

実行すると次のように出力されます。

$ node -e "const m = require('./math'); console.log(m.add(3,4)); console.log(m.average([10,20,30]));"
7
20

非同期関数と JSDoc

file_reader.js
var fs = require('fs').promises;
var path = require('path');

/**
 * @typedef {Object} FileInfo
 * @property {string} name - ファイル名
 * @property {number} size - ファイルサイズ(バイト)
 * @property {string} content - ファイルの内容(UTF-8)
 */

/**
 * 指定したパスのファイルを読み込み、内容と情報を返します。
 * @async
 * @param {string} filePath - 読み込むファイルのパス
 * @returns {Promise<FileInfo>} ファイル情報オブジェクト
 * @throws {Error} ファイルが存在しない場合やアクセスできない場合
 */
async function readFileInfo(filePath) {
  // ファイルの内容と stat を並行して取得します。
  var results = await Promise.all([
    fs.readFile(filePath, 'utf8'),
    fs.stat(filePath),
  ]);
  var content = results[0];
  var stat = results[1];

  return {
    name: path.basename(filePath),
    size: stat.size,
    content: content,
  };
}

// メイン処理
readFileInfo('./package.json')
  .then(function(info) {
    console.log('ファイル名: ' + info.name);
    console.log('サイズ: ' + info.size + ' bytes');
  })
  .catch(function(err) {
    // エラーの内容を stderr に出力して非ゼロ終了します。
    console.error('エラー:', err.message);
    process.exit(1);
  });

デバッグ用コメントアウト

server.js
var http = require('http');

var PORT = process.env.PORT || 3000;

/*
  Node.js の http.createServer は非同期で接続を処理します。
  イベントループがリクエストを受け取るたびにコールバックを呼び出します。
*/
var server = http.createServer(function(req, res) {
  // デバッグ中: リクエストの詳細を確認する(本番では削除します)。
  // console.log('Request:', req.method, req.url, req.headers);

  if (req.url === '/health') {
    // ヘルスチェック用エンドポイント。ロードバランサーが定期的に確認します。
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ status: 'ok' }));
    return;
  }

  // TODO: ルーティングロジックを追加する(#78 参照)。
  res.writeHead(404, { 'Content-Type': 'text/plain' });
  res.end('Not Found');
});

server.listen(PORT, function() {
  console.log('Server listening on port ' + PORT);
});

概要

Node.js のコメント記法は JavaScript と同じです。一行コメント(『//』)・ブロックコメント(『/* */』)・JSDoc コメント(『/** */』)を使います。Node.js の実装では、公開する関数・クラス・モジュールに JSDoc コメントを書く慣習がよく見られます。TypeScript を使わない純粋な JavaScript プロジェクトでも、JSDoc を書くだけで VS Code の型チェックと補完が機能します。

非同期関数には『@async』と『@returns {Promise<型>}』を書いておくと、呼び出し側が戻り値の型を把握しやすくなります。エラーファーストコールバックのパターン((err, data))を持つ関数には『@callback』タグで型を定義しておくと、コールバックの引数の型が明確になります。

コメントは「何をしているか」ではなく「なぜそうしているか」を書くと効果的です。コードを読めば明らかな処理を逐一コメントで説明するのはノイズになります。変更履歴や削除したコードをコメントとして残す必要もありません。それらはバージョン管理(git)で追跡できます。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。