ESLint κ·μΉ λ° μ μ λΆμμΌλ‘ JavaScript μ½λ νμ§μ ν₯μμν€μΈμ. κΈλ‘λ² νλ‘μ νΈμμ μ μ§λ³΄μ κ°λ₯νκ³ κ²¬κ³ ν μ½λλ₯Ό μμ±νκΈ° μν λͺ¨λ² μ¬λ‘λ₯Ό λ°°μ°μΈμ.
JavaScript μ½λ νμ§: ESLint κ·μΉ λ° μ μ λΆμ
μ€λλ λΉ λ₯΄κ² λ³ννλ μννΈμ¨μ΄ κ°λ° νκ²½μμ κΉ¨λνκ³ μ μ§λ³΄μκ° μ©μ΄νλ©° κ²¬κ³ ν μ½λλ₯Ό μμ±νλ κ²μ΄ κ°μ₯ μ€μν©λλ€. JavaScript κ°λ°μμ κ²½μ°, νΉν λ€μν νκ³Ό μκ°λλ₯Ό λλλλ νμ μ΄ μΌλ°μ μΈ κΈλ‘λ² νλ‘μ νΈμμ μμ μ μΈ μ ν리μΌμ΄μ μ ꡬμΆνλ €λ©΄ λμ μ½λ νμ§μ 보μ₯νλ κ²μ΄ μ€μν©λλ€. μ΄λ₯Ό λ¬μ±νλ κ°μ₯ ν¨κ³Όμ μΈ λꡬ μ€ νλλ ESLint λ° μ μ λΆμμ ꡬννλ κ²μ λλ€.
ESLintλ 무μμ λκΉ?
ESLintλ μ μ¬μ μΈ λ¬Έμ λ₯Ό μλ³νκ³ , μ½λ© μ€νμΌ κ·μΉμ μ μ©νλ©°, μ€λ₯κ° λ°μνκΈ° μ μ μλ°©νκΈ° μν΄ μ½λλ₯Ό λΆμνλ κ°λ ₯ν JavaScript λ¦°ν λꡬμ λλ€. νμ΄ λ μ½κ² νμ νκ³ λ―Έλμ κ°λ°μκ° μ½λλ₯Ό μ΄ν΄νκ³ μμ ν μ μλλ‘ μ½λλ² μ΄μ€ μ 체μμ μΌκ΄μ±μ μ μ§νλ λ° λμμ΄ λ©λλ€.
ESLint μ¬μ©μ μ£Όμ μ΄μ :
- μ΄κΈ° μ€λ₯ κ°μ§: κ°λ° μ€μ μ μ¬μ μΈ λ²κ·Έμ μ€λ₯λ₯Ό μλ³νμ¬ λ°νμ λ¬Έμ μ μνμ μ€μ λλ€.
- μ½λ μ€νμΌ μ μ©: μΌκ΄λ μ½λ© μ€νμΌμ μ μ©νμ¬ μ½λλ² μ΄μ€λ₯Ό λ μ½κΈ° μ½κ³ μ μ§λ³΄μ κ°λ₯νκ² λ§λλλ€.
- ν₯μλ νμ : κ°λ° ν μ 체μμ μΌκ΄μ±μ λμ΄λ 곡μ κ·μΉ μΈνΈλ₯Ό μ 곡ν©λλ€.
- μλνλ μ½λ 리뷰: μ½λ 리뷰 νλ‘μΈμ€λ₯Ό μλννμ¬ κ°λ°μκ° λ 볡μ‘ν μμ μ μ§μ€ν μ μλλ‘ ν©λλ€.
- μ¬μ©μ μ μ κ°λ₯ν κ·μΉ: νΉμ νλ‘μ νΈ μꡬ μ¬ν λ° μ½λ© κΈ°λ³Έ μ€μ μ λ§κ² κ·μΉμ ꡬμ±ν μ μμ΅λλ€.
μ μ λΆμ μ΄ν΄
μ μ λΆμμ νλ‘κ·Έλ¨μ΄ μ€νλκΈ° μ μ μμ€ μ½λλ₯Ό κ²μ¬νμ¬ λλ²κΉ νλ λ°©λ²μ λλ€. λ¬Έμ λ₯Ό μλ³νκΈ° μν΄ μ½λλ₯Ό μ€νν΄μΌ νλ λμ λΆμκ³Ό λ¬λ¦¬ μ μ λΆμμ μ½λ ꡬ쑰 λ° κ΅¬λ¬Έ λΆμμ μμ‘΄ν©λλ€. ESLintλ μ μ λΆμ λꡬμ ν ννμ΄μ§λ§, λ λμ κ°λ μλ 보μ μ·¨μ½μ , μ±λ₯ λ³λͺ© νμ λ° κΈ°ν μ μ¬μ μΈ λ¬Έμ λ₯Ό κ°μ§ν μ μλ λ€λ₯Έ λκ΅¬κ° ν¬ν¨λ©λλ€.
μ μ λΆμ μλ λ°©μ
μ μ λΆμ λꡬλ μΌλ°μ μΌλ‘ λ€μμ ν¬ν¨ν κΈ°μ μ‘°ν©μ μ¬μ©νμ¬ μ½λλ₯Ό λΆμν©λλ€.
- μ΄ν λΆμ: μ½λλ₯Ό ν ν°(μ: ν€μλ, μ°μ°μ, μλ³μ)μΌλ‘ λΆν΄ν©λλ€.
- ꡬ문 λΆμ: μ½λ ꡬ쑰λ₯Ό λνλ΄λ ꡬ문 λΆμ νΈλ¦¬λ₯Ό ꡬμΆν©λλ€.
- μλ―Έ λΆμ: μ½λμ μλ―Έμ μΌκ΄μ±μ νμΈν©λλ€.
- λ°μ΄ν° νλ¦ λΆμ: μ μ¬μ μΈ λ¬Έμ λ₯Ό μλ³νκΈ° μν΄ μ½λλ₯Ό ν΅ν΄ λ°μ΄ν° νλ¦μ μΆμ ν©λλ€.
νλ‘μ νΈμμ ESLint μ€μ
ESLint μ€μ μ κ°λ¨ν©λλ€. λ€μμ λ¨κ³λ³ κ°μ΄λμ λλ€.
- ESLint μ€μΉ:
ESLintλ₯Ό μ μμ μΌλ‘ λλ νλ‘μ νΈ λ΄μμ λ‘μ»¬λ‘ μ€μΉν μ μμ΅λλ€. μΌλ°μ μΌλ‘ νλ‘μ νΈλ³λ‘ μ’ μμ±μ κ΄λ¦¬νκΈ° μν΄ λ‘μ»¬λ‘ μ€μΉνλ κ²μ΄ μ’μ΅λλ€.
npm install eslint --save-dev # or yarn add eslint --dev
- ESLint κ΅¬μ± μ΄κΈ°ν:
νλ‘μ νΈμ λ£¨νΈ λλ ν 리μμ λ€μ λͺ λ Ήμ μ€ννμ¬ ESLint κ΅¬μ± νμΌμ λ§λλλ€.
npx eslint --init
μ΄ λͺ λ Ήμ νλ‘μ νΈμ μꡬ μ¬νμ λ°λΌ ESLintλ₯Ό ꡬμ±νκΈ° μν΄ μΌλ ¨μ μ§λ¬Έμ μλ΄ν©λλ€. κΈ°μ‘΄ ꡬμ±(μ: Airbnb, Google, Standard)μ νμ₯νκ±°λ μμ λ§μ ꡬμ±μ λ§λ€ μ μμ΅λλ€.
- ESLint κ·μΉ ꡬμ±:
ESLint κ΅¬μ± νμΌ(
.eslintrc.js
,.eslintrc.yaml
λλ.eslintrc.json
)μ ESLintκ° μ μ©ν κ·μΉμ μ μν©λλ€. μ΄λ¬ν κ·μΉμ μ¬μ©μ μ μνμ¬ νλ‘μ νΈμ μ½λ© μ€νμΌ λ° μꡬ μ¬νμ λ§κ² μ‘°μ ν μ μμ΅λλ€.μμ
.eslintrc.js
:module.exports = { env: { browser: true, es2021: true, node: true }, extends: [ 'eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended' ], parser: '@typescript-eslint/parser', parserOptions: { ecmaFeatures: { jsx: true }, ecmaVersion: 12, sourceType: 'module' }, plugins: [ 'react', '@typescript-eslint' ], rules: { 'no-unused-vars': 'warn', 'no-console': 'warn', 'react/prop-types': 'off', '@typescript-eslint/explicit-function-return-type': 'off' } };
- ESLintλ₯Ό νΈμ§κΈ°μ ν΅ν©:
λλΆλΆμ μΈκΈ° μλ μ½λ νΈμ§κΈ°μλ μ½λλ₯Ό μμ±ν λ μ€μκ° νΌλλ°±μ μ 곡νλ ESLint νλ¬κ·ΈμΈμ΄ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ μ€λ₯λ₯Ό μ¦μ ν¬μ°©νκ³ μμ ν μ μμ΅λλ€.
- VS Code: VS Code Marketplaceμμ ESLint νμ₯μ μ€μΉν©λλ€.
- Sublime Text: SublimeLinter-eslint νλ¬κ·ΈμΈκ³Ό ν¨κ» SublimeLinter ν¨ν€μ§λ₯Ό μ¬μ©ν©λλ€.
- Atom: linter-eslint ν¨ν€μ§λ₯Ό μ€μΉν©λλ€.
- ESLint μ€ν:
λͺ λ Ήμ€μμ ESLintλ₯Ό μ€ννμ¬ μ½λλ₯Ό λΆμν μ μμ΅λλ€.
npx eslint .
μ΄ λͺ λ Ήμ νμ¬ λλ ν 리μ λͺ¨λ JavaScript νμΌμ λΆμνκ³ κ΅¬μ±λ κ·μΉμ λν μλ° μ¬νμ λ³΄κ³ ν©λλ€.
μΌλ°μ μΈ ESLint κ·μΉ λ° λͺ¨λ² μ¬λ‘
ESLintλ μ½λ© μ€νμΌ κ·μΉμ μ μ©νκ³ μ€λ₯λ₯Ό λ°©μ§νλ λ° μ¬μ©ν μ μλ κ΄λ²μν κ·μΉμ μ 곡ν©λλ€. λ€μμ κ°μ₯ μΌλ°μ μ΄κ³ μ μ©ν κ·μΉ μ€ μΌλΆμ λλ€.
no-unused-vars
: μ μΈλμμ§λ§ μ¬μ©λμ§ μμ λ³μμ λν΄ κ²½κ³ ν©λλ€. μ΄λ λ°λ μ½λλ₯Ό λ°©μ§νκ³ λΆνμν μ½λλ₯Ό μ€μ΄λ λ° λμμ΄ λ©λλ€.no-console
: νλ‘λμ μ½λμμconsole.log
λ¬Έμ μ¬μ©νλ κ²μ κΈμ§ν©λλ€. λ°°ν¬ μ μ λλ²κΉ λ¬Έμ μ 리νλ λ° μ μ©ν©λλ€.no-unused-expressions
: λΆμμ©μ΄ μλ ννμκ³Ό κ°μ΄ μ¬μ©λμ§ μμ ννμμ κΈμ§ν©λλ€.eqeqeq
: μΆμμ νλ±(==
λ°!=
) λμ μ격ν νλ±(===
λ°!==
)μ μ¬μ©νλλ‘ κ°μ ν©λλ€. μ΄λ μκΈ°μΉ μμ μ ν κ°μ λ³ν λ¬Έμ λ₯Ό λ°©μ§νλ λ° λμμ΄ λ©λλ€.no-shadow
: μΈλΆ λ²μμμ μ μΈλ λ³μλ₯Ό μλμνλ λ³μ μ μΈμ κΈμ§ν©λλ€.no-undef
: μ μΈλμ§ μμ λ³μμ μ¬μ©μ κΈμ§ν©λλ€.no-use-before-define
: λ³μκ° μ μλκΈ° μ μ μ¬μ©νλ κ²μ κΈμ§ν©λλ€.indent
: μΌκ΄λ λ€μ¬μ°κΈ° μ€νμΌ(μ: 2μΉΈ 곡백, 4μΉΈ 곡백 λλ ν)μ μ μ©ν©λλ€.quotes
: μΌκ΄λ λ°μ΄ν μ¬μ©(μ: μμλ°μ΄ν λλ ν°λ°μ΄ν)μ μ μ©ν©λλ€.semi
: λ¬Έμ₯ λμ μΈλ―Έμ½λ‘ μ μ¬μ©νλλ‘ κ°μ ν©λλ€.
μμ : μΌκ΄λ λ°μ΄ν μ μ©
JavaScript μ½λμμ μμλ°μ΄νλ₯Ό μ¬μ©νλλ‘ κ°μ νλ €λ©΄ ESLint ꡬμ±μ λ€μ κ·μΉμ μΆκ°ν©λλ€.
rules: {
'quotes': ['error', 'single']
}
μ΄ κ·μΉμ΄ νμ±νλλ©΄ ESLintλ μμλ°μ΄ν λμ ν°λ°μ΄νλ₯Ό μ¬μ©νλ©΄ μ€λ₯λ₯Ό λ³΄κ³ ν©λλ€.
ESLintλ₯Ό μν¬νλ‘μ ν΅ν©
ESLintμ μ΄μ μ κ·Ήλννλ €λ©΄ κ°λ° μν¬νλ‘μ ν΅ν©νλ κ²μ΄ μ€μν©λλ€. λ€μμ λͺ κ°μ§ λͺ¨λ² μ¬λ‘μ λλ€.
- Pre-commit Hook μ¬μ©:
μ½λλ₯Ό 컀λ°νκΈ° μ μ ESLintλ₯Ό μ€ννλλ‘ pre-commit hookμ ꡬμ±ν©λλ€. μ΄λ ESLint κ·μΉμ μλ°νλ μ½λκ° λ¦¬ν¬μ§ν 리μ 컀λ°λλ κ²μ λ°©μ§ν©λλ€.
Husky λ° lint-stagedμ κ°μ λꡬλ₯Ό μ¬μ©νμ¬ pre-commit hookμ μ€μ ν μ μμ΅λλ€.
npm install husky --save-dev npm install lint-staged --save-dev
package.json
μ λ€μ ꡬμ±μ μΆκ°ν©λλ€.{ "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.js": [ "eslint --fix", "git add" ] } }
- μ§μμ μΈ ν΅ν©(CI)κ³Ό ν΅ν©:
λ°°ν¬νκΈ° μ μ λͺ¨λ μ½λκ° νμ§ νμ€μ μΆ©μ‘±νλμ§ νμΈνκΈ° μν΄ CI νμ΄νλΌμΈμ μΌλΆλ‘ ESLintλ₯Ό μ€νν©λλ€. μ΄λ μ€λ₯λ₯Ό μ‘°κΈ°μ ν¬μ°©νκ³ νλ‘λμ νκ²½μ μ§μ νλ κ²μ λ°©μ§νλ λ° λμμ΄ λ©λλ€.
Jenkins, Travis CI, CircleCI λ° GitHub Actionsμ κ°μ μΈκΈ° μλ CI λꡬλ ESLint μ€νμ μν ν΅ν© κΈ°λ₯μ μ 곡ν©λλ€.
- μ½λ ν¬λ§· μλν:
Prettierμ κ°μ μ½λ ν¬λ§·ν°λ₯Ό μ¬μ©νμ¬ κ΅¬μ±λ μ€νμΌ κ·μΉμ λ°λΌ μ½λλ₯Ό μλμΌλ‘ ν¬λ§·ν©λλ€. μ΄λ₯Ό ν΅ν΄ μ½λλ₯Ό μλμΌλ‘ ν¬λ§·ν νμκ° μμΌλ©° μ½λλ² μ΄μ€ μ 체μμ μΌκ΄μ±μ 보μ₯ν©λλ€.
Prettierλ₯Ό ESLintμ ν΅ν©νμ¬ ν¬λ§· λ¬Έμ λ₯Ό μλμΌλ‘ μμ ν μ μμ΅λλ€.
npm install prettier eslint-config-prettier eslint-plugin-prettier --save-dev
.eslintrc.js
λ₯Ό μ λ°μ΄νΈν©λλ€.module.exports = { extends: [ 'eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended', 'prettier' ], plugins: [ 'react', '@typescript-eslint', 'prettier' ], rules: { 'prettier/prettier': 'error' } };
ESLintλ₯Ό λμ΄μ: λ€λ₯Έ μ μ λΆμ λꡬ νμ
ESLintλ λ¦°ν λ° μ€νμΌ μ μ©μ νλ₯ν λꡬμ΄μ§λ§, λ€λ₯Έ μ¬λ¬ μ μ λΆμ λꡬλ μ½λμ λν λ κΉμ ν΅μ°°λ ₯μ μ 곡νκ³ λ 볡μ‘ν λ¬Έμ λ₯Ό μλ³ν μ μμ΅λλ€.
- SonarQube: μ½λ νμ§μ μ§μμ μΈ κ²μ¬λ₯Ό μν ν¬κ΄μ μΈ νλ«νΌμ λλ€. JavaScriptλ₯Ό ν¬ν¨ν λ€μν μΈμ΄μμ λ²κ·Έ, μ·¨μ½μ λ° μ½λ λμλ₯Ό κ°μ§ν©λλ€. SonarQubeλ μκ° κ²½κ³Όμ λ°λ₯Έ μ½λ νμ§μ μΆμ νκ³ κ°μ νλ λ° λμμ΄ λλ μμΈν λ³΄κ³ μμ λ©νΈλ¦μ μ 곡ν©λλ€.
- JSHint: μ€λλμμ§λ§ μ¬μ ν μ μ©ν JavaScript λ¦°ν λꡬμ λλ€. μΌλΆ μμμμλ ESLintλ³΄λ€ κ΅¬μ± κ°λ₯μ±μ΄ λ λμ΅λλ€.
- TSLint: (λ μ΄μ μ¬μ©λμ§ μμΌλ©° μ΄μ TypeScript νλ¬κ·ΈμΈμ΄ μλ ESLintκ° μ νΈλ¨) TypeScript μ μ© λ¦°ν°μ
λλ€. μ΄μ TypeScript νλ‘μ νΈλ
@typescript-eslint/eslint-plugin
λ°@typescript-eslint/parser
μ ν¨κ» ESLintλ₯Ό μ μ λ λ§μ΄ μ¬μ©νκ³ μμ΅λλ€. - FindBugs: Java μ½λ λΆμμλ μ¬μ©ν μ μλ Javaμ© μ μ λΆμ λꡬμ λλ€. μ μ¬μ μΈ λ²κ·Έ λ° μ±λ₯ λ¬Έμ λ₯Ό μλ³ν©λλ€. μ£Όλ‘ Javaμ©μ΄μ§λ§ μΌλΆ κ·μΉμ JavaScriptμ μ μ©ν μ μμ΅λλ€.
- PMD: JavaScriptλ₯Ό ν¬ν¨ν μ¬λ¬ μΈμ΄λ₯Ό μ§μνλ μμ€ μ½λ λΆμκΈ°μ λλ€. λ°λ μ½λ, μ€λ³΅ μ½λ λ° μ§λμΉκ² 볡μ‘ν μ½λμ κ°μ μ μ¬μ μΈ λ¬Έμ λ₯Ό μλ³ν©λλ€.
κΈλ‘λ² νλ‘μ νΈμ ESLint: κ΅μ νμ μν κ³ λ € μ¬ν
λΆμ°λ νκ³Ό ν¨κ» κΈλ‘λ² JavaScript νλ‘μ νΈμμ μμ ν λ ESLintλ λμ± μ€μν΄μ§λλ€. λ€μμ λͺ κ°μ§ κ³ λ € μ¬νμ λλ€.
- 곡μ ꡬμ±: λͺ¨λ ν ꡬμ±μμ΄ λμΌν ESLint κ΅¬μ± νμΌμ μ¬μ©νκ³ μλμ§ νμΈν©λλ€. μ΄λ μ½λλ² μ΄μ€ μ 체μμ μΌκ΄μ±μ λμ΄κ³ μ€νμΌ μΆ©λ μνμ μ€μ λλ€. λ²μ μ μ΄λ₯Ό μ¬μ©νμ¬ κ΅¬μ± νμΌμ κ΄λ¦¬νκ³ μ΅μ μνλ‘ μ μ§ν©λλ€.
- λͺ νν μμ¬ μν΅: μ νν ESLint κ·μΉ λ€μ μ¨κ²¨μ§ κ·Όκ±°λ₯Ό νμ μ λ¬ν©λλ€. μ΄λ λͺ¨λ μ¬λμ΄ νΉμ κ·μΉμ΄ μλ μ΄μ λ₯Ό μ΄ν΄νκ³ μ΄λ₯Ό λ°λ₯΄λλ‘ μ₯λ €νλ λ° λμμ΄ λ©λλ€. νμμ λ°λΌ κ΅μ‘ λ° λ¬Έμλ₯Ό μ 곡ν©λλ€.
- μλνλ μ μ©: pre-commit hook λ° CI ν΅ν©μ μ¬μ©νμ¬ ESLint κ·μΉμ μλμΌλ‘ μ μ©ν©λλ€. μ΄λ λκ° μμ±νλμ§μ κ΄κ³μμ΄ λͺ¨λ μ½λκ° νμ§ νμ€μ μΆ©μ‘±νλμ§ νμΈν©λλ€.
- μ§μν κ³ λ € μ¬ν: νλ‘μ νΈμ μ§μνκ° ν¬ν¨λ κ²½μ° ESLint κ·μΉμ΄ μ§μνλ λ¬Έμμ΄ μ¬μ©μ λ°©ν΄νμ§ μλμ§ νμΈν©λλ€. μλ₯Ό λ€μ΄ νΉμ λ¬Έμ λλ μΈμ½λ© λ°©μμ μ¬μ©μ μ ννλ κ·μΉμ νΌνμμμ€.
- μκ°λ μ°¨μ΄: μλ‘ λ€λ₯Έ μκ°λμ μλ νκ³Ό νμ ν λλ ESLint μλ° μ¬νμ μ¦μ ν΄κ²°νμμμ€. μ΄λ μ½λ νμ§ λ¬Έμ κ° λμ λμ΄ μμ νκΈ°κ° λ μ΄λ €μμ§λ κ²μ λ°©μ§ν©λλ€. κ°λ₯ν κ²½μ° μλ μμ μ΄ λ§€μ° μ μ©ν©λλ€.
μμ : μ§μν λ¬Έμμ΄ μ²λ¦¬
μ ν리μΌμ΄μ
μ΄ μ¬λ¬ μΈμ΄λ₯Ό μ§μνκ³ i18next
μ κ°μ κ΅μ ν(i18n) λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ μ§μνλ λ¬Έμμ΄μ κ΄λ¦¬νλ μλ리μ€λ₯Ό κ³ λ €νμμμ€. μΌλΆ ESLint κ·μΉμ νΉν νΉμ λ¬Έμ λλ ν¬λ§·μ΄ ν¬ν¨λ κ²½μ° μ΄λ¬ν λ¬Έμμ΄μ μ¬μ©λμ§ μμ λ³μ λλ μ ν¨νμ§ μμ ꡬ문μΌλ‘ νλκ·Έ μ§μ ν μ μμ΅λλ€. μ΄λ¬ν κ²½μ°λ₯Ό 무μνλλ‘ ESLintλ₯Ό ꡬμ±ν΄μΌ ν©λλ€.
μλ₯Ό λ€μ΄ μ§μνλ λ¬Έμμ΄μ λ³λμ νμΌ(μ: locales/en.json
)μ μ μ₯νλ κ²½μ° ESLintμ .eslintignore
νμΌμ μ¬μ©νμ¬ μ΄λ¬ν νμΌμ λ¦°ν
μμ μ μΈν μ μμ΅λλ€.
locales/*.json
λλ ESLintμ globals
ꡬμ±μ μ¬μ©νμ¬ μ§μνλ λ¬Έμμ΄μ μ¬μ©λλ λ³μλ₯Ό μ μΈν μ μμ΅λλ€.
module.exports = {
globals: {
'i18n': 'readonly',
't': 'readonly'
}
};
κ²°λ‘
ESLint λ° μ μ λΆμμ μ¬μ©νμ¬ JavaScript μ½λ νμ§μ ν¬μνλ κ²μ νΉν κΈλ‘λ² νκ²½μμ μ μ§λ³΄μκ° μ©μ΄νκ³ κ°λ ₯νλ©° νμ μ μΈ νλ‘μ νΈλ₯Ό ꡬμΆνλ λ° νμμ μ λλ€. μΌκ΄λ μ½λ© μ€νμΌμ ꡬννκ³ , μ€λ₯λ₯Ό μ‘°κΈ°μ κ°μ§νκ³ , μ½λ 리뷰λ₯Ό μλνν¨μΌλ‘μ¨ μ½λλ² μ΄μ€μ μ λ°μ μΈ νμ§μ κ°μ νκ³ κ°λ° νλ‘μΈμ€λ₯Ό κ°μνν μ μμ΅λλ€. νΉμ νλ‘μ νΈ μꡬ μ¬νμ λ§κ² ESLint ꡬμ±μ μ‘°μ νκ³ μ΄ κ°λ ₯ν λꡬμ λͺ¨λ μ΄μ μ μ»κΈ° μν΄ μν¬νλ‘μ μννκ² ν΅ν©νμμμ€. μ΄λ¬ν κ΄νμ μμ©νμ¬ κ°λ° νμ μλμ κ°ννκ³ κΈλ‘λ² μ²μ€μ μꡬλ₯Ό μΆ©μ‘±νλ κ³ νμ§ JavaScript μ ν리μΌμ΄μ μ μ 곡νμμμ€.