Home ๐ŸŒ€ Delve into TS environment - eslint, prettier, babel
Post
Cancel

๐ŸŒ€ Delve into TS environment - eslint, prettier, babel

์ด๋ฒˆ์— js ํ”„๋กœ์ ํŠธ๋ฅผ ts๋กœ ๋ฐ”๊พธ๋Š” ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉด์„œ typescript ํ™˜๊ฒฝ์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•ด์ ธ์„œ ์ •๋ฆฌํ•ด ๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค.

ESlint

  • code level์—์„œ ์—๋Ÿฌ๊ฐ€ ๋‚  ๋งŒํ•œ ๋ถ€๋ถ„์„ ์งš์–ด์ค€๋‹ค
  • ๋ฌธ๋ฒ•์˜ค๋ฅ˜์ฒดํฌ, ์ž๋™์™„์„ฑ, formatting ์ง€์›
  • .eslintrc.{js, yml, json} ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ™•์žฅ์ž๋กœ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ js๋กœ ํ•˜๋ฉด ์ฃผ์„ ๋‹ฌ ์ˆ˜ ์žˆ์–ด์„œ ์ข‹์Œ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
module.exports = {
  root: true, //lint๊ฐ€ root:true๋ผ๊ณ  ์ง€์ •ํ•˜๋ฉด ์ด ์œ„์น˜๊นŒ์ง€๋งŒ configuration ํŒŒ์ผ๋“ค์„ ์ฐพ์Œ
  env: { //ํ”„๋กœ์ ํŠธ์˜ ์‚ฌ์šฉ ํ™˜๊ฒฝ์„ ์„ค์ •
    browser: true,
    node: true,
  },
  extends: [
    'eslint:recommended', //eslint์˜ ๊ธฐ๋ณธ ๊ถŒ์žฅํ•˜๋Š” ์˜ต์…˜์œผ๋กœ validation ํ•˜๊ฒ ์Œ
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  ignorePatterns: ["temp.js", "**/vendor/*.js"], //์ด ํŒŒ์ผ๋“ค์€ ๊ฑด๋„ˆ๋œ€
  plugins: ['react', 'prettier', '@typescript-eslint'], //
  rules: {
    'prettier/prettier': [ //prettier ์„ค์ • - eslint-plugin-prettier
      'error', //error level๋กœ ์„ค์ •
      {
        singleQuote: true, //prettier ๊ด€๋ จ ์„ค์ •์€ ์•„๋ž˜์—์„œ ์„ค๋ช…
        semi: true,
        useTabs: false,
        tabWidth: 2,
        printWidth: 80,
        bracketSpacing: true,
        arrowParens: 'avoid',
      },
    ],
  },
  parserOptions: {
    parser: '@typescript-eslint/parser', //tsํŒŒ์ผ์„ ํŒŒ์‹ฑํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ parser๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค.
  },
};

(1) extends ์˜ต์…˜:

  • ์ƒ์†๋ฐ›์„ ๋ชจ๋“  ํŒŒ์ผ configuration file์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ
  • ์—ฌ๋Ÿฌ ๊ฐœ๋Š” arrayํ˜•์‹์œผ๋กœ ์ ์œผ๋ฉด ๋Œ
  • extends์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋”ฐ๋ฅผ ํ˜•์‹์„ ์ •ํ•ด๋†“๊ณ , ์ดํ›„์— โ€˜rulesโ€™ option์—์„œ override ํ•  ์ˆ˜ ์žˆ์Œ
  • eslint/recommended, eslint:all ์ด ์žˆ๋Š”๋ฐ ํ›„์ž๋Š” ์ž˜ ์“ฐ์ง€ ์•Š์Œ(์•ˆ ์“ฐ๋Š”๊ฒŒ ์•ˆ์ „ํ•จ)
  • eslint-config prefix๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Œ
    1
    2
    3
    
      // example
      extends: ['eslint-config-airbnb', 'eslint-config-standard'] 
      extends: ['airbnb', 'standard']//์œ„์™€ ๋™์ผํ•จ
    

    (2) rules ์˜ต์…˜:

  • ๊ทœ์น™๋“ค์„ override(๋˜๋Š” ํ™•์žฅ) ํ•  ์ˆ˜ ์žˆ์Œ
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
      "rules": {
        // enable additional rules
        "indent": ["error", 4], // indent 4
        "linebreak-style": ["error", "unix"],
        "quotes": ["error", "double"], //double quote๋ฉด error๋กœ
        "semi": ["error", "always"], //semi colon ํ•ญ์ƒ - ์—†์œผ๋ฉด error
    
        // override configuration set by extending "eslint:recommended"
        "no-empty": "warn",
        "no-cond-assign": ["error", "always"],
    
        // disable rules from base configurations
         "for-direction": "off",
    }
    

    ์•„๋ž˜์ฒ˜๋Ÿผ ๊ฐ์ฒดํ˜•์‹์œผ๋กœ ์ ์–ด๋„ ๋Œ. array์˜ ์ฒซ ๋ฒˆ์งธ ์›์†Œ๋Š” โ€˜errorโ€™์ฒ˜๋Ÿผ ์ ์–ด๋„ ๋˜์ง€๋งŒ ์ˆซ์ž๋กœ ์ ์–ด๋„ ๋Œ.
    0=off, 1=warn, 2=error

    1
    2
    
      "max-lines": ["error", { "max": 100 }]
      "react/jsx-filename-extension": [2, { "extensions": [".jsx", ".tsx"] }],
    

(3) plugin ์˜ต์…˜:

  • eslint์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ npm package
  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ eslint-plugin- prefix๋ฅผ ์•ž์— ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Œ ( react === eslint-plugin-react)

๊ทธ ์™ธ์— ๊ต‰์žฅํžˆ ๋งŽ์€ rule ๋“ค์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ํ™ˆํŽ˜์ด์ง€ ์ฐธ๊ณ .

๊ทธ๋ฆฌ๊ณ  prettier์™€ ํ•จ๊ป˜ ์“ฐ๋ฉด eslint ์ž์ฒด์—์„œ๋„ formattingํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— conflict๊ฐ€ ์ƒ๊ธด๋‹ค. ๋”ฐ๋ผ์„œ plugin๋“ค์„ ์„ค์น˜ํ•ด์„œ eslint์˜ formatting์„ disableํ•ด์ฃผ๊ณ , prettier์—๊ฒŒ ๋ชจ๋“  formatting์„ ์ผ์ž„ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

  • eslint-config-prettier: eslint์˜ prettier์™€ ์ถฉ๋Œ๋‚˜๋Š” formatting ๋น„ํ™œ์„ฑํ™”
  • eslint-plugin-prettier: prettier๋ฅผ eslint์— plugin์œผ๋กœ ์ถ”๊ฐ€ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ

์ถ”๊ฐ€๋กœ prettier ๊ณต์‹ document์—์„œ๋Š” eslint-plugin-prettier ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ generally not recommended๋ผ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ ์จ์žˆ๊ธด ํ•˜๋‹ค.

1
2
- ์ง์ ‘์ ์œผ๋กœ prettier์„ ๋Œ๋ ธ์„ ๋•Œ๋ณด๋‹ค ๋А๋ฆฌ๋‹ค
- ์—๋Ÿฌ ๋ผ์ธ์ด ๋„ˆ๋ฌด ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ๋‹ค(?)

Prettier

๋ณดํ†ต .prettierrc ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋˜์ง€๋งŒ, eslint์— plugin ๊น”์•„์„œ ๊ฑฐ๊ธฐ์„œ ์„ค์ •ํ•ด์ค˜๋„ ๋œ๋‹ค.

  • ํŒ€ ๋‹จ์œ„ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜์„ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋„๊ตฌ
  • ๋ณดํ†ต ์ด์ •๋„ ์…‹ํŒ…ํ•ด๋‘๊ณ , ํŒ€์—์„œ ํ˜‘์˜ํ•ด์„œ ์ถ”๊ฐ€/์‚ญ์ œํ•˜๋ฉด ๋œ๋‹ค
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    {
      "singleQuote": true, // ๋ฌธ์ž์—ด์€ ๋”ฐ์˜ดํ‘œ๋กœ formatting
      "semi": true, //์ฝ”๋“œ ๋งˆ์ง€๋ง‰์— ์„ธ๋ฏธ์ฝœ๋ฅธ์ด ์žˆ๊ฒŒ formatting
      "useTabs": false, //ํƒญ์˜ ์‚ฌ์šฉ์„ ๊ธˆํ•˜๊ณ  ์ŠคํŽ˜์ด์Šค๋ฐ” ์‚ฌ์šฉ์œผ๋กœ ๋Œ€์ฒดํ•˜๊ฒŒ formatting
      "tabWidth": 2, // ๋“ค์—ฌ์“ฐ๊ธฐ ๋„ˆ๋น„๋Š” 2์นธ
      "trailingComma": 'all', // ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด ํ‚ค:๊ฐ’ ๋’ค์— ํ•ญ์ƒ ์ฝค๋งˆ๋ฅผ ๋ถ™ํžˆ๋„๋ก formatting
      "printWidth": 120, // ์ฝ”๋“œ ํ•œ์ค„์ด maximum 120์นธ
      "arrowParens": 'avoid', // ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ํ•˜๋‚˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์„ ๋•Œ ๊ด„ํ˜ธ๋ฅผ ์ƒ๋žตํ•˜๊ฒŒ formatting
    }
    

Babel

  • javascript compiler(์ตœ์‹  js ๋ฌธ๋ฒ•์ด ์ตœ๋Œ€ํ•œ ๋งŽ์€ ๋ธŒ๋ผ์šฐ์ €์— ํ˜ธํ™˜๋  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ”๊ฟ”์ฃผ๋Š” ๋„๊ตฌ)

reference

Eslint configuration doc
TS๊ฐ•์˜ - section.5 ํ”Œ์  ํ™˜๊ฒฝ ๊ตฌ์„ฑ
ESLint, Prettier ์ ์šฉํ•˜๊ธฐ

This post is licensed under CC BY 4.0 by the author.

๊ธฐ๋ณธ๊ณผ ๋ณธ์งˆ

-