Felix's Node.js Style Guide

node.jsアプリケーションのスタイルを支配する公的な文章はありません。このガイドはあなたが美しく、一貫したソフトウェアを作れるようになる教訓を与えようとする私の独断の試みです。

このガイドはあなたがnode.jsのみを対象にしていると仮定しています。もしあなたのコードをブラウザなど他の環境でも動かす必要があるのなら、いくつかのガイドは無視してください。

様々なパッケージだけではなくnode.jsもまた、それぞれ自体のスタイルを持っています。なので何かのパッケージの開発に貢献することに興味があるのならば、それぞれのルールに従ってコーディングを楽しんでください。

Tab vs Spaces

まずはこの宗教的な問題の話をしましょう。私達の慈悲深い独裁者様はnodeのコアに2スペースのインデントを選択なさったので、彼の秩序に従うのが賢明でしょう。

セミコロン

あなたからセミコロンを奪おうとする反抗的な軍隊があるようです。でも確かに私達の伝統的な文化はまだ元気に生き残っています。だからコミュニティに従って、セミコロンを使いなさい!

エディタ

どんなエディタを使ってもいいです。しかし、JavaScriptの構文ハイライトと、現在開いているファイルをnode.jsで実行できることはとても役に立つでしょう。Vimは女の子にもてる為には役にたたないかも知れませんが、私達のBFDL(訳注:オープンソースソフトウェア開発のリーダー)を満足させ、あなたのおじいさんもまた賛成するでしょう。

私(訳注:原文筆者)はこのドキュメントをiPadの「メモ」で書いていますが、それは私がタイのベンチに座っているからです。このように、あなたの開発環境はあなたのエディタにも影響を与えるでしょう。

末尾の空白

ご飯の後には歯を磨くように、あなたのJavaScriptファイルをコミットする前に末尾の空白はすべて取り除きましょう。そうでなければ不注意な怠慢による悪臭によってコントリビューターや同僚はしばらくのちに逃げ出すでしょう。

一行の長さ

一行の長さは80文字に制限してください。スクリーンは確かにここ数年で十分大きくなりましたが、あなたの脳は大きくなっていません。スクリーンを増やす為にもう一部屋使いましょうか。あなたのエディタはサポートしていますよね?

クォート

JSON以外ではシングルクォートを使いましょう。

せいかい:

  
    var foo = 'bar';
  
  

まちがい:

  
    var foo = "bar"
  
  

中括弧

開き括弧は文と同じ行に置きましょう。

せいかい:

  
    if (true) {
  console.log('winning');
}

まちがい:

  
    if (true)
{
  console.log('losing');
}

条件文の前後のスペースの使い方にも注意してください。

変数宣言

行の順番の変更が簡単になるので、一文ごとに一つの変数を宣言しましょう。ここではCrockfordは無視して、道理にかなったところで宣言してください。

せいかい:

  
    var keys = ['foo', 'bar'];
var values = [23, 42];

var object = {};
while (items.length) {
  var key = keys.pop();
  object[key] = values.pop();
}

まちがい:

  
    var keys = ['foo', 'bar'],
   values = [23, 42],
   object = {},
   key;

while (items.length) {
  key = keys.pop();
  object[key] = values.pop();
}

変数とプロパティの名前

変数とプロパティの名前にはローワーキャメルケースを使うべきです。それは分かりやすいものでもあるのです。一文字の変数や一般的でない略語は普通避けるべきです。

せいかい:

  
    var adminUser = db.query('SELECT * FROM users ...');
  
  

まちがい:

  
    var admin_user = d.query('SELECT * FROM users ...');
  
  

クラスの名前

クラスの名前にはアッパーキャメルケースを使うべきです。

せいかい:

  
    function BankAccount() {
}

まちがい:

  
    function bank_Account() {
}

定数

定数は普通の変数やクラスのプロパティとして、すべて大文字で宣言されるべきです。

node.js(V8)は実はMozilla拡張のconst文をサポートしているのですが、残念ながらクラスのメンバには適用できず、ECMA標準にも含まれていないのです。

せいかい:

  
    var SECOND = 1 * 1000;

function File() {
}
File.FULL_PERMISSIONS = 0777;

まちがい:

  
    const SECOND = 1 * 1000;

function File() {
}
File.fullPermissions = 0777

Object / Array の作成

最後にはコンマを置いて、一行で短い宣言をしてください。キーにクォートを使うのはインタプリタが文句を言うときだけです。

せいかい:

  
    var a = ['hello', 'world'];
var b = {
  good: 'code',
  'is generally': 'pretty',
};

まちがい:

  
    var a = [
  'hello', 'world'
];
var b = {"good": 'code'
        , is generally: 'pretty'
};

同値演算子

プログラミングとはくだらないルールを覚えることではありません。あなたの期待通りに動かすために、===演算子を使いましょう。

せいかい:

  
    var a = 0;
if (a === '') {
  console.log('winning');
}

まちがい:

  
    var a = 0;
if (a == '') {
  console.log('losing');
}

prototype の拡張

すべてのオブジェクト、特にネイティブオブジェクトのprototypeは拡張しないでください。このルールに従わないのならば地獄が待っています。

せいかい:

  
    var a = [];
if (!a.length) {
  console.log('winning');
}

まちがい:

  
    Array.prototype.empty = function() {
  return !this.length;
}

var a = [];
if (a.empty()) {
  console.log('losing');
}

条件文

すべての自明でない条件文にはわかりやすい名前の変数が与えられるべきです。

せいかい:

  
    var isAuthorized = (user.isAdmin() || user.isModerator());
if (isAuthorized) {
  console.log('winning');
}

まちがい:

  
    if (user.isAdmin() || user.isModerator()) {
  console.log('losing');
}

関数の長さ

関数は短くしましょう。よい関数は、一枚のスライドに、大きな部屋の一番後ろの列にいる人が快適に読めるようにおさまります。だから完璧な見た目は期待せず、関数ごとに10行ぐらいで我慢してください。

return 文

if分の深いネストを避けるために、出来るだけ早く関数から値をreturnしてください。

せいかい:

  
    function isPercentage(val) {
  if (val < 0) {
    return false;
  }

  if (val > 100) {
    return false;
  }

  return true;
}

まちがい:

  
    function isPercentage(val) {
  if (val < 0) {
    if (val > 100) {
      return false;
    } else {
      return true;
    }
  } else {
    return false;
  }
}

この例の場合はもっと短くしてもいいでしょう。

  
    function isPercentage(val) {
  var isInRange = (val >= 0 && val <= 100);
  return isInRange;
}

名前付きクロージャ

クロージャに名前をつけても大丈夫です。あなたがその関数に注意していることを強調でき、またより良いスタックトレースを生み出すでしょう。

せいかい:

  
    req.on('end', function onEnd() {
  console.log('winning');
});

まちがい:

  
    req.on('end', function() {
  console.log('losing');
});

ネストされたクロージャ

クロージャは使って良いですが、ネストしないでください。そうでなければコードはぐちゃぐちゃになるでしょう。

せいかい:

  
    setTimeout(function() {
  client.connect(afterConnect);
}, 1000);

function afterConnect() {
  console.log('winning');
}

まちがい:

  
    setTimeout(function() {
  client.connect(function() {
    console.log('losing');
  });
}, 1000);

コールバック

nodeはI/Oをブロックしないための物なので、関数は普通コールバックを使って結果を返します。nodeのコアでの慣習にすべてのコールバック関数の最初の引数を任意のエラーオブジェクトのために予約しておくというものがあります。

あなたもコールバック関数では同じアプローチをするべきです。

Object.freeze, Object.preventExtensions, Object.seal, with, eval

永遠に不必要だろうくそったれ共です。近づかないでください。

getter と setter

セッターを使わないでください。あなたのソフトウェアを使う人々が自身で解決できない問題を引き起こす可能性があります。

副作用のないゲッターを使うことを気にしないでください。たとえば集合のクラスのlengthプロパティを提供することなどです。

EventEmitter

Node.jsは'event'モジュールからインクルードできるEventEmitterというシンプルなクラスを搭載しています。

  
    var EventEmitter = require('events').EventEmitter;
  
  

複雑なクラスを作るとき、イベントを発行するためにこのEventEmitterクラスを継承するのが普通です。このクラスはObserverパターンの単純な実装です。

しかし、私はあなたのクラス自身からのイベントを受け取らないようにすることを強く推奨します。オブジェクトが自身を監視することは不自然です。そのようなことはしばしば内部の実装の詳細を望ましくないことで晒してしまう原因となり、あなたのコードをたどる事をずっと難しくしてしまうからです。

継承 / オブジェクト指向プログラミング

継承とオブジェクト指向プログラミングはそれだけで大きな主題です。あなたかこの有名なプログラミングモデルに従うことに興味があるのならば、私のオブジェクト指向プログラミングのガイドを読んでください。