๐Ÿ’ป๐Ÿ’€/๊ฐœ๋ฐœ

[ESLint] import/order ๊ทœ์น™ ์„ค์ •ํ•˜๊ณ  ๋’ค์ฃฝ๋ฐ•์ฃฝ import ์ฝ”๋“œ ๊ฐœ์„ ํ•˜๊ธฐ

db2 2022. 8. 7. 23:20

๊ฑฐ์Šฌ๋ฆฌ๋Š” import ์ฝ”๋“œ

๊ทธ๋™์•ˆ ๋‚˜๋ฆ„๋Œ€๋กœ์˜ ๊ทœ์น™์„ ๊ฐ€์ง€๊ณ  import ์ฝ”๋“œ๋ฅผ ์ตœ๋Œ€ํ•œ ๋ณด๊ธฐ ์ข‹๊ฒŒ ์ •๋ฆฌํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“ˆ์ด ํ•œ ๋‘๊ฐœ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งค๋ฒˆ ์ด๋ ‡๊ฒŒ ์ˆ˜์ž‘์—…์œผ๋กœ ์ผ์ผ์ด import ์ˆœ์„œ๋ฅผ ๋งž์ถฐ์ฃผ๋Š” ๊ฒŒ ์—ฌ๊ฐ„ ๊ท€์ฐฎ์€ ์ผ์ด ์•„๋‹ ์ˆ˜ ์—†์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์•„๋ฌด๋ฆฌ ์ž˜ ํ•œ๋‹ค๊ณ  ํ•ด๋„ ๋ชจ๋“  ํŒŒ์ผ์—์„œ ๋™์ผํ•œ ๊ทœ์น™์„ ๋”ฐ๋ฅด๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์•˜๋‹ค. ๋”ฐ๋ผ์„œ ESLint๋กœ ๊ทœ์น™์„ ์ •ํ•˜๊ณ  ๊ฐ•์ œํ™” ํ•˜๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ–ˆ๋‹ค.

์ผ์ผ์ด ์ •๋ฆฌํ–ˆ๋˜ import ์ฝ”๋“œ...๊ท€์ฐฎ์•„...

ESLint์˜ eslint-plugin-import

ESLint๋Š” eslint-plugin-import๋ฅผ ํ†ตํ•ด import/export ๊ตฌ๋ฌธ์˜ ๋ฆฐํŠธ๋ฅผ ์ง€์›ํ•œ๋‹ค. ์ถ”๊ฐ€์ ์œผ๋กœ ๋‚˜๋Š” Webpack๊ณผ TypeScript๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ ˆ๋Œ€ ๊ฒฝ๋กœ(alias)๋ฅผ ์„ค์ •ํ•ด๋†“๊ณ  ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ์ ํŠธ์— eslint-plugin-import์™€ eslint-import-resolver-webpack, eslint-import-resolver-typescript ํŒจํ‚ค์ง€๋“ค์„ ์„ค์น˜ํ–ˆ๋‹ค.

# yarn 
yarn add -D eslint-plugin-import eslint-import-resolver-webpack eslint-import-resolver-typescript

# npm 
npm install --save-dev eslint-plugin-import eslint-import-resolver-webpack eslint-import-resolver-typescript

๊ทธ๋ฆฌ๊ณ  import/resolver ์…‹ํŒ…์„ ์•„๋ž˜์™€ ๊ฐ™์ด ํ–ˆ๋‹ค.

// .eslintrc

{
    "settings": {
        "import/resolver": {
            "webpack": {},
            "typescript": {}
        }
    }
}

import/order ๊ทœ์น™ ์„ค์ •ํ•˜๊ธฐ

์ด์ œ ESLint ๊ทœ์น™์— import/order์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. import/order ๊ทœ์น™์€ import ์ˆœ์„œ์˜ ์ปจ๋ฒค์…˜์„ ์ •ํ•˜๊ณ , ๊ทธ๊ฒƒ์„ ๊ฐ•์ œํ™”ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  --fix ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๊ด„์ ์œผ๋กœ ๋ฃฐ์— ๋งž์ง€ ์•Š๋Š” ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ์— ์ˆ˜์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๊ทธ๋Ÿผ ์ด์ œ ์˜ต์…˜๋“ค์„ ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณด์ž.

groups

  • import ๋˜๋Š” ์ˆœ์„œ๋ฅผ ์ •์˜. ๊ทธ๋ฃน ๋‚ด ๊ฐ ์š”์†Œ์˜ ์ˆœ์„œ์™€ ๋™์ผ
  • ์ƒ๋žต๋œ ๋ฌธ์ž์—ด์€ ๋งˆ์ง€๋ง‰ ์š”์†Œ์™€ ํ•จ๊ป˜ ๊ทธ๋ฃนํ™”
  • ๊ฐ€๋Šฅํ•œ ๊ทธ๋ฃน ๋ฌธ์ž์—ด: builtin, external, internal, unknown, parent, sibling, index, object, type
{
    "groups": [
      "builtin",
      "external",
      "internal",
      // `sibling`, `parent`, `index` ํƒ€์ž…์€ ์ƒ๋Œ€ ๊ฒฝ๋กœ์˜ ํŒŒ์ผ๋กœ๋ถ€ํ„ฐ import ๋˜๋Š” ๋ชจ๋“ˆ์„ ๋œปํ•œ๋‹ค. 
      // ์ฐจ๋ก€๋Œ€๋กœ ํ•˜๋‚˜์˜ ๊ทธ๋ฃน์œผ๋กœ ๋ชจ์•„ import ํ•œ๋‹ค. 
      ["sibling", "parent", "index"],
      "type",
      // ์ƒ๋žต๋œ `object` ํƒ€์ž…๊ณผ ํ•จ๊ป˜ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— import ๋œ๋‹ค. 
      "unknown"
    ],
}

pathGroups

  • ์ถ”๊ฐ€์ ์œผ๋กœ ์˜ต์…˜์„ ์„ค์ •ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ๋กœ๋ฅผ ๋ณ„์นญ๊ณผ ํ•จ๊ป˜ ๋‹ค์‹œ ๊ทธ๋ฃนํ™”
  • ํ”„๋กœํผํ‹ฐ
    • pattern
    • patternOptions
      • minimatch๋ฅผ ์œ„ํ•œ ์˜ต์…˜
      • ๊ธฐ๋ณธ๊ฐ’์€ default: { nocomment: true }
    • group
      • ์ ์šฉ๋  ๊ทธ๋ฃน์˜ ํƒ€์ž…
    • position
      • ์ ์šฉ๋  ๊ทธ๋ฃน์— ๋ฐฐ์น˜๋  ์œ„์น˜
      • after ๋˜๋Š” before
      • ์ƒ๋žตํ•  ๊ฒฝ์šฐ ์•ž, ๋’ค๊ฐ€ ์•„๋‹Œ ๊ทธ๋ฃน๊ณผ ๊ฐ™์ด ๋ฐฐ์น˜๋จ

๋‚˜๋Š” react์™€ ๊ด€๋ จ๋œ ๊ฒฝ๋กœ๋ฅผ external ๊ทธ๋ฃน ์ค‘์—์„œ๋„ ๊ฐ€์žฅ ์œ„์— ๋ฐฐ์น˜ํ•˜๊ณ , ์Šคํƒ€์ผ๊ณผ ๊ด€๋ จ๋œ ํŒŒ์ผ์„ unknown ๊ทธ๋ฃน์œผ๋กœ ์„ค์ •ํ•ด import ์ฝ”๋“œ ๋‚ด์— ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐฐ์น˜ํ•˜๊ณ ์ž ํ–ˆ๋‹ค.

{
    "pathGroups": [
      // react๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ๋กœ๋Š” external ๊ทธ๋ฃน ๋‚ด์—์„œ ๊ฐ€์žฅ ์•ž์— ์œ„์น˜์‹œํ‚จ๋‹ค. 
      {
        "pattern": "{react*,react*/**}",
        "group": "external",
        "position": "before"
      },
      // ์•„๋ž˜๋Š” ์ „๋ถ€ ์Šคํƒ€์ผ ๊ด€๋ จ ํŒŒ์ผ๋“ค์„ unknown ๊ทธ๋ฃน ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. 
      {
        "pattern": "@saas-fe/**/*.style",
        "group": "unknown"
      },
      {
        "pattern": "@pages/**/*.style",
        "group": "unknown"
      },
      {
        "pattern": "@components/**/*.style",
        "group": "unknown"
      },
      {
        "pattern": "./**/*.style",
        "group": "unknown"
      },
      {
        "pattern": "../**/*.style",
        "group": "unknown"
      },
      {
        "pattern": "*.style",
        "group": "unknown"
      }
    ],
}

์ฐธ๊ณ ๋กœ ์Šคํƒ€์ผ ํŒŒ์ผ์˜ pattern ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ {react*,react*/**} ์ฒ˜๋Ÿผ minimatch ํŒจํ„ด์„ ์ ์šฉํ•ด์„œ ์ž‘์„ฑํ•˜๊ณ  ์†Œ์Šค๋ฅผ ์ค„์ด๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ ๋ง˜์ฒ˜๋Ÿผ ๋˜์ง€ ์•Š์•˜๋‹ค. minimatch ํŒจํ„ด์„ ๋‹ค์‹œ ์‚ดํŽด๋ด์•ผ์ง€. (minimatch ํŒจํ„ด์€ ์œ„์˜ ๋งํฌ๋ณด๋‹ค๋Š” ์ด cheat-sheet์„ ์ฐธ๊ณ ํ•˜๋Š” ๊ฑธ ์ถ”์ฒœํ•œ๋‹ค.)

pathGroupsExcludedImportTypes

  • pathGroups์—์„œ ์„ค์ •์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š๋Š” import type์„ ์ •์˜
  • external ๊ทธ๋ฃน์ฒ˜๋Ÿผ ๋ณด์ด๋Š” pathGroups ์˜ต์…˜์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ฃผ๋กœ ํ•„์š”

์‚ฌ์‹ค ์ž˜ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๊ณ  ์“ฐ๊ณ  ์žˆ๋‹ค. ๐Ÿ˜ญ ์œ„์— ์„ค์ •ํ•œ pathGroups ๊ธฐ์ค€์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ ์šฉ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ๋งŒ ์ฐธ๊ณ !

{
    "pathGroupsExcludedImportTypes": ["react", "unknown"],
}

newlines-between

  • ๊ทธ๋ฃน ์‚ฌ์ด์— ์ค„๋ฐ”๊ฟˆ์„ ๊ฐ•์ œํ™” ํ•˜๊ฑฐ๋‚˜ ๊ธˆ์ง€ํ•˜๋Š” ์˜ต์…˜
  • ignore
    • ๊ทธ๋ฃน ๊ฐ„์— ์ค„๋ฐ”๊ฟˆ์ด ์—†์–ด๋„ ์—๋Ÿฌ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
  • always
    • ๊ทธ๋ฃน ๊ฐ„์— ์ตœ์†Œ ํ•œ ์ค„ ์ด์ƒ์˜ ์ค„๋ฐ”๊ฟˆ์ด ๊ฐ•์ œํ™”๋˜๋ฉฐ, ๊ทธ๋ฃน ์•ˆ์—์„œ์˜ ์ค„๋ฐ”๊ฟˆ์€ ๊ธˆ์ง€๋จ
    • ์—ฌ๋Ÿฌ ์ค„์˜ ์ค„๋ฐ”๊ฟˆ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ no-multiple-empty-lines ๊ทœ์น™์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • always-and-inside-groups
    • ๊ทธ๋ฃน ๊ฐ„์— ์ตœ์†Œ ํ•œ ์ค„ ์ด์ƒ์˜ ์ค„๋ฐ”๊ฟˆ์ด ๊ฐ•์ œํ™”๋˜๋ฉฐ, ๊ทธ๋ฃน ์•ˆ์—์„œ์˜ ์ค„๋ฐ”๊ฟˆ๋„ ํ—ˆ์šฉ๋จ
  • never
    • ์ „์ฒด import ์ฝ”๋“œ ๋‚ด์—์„œ ์ค„๋ฐ”๊ฟˆ์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š์Œ

๋‚˜๋Š” ๋นˆ ๋ผ์ธ์œผ๋กœ ๊ทธ๋ฃน ๊ฐ„์— ๊ตฌ๋ถ„์ด ๊ฐ€์‹œ์ ์œผ๋กœ ๋˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๋ฏ€๋กœ always๋ฅผ ์ ์šฉํ–ˆ๋‹ค.

{
    "newlines-between": "always"
}

alphabetize

  • ๊ทธ๋ฃน ๋‚ด์—์„œ ์•ŒํŒŒ๋ฒณ์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ ์ˆœ์„œ๋ฅผ ์„ค์ •
  • ํ”„๋กœํผํ‹ฐ
    • order
      • ๊ธฐ๋ณธ๊ฐ’: ignore
      • ์˜ค๋ฆ„์ฐจ์ˆœ asc ๋˜๋Š” ๋‚ด๋ฆผ์ฐจ์ˆœ desc
    • caseInsensitive
      • ๊ธฐ๋ณธ๊ฐ’: false
      • true
        • ๋Œ€์†Œ๋ฌธ์ž ๋ฌด์‹œ
{
    "alphabetize": {
      "order": "asc",
      "caseInsensitive": true
    },
}

warnOnUnassignedImports

  • ๋“ฑ๋ก๋˜์ง€ ์•Š์€ import์˜ ์ˆœ์„œ๊ฐ€ ์ž˜๋ชป๋์„ ๊ฒฝ์šฐ ๊ฒฝ๊ณ  ๋ฐœ์ƒ ์—ฌ๋ถ€
  • ๊ธฐ๋ณธ๊ฐ’: false
  • true
    • ๊ฒฝ๊ณ  ๋ฐœ์ƒ
    • --fix ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์ž๋™์ ์œผ๋กœ ์ˆ˜์ •๋˜์ง€ ์•Š์Œ

์ตœ์ข… ์„ค์ •

// .eslintrc

{
    "rules": {
        "import/order": [
            "error",
            {
                "groups": [
                    "builtin",
                    "external",
                    "internal",
                    ["sibling", "parent", "index"],
                    "type",
                    "unknown"
                ],
                "pathGroups": [
                    {
                        "pattern": "{react*,react*/**}",
                        "group": "external",
                        "position": "before"
                    },
                    {
                        "pattern": "@saas-fe/**/*.style",
                        "group": "unknown"
                    },
                    {
                        "pattern": "@pages/**/*.style",
                        "group": "unknown"
                    },
                    {
                        "pattern": "@components/**/*.style",
                        "group": "unknown"
                    },
                    {
                        "pattern": "./**/*.style",
                        "group": "unknown"
                    },
                    {
                        "pattern": "../**/*.style",
                        "group": "unknown"
                    },
                    {
                        "pattern": "*.style",
                        "group": "unknown"
                    }
                ],
                "pathGroupsExcludedImportTypes": ["react", "unknown"],
                "newlines-between": "always"
                "alphabetize": {
                    "order": "asc",
                    "caseInsensitive": true
                },

            }
        ],
    }
}

๊ฐœ์„ ๋œ import ์ฝ”๋“œ

์ฒ˜์Œ๋ณด๋‹ค ํ›จ์”ฌ ์ฒด๊ณ„์ ์ด๊ณ  ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌ๋๋‹ค!

์ด์ œ๋Š” ๊ทœ์น™์— ๋งž์ง€ ์•Š์œผ๋ฉด ์ฝ”๋“œ ์ƒ์—์„œ ESLint ์—๋Ÿฌ๊ฐ€ ๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ์ž˜๋ชป๋œ ๋ถ€๋ถ„์„ ๋†“์น˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๊ณ , ์ผ์ผ์ด ๋งž์ถฐ์ค„ ํ•„์š”์—†์ด ์ž๋™์ ์œผ๋กœ ์ˆ˜์ •๋„ ๋œ๋‹ค. ์ตœ๊ณ ๋‹ค. ESLint๋ฅผ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ์ด๋ ‡๊ฒŒ๋‚˜ ๊ฐœ๋ฐœ์˜ ์งˆ์ด ์˜ฌ๋ผ๊ฐ„๋‹ค! ๐Ÿ˜Ž๐Ÿ‘