/eslint-config-codestates

๐Ÿ—‚๏ธ ESLint, Prettier, Stylelint configuration for CodeStates-Engineering

Primary LanguageJavaScript

eslint-config-codestates CI

CodeStates์—์„œ ์ž‘์„ฑํ•˜๋Š” ๊ณตํ†ต ๋ฆฐํŠธ ๊ทœ์น™ ๋ชจ์Œ์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

.github
โ”œโ”€โ”€ workflows
โ”‚   โ””โ”€โ”€ *.yaml
โ”œโ”€โ”€ CODEOWNERS
rules (๊ฐœ๋ฐœ์ž ์ปค์Šคํ…€ ๋ฃฐ ๊ทœ์น™ ๋ชจ์Œ)
โ”œโ”€โ”€ typescript (ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋ฃฐ)
โ”‚   โ””โ”€โ”€ *.js
โ”œโ”€โ”€ base.js (eslint ๊ธฐ๋ณธ ๋ฃฐ)
โ”œโ”€โ”€ import.js (๋ชจ๋“ˆ import/export ๊ด€๋ จ ๋ฃฐ)
โ”œโ”€โ”€ jsx-a11y.js (์ ‘๊ทผ์„ฑ ๊ด€๋ จ ๋ฃฐ)
โ”œโ”€โ”€ prettier.js (prettier ๊ด€๋ จ ๋ฃฐ)
โ”œโ”€โ”€ promise.js (promise ๊ด€๋ จ ๋ฃฐ)
โ”œโ”€โ”€ react-hooks.js (react hooks ๊ด€๋ จ ๋ฃฐ)
โ”œโ”€โ”€ react.js (react ๊ด€๋ จ ๋ฃฐ)
scripts (์Šคํฌ๋ฆฝํŠธ)
โ”œโ”€โ”€ canary-publish.sh (์นด๋‚˜๋ฆฌ ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ)
test (๋ฆฐํŠธ ํ…Œ์ŠคํŠธ ๋ชจ์Œ)
โ””โ”€โ”€ * (๊ฐ ํ™˜๊ฒฝ๋ณ„ ํ…Œ์ŠคํŠธ ๋””๋ ‰ํ† ๋ฆฌ)
    โ”œโ”€โ”€ .eslintrc
    โ””โ”€โ”€ *.{js,ts,tsx}
frontend.js (ํ”„๋ก ํŠธ์—”๋“œ ์ „์šฉ ๋ฆฐํŠธ ๋ชจ๋“ˆ)
index.js (๋ฆฐํŠธ ๋ชจ๋“ˆ)
prettierrc.js (ํ”„๋ฆฌํ‹ฐ์–ด ๋ชจ๋“ˆ)
stylelint.js (์Šคํƒ€์ผ๋ฆฐํŠธ ๋ชจ๋“ˆ)
tsconfig.json

์„ค์น˜

.npmrc

  1. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .npmrc ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ์ƒ์„ฑํ•œ ํŒŒ์ผ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
//npm.pkg.github.com/:_authToken=${CSE_NPM_TOKEN}
@codestates-engineering:registry=https://npm.pkg.github.com/
  1. ๊ฐ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

npm

npm install --save-dev @codestates-engineering/eslint-config-codestates

yarn

yarn add -D @codestates-engineering/eslint-config-codestates

์‚ฌ์šฉ ๋ฐฉ๋ฒ•

ESLint

  1. ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์˜ package.json scripts ์†์„ฑ์— ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
{
  "lint": "eslint './src/**/*.{js,ts,tsx}'",
  "lint:fix": "npm run lint -- --fix"
}
  1. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .eslintrc ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์ถ”๊ฐ€ํ•œ ๋ฆฐํŠธ ์˜์กด์„ฑ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์ถ”๊ฐ€, ํ™•์žฅํ•  ์„ค์ •์ด ์žˆ๋‹ค๋ฉด ์ฃผ์„ ๋ถ€๋ถ„์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

{
  "extends": [
    "@codestates-engineering/eslint-config-codestates"
    // ํ™•์žฅํ•  ๊ทœ์น™ ์ž‘์„ฑ
  ],
  "rules": {
    // ์ถ”๊ฐ€ํ•  ๊ทœ์น™ ์ž‘์„ฑ
  }
}

frontend

React ๊ธฐ๋ฐ˜์˜ ํ”„๋ก ํŠธ์—”๋“œ ํ”„๋กœ์ ํŠธ๋ผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด .eslintrc ํŒŒ์ผ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

{
  "extends": ["@codestates-engineering/eslint-config-codestates/frontend"]
}

Prettier

  1. ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์˜ package.json scripts ์†์„ฑ์— ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
{
  "prettier": "prettier './src/*.{json,yaml,md,js,ts,tsx}' --check",
  "prettier:fix": "prettier './src/*.{json,yaml,md,js,ts,tsx}' --write"
}
  1. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .prettierrc ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์ถ”๊ฐ€ํ•œ ์˜์กด์„ฑ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
'@codestates-engineering/eslint-config-codestates/prettierrc';

Stylelint

  1. ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์˜ package.json scripts ์†์„ฑ์— ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
{
  "lint:style": "stylelint './src/**/*.{js,ts,tsx}'",
  "lint:style:fix": "stylelint './src/**/*.{js,ts,tsx}' --fix"
}
  1. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .stylelintrc ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์ถ”๊ฐ€ํ•œ ์˜์กด์„ฑ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
{
  "extends": ["@codestates-engineering/eslint-config-codestates/stylelint"]
}

Versioning

Semantic Versioning์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  1. MAJOR ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์€ ๋ฐฉ์‹์œผ๋กœ ์ˆ˜์ •๋  ๊ฒฝ์šฐ
  2. MINOR ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ
  3. PATCH ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•  ๊ฒฝ์šฐ

CI/CD

Github Actions๋ฅผ ํ†ตํ•ด CI/CD๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ์ •์‹ Release์™€ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ Canary๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • feature/** ๋ธŒ๋žœ์น˜๋ฅผ push ํ•˜๋ฉด ์ž๋™์œผ๋กœ Canary ๋ฐฐํฌ๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • feature/** ๋ธŒ๋žœ์น˜์—์„œ Commit Message ์ž‘์„ฑ์‹œ skip canary ๋ฌธ์žฅ์„ ํฌํ•จ์‹œํ‚ค๋ฉด Canary ๋ฐฐํฌ๋ฅผ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค.
  • main ๋ธŒ๋žœ์น˜์— pushํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ •์‹ ๋ฒ„์ „์ด ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค.

Git Workflow

Git-flow๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘์—…ํ•ฉ๋‹ˆ๋‹ค.

Branch

  • main: ๋ฐฐํฌ๊นŒ์ง€ ๋งˆ๋ฌด๋ฆฌ๊ฐ€ ๋œ ์ตœ์ข… ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ๋ธŒ๋žœ์น˜
  • develop: main์„ ๊ธฐ์ค€์œผ๋กœ ์ตœ์‹ ํ™”๋œ ๋‹ค์Œ ๋ฒ„์ „์„ ๊ฐœ๋ฐœํ•  ๋ธŒ๋žœ์น˜
  • feature: ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ๋ธŒ๋žœ์น˜
  • release/**: ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์„ ์™„๋ฃŒํ•˜๊ณ  ๋ฐฐํฌํ•  ๋ธŒ๋žœ์น˜

develop

  1. ์ตœ์‹ ํ™”๋œ develop ๋ธŒ๋žœ์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ feature/** ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ๋ฐ ๊ฐœ๋ฐœ์— ๋Œ€ํ•œ CHANGELOG๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ฐœ๋ฐœ์ด ์™„๋ฃŒ๋œ feature ๋ธŒ๋žœ์น˜๋ฅผ pushํ•ฉ๋‹ˆ๋‹ค.
  4. target branch๋ฅผ develop ๋ธŒ๋žœ์น˜๋กœ ์„ค์ •ํ•˜๊ณ  PR์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๋•Œ ๊ฐœ๋ฐœํ•œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด์„œ ์ž๋™์œผ๋กœ Canary ๋ฐฐํฌ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
    • ๋งŒ์•ฝ, Canary ๋ฐฐํฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์— skip canary๋ฅผ ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค.
    • ์ด ๋•Œ Canary ๋ฐฐํฌ์˜ ํšŸ์ˆ˜๋Š” ๋ช‡ ๋ฒˆ์ด๋“  ์ƒ๊ด€ ์—†์Šต๋‹ˆ๋‹ค.
  5. ๋ฐฐํฌ๋œ Canary ๋ฒ„์ „์„ ํ†ตํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ ํ›„ ๋ฌธ์ œ๊ฐ€ ์—†๊ณ  ๋ฆฌ๋ทฐ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด develop ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  6. Local develop ๋ธŒ๋žœ์น˜๋ฅผ ์ตœ์‹ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

release/**

  1. ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์ด ์™„๋ฃŒ๋œ develop ๋ธŒ๋žœ์น˜๊ฐ€ ์ตœ์‹ ํ™” ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  2. develop๋ธŒ๋žœ์น˜์—์„œ ๋ฐฐํฌํ•  ๋ฒ„์ „์˜ release/v${๋ฐฐํฌํ• _๋ฒ„์ „} ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ฐฐํฌํ•  ๋ฒ„์ „์— ๋งž๊ฒŒ ๋ฒ„์ „์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • MAJOR npm version major
    • MINOR npm version minor
    • PATCH npm version patch
  4. PR์„ ์š”์ฒญํ•˜๊ณ  target branch๋ฅผ main ๋ธŒ๋žœ์น˜๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  5. CI๊ฐ€ ์ง„ํ–‰๋˜๊ณ  ์ด์ƒ์ด ์—†๋‹ค๋ฉด main ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  6. ๋ณ‘ํ•ฉ์‹œ ์ž๋™์œผ๋กœ CD๊ฐ€ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.
  7. CD ์ง„ํ–‰ ์ดํ›„ ์ž๋™์œผ๋กœ Release Tag๊ฐ€ ์ƒ์„ฑ๋˜๋ฉฐ ์ƒ์„ฑ๋œ Tag์— ๋ฐฐํฌ๋œ ๋ฒ„์ „์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  8. CD ์ดํ›„ develop ๋ธŒ๋žœ์น˜๋ฅผ ์ตœ์‹ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

Trouble shooting

vscode ํ™˜๊ฒฝ์—์„œ ํŒŒ์ผ ์ €์žฅ์‹œ AutoFix๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ settings.json์— ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
  "source.fixAll.stylelint": true,
  "source.fixAll.eslint": true
},
"stylelint.validate": [
  "css",
  "scss",
  "less",
  "postcss",
  "typescriptreact",
  "typescript",
  "javascript",
  "javascriptreact"
],
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
  "editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
  "editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
  "editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
  "editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
  "editor.defaultFormatter": "esbenp.prettier-vscode"
},