LoginSignup
3
0

More than 3 years have passed since last update.

Ragate JavaScript Coding Rules

Last updated at Posted at 2019-07-02

Ragate JavaScriptコーディング規約

社内向けのドキュメントですが、ご質問やご意見等あればコメント大歓迎です!

はじめに

Ragate株式会社では、エンジニアを募集しています!
https://recruit.ragate.co.jp/

コーディング規約の規約

  • 規約で縛りすぎない(エンジニア上級者にとって細かすぎる規約は足枷でしかなく、開発スピードが落ち、やる気も損ねるため)
  • それぞれの項目に、「なぜこの規約を設定するのか」という目的( GOAL )を書く
  • 各項目には MUSTSHOULD をラベリングする
  • MUST は必ず守る規約
  • SHOULD はできれば守ってほしい推奨項目
  • なるべく規約の例をコードで書き示す
  • 個人的な好みではなく合理性を追求する

命名

GOAL 命名規則を統一し、直感的に分かりやすく命名することで、可読性を向上させる

ケース

MUST 変数や関数の名前はキャメルケース

const date = new Date()
function startCoding () {}

MUST 定数の名前は全て大文字

const WIDTH = 123

SHOULD ENUMまたはENUMのような機能を持つ変数の値は全て大文字

const mode = 'ADMIN'

SHOULD クラスやVueコンポーネントの名前はパスカルケース
SHOULD ファイル名はキャメルケース(クラスやVueコンポーネントの定義ファイルはパスカルケース

UserReport.js
class UserReport {}

品詞/文法

MUST 変数や関数の名前は英語の文法的に問題ない範囲で命名する
MUST 変数名は名詞
MUST 関数名は動詞から始める
MUST 単語を略さない(誰もが分かる略語を使うのはOK)
SHOULD 名前は短く(30文字以上はできるだけ避ける)

const createdDate = new Date()
function startCoding () {}

MUST 配列の変数名は複数形

const users = []

SHOULD 真偽値の変数名はis/has/canのいずれかから始める
SHOULD 真偽値の変数名にflgflagという単語を使わない

const user = {
  isGood: true,
  hasCar: true,
  canDrive: false,
}

基本文法

GOAL 基本文法の書き方を統一し、ミスを防ぐような書き方をすることで、可読性を向上させる

SHOULD 末尾にセミコロンを入れない
SHOULD なるべくletではなくconstで変数定義する

const hoge = 'fuga'

SHOULD オブジェクト定義時などに末尾にカンマを入れる
SHOULD インデント数を統一する(トレンド的な観点ではスペース2個が一般的)

const user = {
  isGood: true,
  hasCar: true,
  canDrive: false,
}

SHOULD 三項演算子はネストしない(見づらい)

// Bad
const hoge = fuga <= 5 ? piyo < 0 ? 0 : baki > 0 ? baki : 99

// Good
let hoge = 99
if (fuga <= 5) {
  if (piyo < 0) {
    hoge = 0
  } else if (baki > 0) {
    hoge = baki
  }
}

関数

GOAL 関数の書き方を統一し、直感的に分かりやすく、かつDRYに書くことで、可読性を向上させ、ユニットテストを導入しやすくし、保守性を上げる

MUST 最小機能単位(ユニットテストを書きやすい単位)で関数を書く
MUST 関数一つあたりの行数は少なく(100行以内はMUST、10行以内がSHOULD)
MUST 一行あたりの文字数は少なく(200文字以内はMUST、80文字以内がSHOULD)
SHOULD 波括弧の開始「{」は行の最後に書き、終了は「}」は行の最初に書く

function startCoding () {
  return 123
}

配列

GOAL 配列操作の書き方を統一し、分かりやすく、かつDRYに書くことで、可読性を向上させ、不具合を防ぐ

for

SHOULD 非常にシビアな動作スピードを求められる場面以外ではforを使わない

// Bad
const array = ['hoge', 'fuga', 'piyo']
for (var i = 0; i < array.length; i++) {
  console.log(array[i])
}

// Good
array.map(value => console.log(value))

SHOULD 配列から新しい配列を生成する時はArray.map()を使う

// Bad
const oldArray = ['hoge', 'fuga', 'piyo']
let newArray = []
oldArray.forEach((value, index) => {
  newArray.push(`${value}_${index}`)
})

// Good
const oldArray = ['hoge', 'fuga', 'piyo']
const newArray = oldArray.map((value, index) => {
  return `${value}_${index}`
})

SHOULD 配列からオブジェクトを生成する時はArray.reduce()を使う

// Bad
const array = ['hoge', 'fuga', 'piyo']
const object = {}
array.forEach((value, index) => {
  object[value] = index
})

// Good
const array = ['hoge', 'fuga', 'piyo']
const object = array.reduce((obj, value, index) => {
  obj[value] = index
  return obj
}, {})

非同期処理

GOAL コードが複雑になりがちな非同期処理を見やすく書くことで、可読性を向上させる

async/await

SHOULD 非同期処理はasync/awaitを使う
SHOULD awaitによる変数定義は同じ関数内でたくさん使わない(変数のスコープが広くなりバグの温床となるため)

// Bad
const hoge = await getHoge()
const fuga = await getFuga(hoge)
const piyo = await getPiyo(fuga)
const baki = await getBaki(piyo)

// Good
const baki = await getHoge()
  .then(getFuga)
  .then(getPiyo)
  .then(getBaki)

Lodash

GOAL Lodashを効果的に使うことで、不具合を防ぎ、可読性を向上させる

SHOULD オブジェクトがundefinedやnullになる可能性がある場合は_.get()を使う

const user = undefined
// Bad
user.hoge // Error

// Good
_.get(user, 'hoge') // Not Error

SHOULD 配列がundefinedやnullになる可能性がある場合は_.map()を使う
SHOULD mapだけでなくforEachやreduce等も同様

const users = undefined
// Bad
users.map(user => console.log(user)) // Error

// Good
_.map(users, user => console.log(user)) // []

SHOULD 配列がundefinedやnullになる可能性がある場合はlengthではなく_.size()を使う

const users = undefined
// Bad
users.length // Error

// Good
_.size(users) // 0

SHOULD 変数を定義しすぎず_.chain()を活用する(変数定義が多いとスコープが汚染され、不具合の温床となる)

// Bad
const users = [
  {name: 'hoge', age: 25},
  {name: 'fuga', age: 31},
  {name: 'piyo', age: 48},
]
const over30Users = users.filter(user => user.age >= 30)
const over30UsersCount = over30Users.length

// Good
const over30UsersCount = _.chain(users)
  .map('age')
  .filter(age => age >= 30)
  .size()
  .value()

あとがき

社内向けのドキュメントですが、ご質問やご意見等あればコメント大歓迎です!

また、Ragate株式会社では、エンジニアを募集しています!(2回目)
採用サイトもかなりこだわっているので是非一度ご覧になってみてください!
https://recruit.ragate.co.jp/

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0