๐Ÿ•บ ESLint ์ปค์Šคํ…€ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋งŒ๋“ค๊ณ  ๋ฐฐํฌํ•˜๊ธฐ

2025. 10. 29. 00:06ยท๐Ÿ‘€ ํ”„๋กœ์ ํŠธ ๋ฐ ํ™œ๋™/๊ฐœ์ธ ํ”„๋กœ์ ํŠธ

ESLint ์„ค์ • ์ค‘์— 'arrow-body-style': ['error', 'always']๋ผ๋Š” ๊ทœ์น™์ด ์žˆ๋‹ค.

์ด ์„ค์ •์„ ์ผœ๋ฉด ๋ชจ๋“  ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ ํ•ญ์ƒ ์ค‘๊ด„ํ˜ธ({})์™€ return ๋ฌธ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

์•„๋ž˜์ฒ˜๋Ÿผ ํ•œ์ค„๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ์—๋Š” return์ด ์žˆ์–ด๋„ ๋ณด๊ธฐ ์ข‹์ง€๋งŒ,

setErrors((prev) => {
  const errorMsg = validators[name] ? validators[name](value, values) : '';
  return { ...prev, [name]: errorMsg };
});

์•„๋ž˜ ์ผ€์ด์Šค์ฒ˜๋Ÿผ ํ•œ ์ค„๋กœ ํ‘œํ˜„์ด ์ถฉ๋ถ„ํžˆ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์—๋„ return์ด ์ถ”๊ฐ€๋˜์–ด ์•„์‰ฌ์› ๋‹ค.

const handlePasswordToggle = () => {
    setShowPassword((prev) => {
      return !prev;
    });
  };

๊ทผ๋ฐ ๋˜ ํ•œ ์ค„๋กœ ํ‘œํ˜„๊ฐ€๋Šฅํ•˜๋”๋ผ๋„ JSX๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” return ํ‚ค์›Œ๋“œ๋ฅผ ๊ผญ ๋„ฃ๊ณ  ์‹ถ์—ˆ๋‹ค.

const page = () => {
  return <>ํŽ˜์ด์ง€~</>
}

์ง€๊ทนํžˆ ๊ฐœ์ธ ์ทจํ–ฅ์ด์ง€๋งŒ...๐Ÿ™ƒ 'arrow-body-style' ์„ค์ •๋งŒ์œผ๋กœ๋Š”

๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๋™์ž‘์„ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ปจํŠธ๋กคํ•˜๊ธฐ ์–ด๋ ค์› ๋‹ค.

 

๊ทธ๋ž˜์„œ ๋ฉ˜ํ† ๋‹˜์˜ ์กฐ์–ธ์— ํž˜์ž…์–ด ์ง์ ‘ ์ปค์Šคํ…€ ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋งŒ๋“ค์–ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค. (๋ƒ…๋‹ค ๋„์ „~~!)

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ œ์ž‘ ๊ณผ์ •๊ณผ ๊ฐ„๋‹จํ•œ ํ›„๊ธฐ๊นŒ์ง€ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

โš™๏ธ ์ œ์ž‘ ๊ณผ์ •

1๏ธโƒฃ module.exports

module.exports = {
  meta: { ... },
  create(context) { ... }
};

ESLint ๋ฃฐ์„ ์ •์˜ํ•  ๋•Œ๋Š” ๊ฐ์ฒด๋ฅผ ๋‚ด๋ณด๋‚ด์•ผ ํ•œ๋‹ค.

์ด ๊ฐ์ฒด๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€ ํ•ต์‹ฌ ์†์„ฑ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

  1. meta → ๋ฃฐ์˜ ๋ฉ”ํƒ€์ •๋ณด (๋ฌธ์„œ, ๋ฉ”์‹œ์ง€, ์ˆ˜์ • ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ๋“ฑ)
  2. create → ์‹ค์ œ AST๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ฝ”๋“œ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ํ•จ์ˆ˜

 

2๏ธโƒฃ meta ๊ฐ์ฒด

meta: {
    type: "suggestion",
    docs: {
      description: "์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ ์ค‘๊ด„ํ˜ธ ์‚ฌ์šฉ, ์ผ๋ฐ˜ ํ•จ์ˆ˜๋Š” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ",
      category: "Stylistic Issues",
      recommended: false,
    },
    fixable: "code",
    schema: [],
    messages: {
      unexpectedBraces:
        "๊ฐ„๋‹จํ•œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—๋Š” ์ค‘๊ด„ํ˜ธ์™€ return์„ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”",
      expectedBraces: "์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜์—๋Š” ์ค‘๊ด„ํ˜ธ์™€ return์„ ์‚ฌ์šฉํ•˜์„ธ์š”",
    },
  },

type: "suggestion" → ์ฝ”๋“œ ์Šคํƒ€์ผ๊ณผ ๊ด€๋ จ๋œ ๊ถŒ์žฅ์‚ฌํ•ญ์„ ์ œ์‹œํ•˜๋Š” ๋ฃฐ์ด๋‹ค.

  • "problem": ์ฝ”๋“œ ์˜ค๋ฅ˜/๋ฒ„๊ทธ๋ฅผ ์ฐพ๋Š” ๋ฃฐ
  • "suggestion": ์ฝ”๋“œ ์Šคํƒ€์ผ์ด๋‚˜ ๊ถŒ์žฅ ์‚ฌํ•ญ
  • "layout": ๋“ค์—ฌ์“ฐ๊ธฐ, ๊ณต๋ฐฑ ๋“ฑ ํฌ๋งท ๊ด€๋ จ

docs → ESLint ๋ฌธ์„œ์— ํ‘œ์‹œ๋  ์„ค๋ช…๊ณผ ์นดํ…Œ๊ณ ๋ฆฌ ์ •๋ณด์ด๋‹ค.

fixable: "code" → ESLint --fix ๋ช…๋ น์œผ๋กœ ์ž๋™ ์ˆ˜์ • ๊ฐ€๋Šฅํ•จ์„ ์˜๋ฏธํ•œ๋‹ค.

  • "code": ์ฝ”๋“œ ์ˆ˜์ • ๊ฐ€๋Šฅ
  • "whitespace": ๊ณต๋ฐฑ/ํฌ๋งท๋งŒ ์ˆ˜์ • ๊ฐ€๋Šฅ

messages → ESLint๊ฐ€ ๊ฒฝ๊ณ /์—๋Ÿฌ๋ฅผ ํ‘œ์‹œํ•  ๋•Œ ์‚ฌ์šฉํ•  ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก์ด๋‹ค.

 

3๏ธโƒฃ create(context) ํ•จ์ˆ˜

create ํ•จ์ˆ˜๋Š” ESLint๊ฐ€ AST๋ฅผ ์ˆœํšŒํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•ต์‹ฌ ๋ถ€๋ถ„์ด๋‹ค.

context ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ์œ„์น˜ ์ •๋ณด, ๊ฒฝ๊ณ  ๋ณด๊ณ , ์ž๋™ ์ˆ˜์ • ๋“ฑ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ๋Š” AST ๋…ธ๋“œ ํƒ€์ž…๋ณ„ ์ฝœ๋ฐฑ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

return {
  ArrowFunctionExpression(node) {
    ...
  }
};

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ์—์„œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ๋ฐœ๊ฒฌ๋  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋œ๋‹ค.

 

4๏ธโƒฃ isComponentFunction(node)

React ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ ํ—ฌํผ ํ•จ์ˆ˜์ด๋‹ค.

๋‘ ๊ฐ€์ง€ ๊ธฐ์ค€์œผ๋กœ ํŒ๋ณ„ํ–ˆ๋‹ค.

โœ… 1. ํ•จ์ˆ˜ ์ด๋ฆ„์ด ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜๋Š”๊ฐ€?

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ต๋ช… ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์—,

๋ถ€๋ชจ ๋…ธ๋“œ(VariableDeclarator)์˜ id.name์„ ํ†ตํ•ด ์ด๋ฆ„์„ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

→ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ต๋ช… ํ•จ์ˆ˜์—ฌ์„œ id๊ฐ’์ด null

const parent = node.parent;
  if (parent.type === "VariableDeclarator" && parent.id && parent.id.name) {
    if (/^[A-Z]/.test(parent.id.name)) {
      return true;
    }
}

// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ AST ํŠธ๋ฆฌ๊ฐ€ ๊ทธ๋ ค์ง
"declarations": [
  {
    "type": "VariableDeclarator", // ๋ณ€์ˆ˜ ์„ ์–ธ ๋ถ€๋ถ„์— ํ•ด๋‹นํ•จ
    "start": 6,
    "end": 53,
    "id": {
      "type": "Identifier",
      "start": 6,
      "end": 12,
      "name": "Button"
    },
...
]

โœ… 2. JSX๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฐ€?

ํ•จ์ˆ˜ ์ด๋ฆ„์ด ํŒŒ์Šค์นผ ์ผ€์ด์Šค๊ฐ€ ์•„๋‹ˆ๋”๋ผ๋„ JSX๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ„์ฃผํ–ˆ๋‹ค.

if (node.body.type === "JSXElement" || node.body.type === "JSXFragment") {
  return true;
}

// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ์˜ˆ์ œ
const Button1 = () => <>ํ•˜์ด</>
const Button2 = () => <button>ํ•˜์ด</button>

// AST ์˜ˆ์‹œ
{
  "type": "ArrowFunctionExpression",
  "id": null,
  "body": {
      "type": "JSXFragment", // <></>์ผ ๊ฒฝ์šฐ JSXFragment
     }
}

๋ธ”๋ก๋ฌธ ์•ˆ์—์„œ JSX๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์ฒ˜๋ฆฌํ–ˆ๋‹ค.

if (node.body.type === "BlockStatement") {
  const returnStatements = node.body.body.filter(
    (stmt) => stmt.type === "ReturnStatement"
  );
  return returnStatements.some(
    (stmt) =>
      stmt.argument &&
      (stmt.argument.type === "JSXElement" ||
        stmt.argument.type === "JSXFragment")
  );
}

// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ์˜ˆ์ œ
const List = ({loading}) => {
  if (loading) {
    return <div>๋กœ๋”ฉ์ค‘...</div>
  }

  return (
    <ul>
      <li>๋ฆฌ์ŠคํŠธ</li>
    </ul>
  )
}

// AST ์˜ˆ์‹œ (์ถ•์•ฝ)
"body": {
  "type": "BlockStatement",
  "start": 28,
  "end": 137,
  "body": [
    "consequent": {
      "type": "BlockStatement",
      "start": 45,
      "end": 79,
      "body": [
        {
          "type": "ReturnStatement",
          "argument": {
            "type": "JSXElement",
  },
  {
    "type": "ReturnStatement",
    ....

 

5๏ธโƒฃ isSingleReturn(node)

ํ•œ ์ค„๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅํ•œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์ธ์ง€ ํŒ๋‹จํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

function isSingleReturn(node) {
  // ์ฒซ ๋ฒˆ์งธ ์กฐ๊ฑด: body์˜ type์ด Block๋ฌธ์ด ์•„๋‹ˆ๋ฉด ์ด๋ฏธ ํ•œ ์ค„์ด๋ผ์„œ true๋ฅผ ๋ฆฌํ„ด
  if (node.body.type !== "BlockStatement") {
    return true;
  }

    // block๋ฌธ์ด ์žˆ์„๋•Œ body์˜ length๊ฐ€ 1์ด ์•„๋‹ˆ๋ฉด ํ•œ ์ค„๋กœ ํ‘œํ˜„ํ•˜์ง€ ๋ชปํ•˜๋„๋ก false๋ฅผ ๋ฆฌํ„ด
  const [statement] = node.body.body;
  if (!statement || node.body.body.length !== 1) {
    return false;
  }

    // block๋ฌธ์ด ์žˆ์„ ๋•Œ ๊ทธ ํƒ€์ž…์ด ๋ฆฌํ„ด์ด๊ณ  argument๊ฐ€ ์žˆ๋‹ค๋ฉด ํ•œ ์ค„๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅ
  return statement.type === "ReturnStatement" && statement.argument;
}

 

6๏ธโƒฃ return {ArrowFunctionExpression}

ESLint๋Š” ๋ฐฉ๋ฌธ์ž(Visitor) ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด์„œ ๊ทœ์น™์„ ๊ฒ€์‚ฌํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ArrowFunctionExpression๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋งŒ ๊ฒ€์‚ฌํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.

return {
  ArrowFunctionExpression(node) {
    ...
};

์ด ๊ตฌ๋ฌธ์— fixํ•จ์ˆ˜๋„ ์ถ”๊ฐ€ํ•ด์„œ --fix ์˜ต์…˜์œผ๋กœ ์ž๋™ ์ˆ˜์ • ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.

 

๐Ÿš€ NPM ๋ฐฐํฌ

npm publish

์™„์„ฑํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ npm์— ๋ฐฐํฌํ–ˆ๋‹ค.

๐Ÿ‘‰ eslint-plugin-component-arrow-style

 

์ฒ˜์Œ์— ๋‹ค ๋งŒ๋“ค์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ  ๋ฌด์ž‘์ • ๋ฐฐํฌ๋ฅผ ํ•ด๋ฒ„๋ ธ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ฒซ ๋ฐฐํฌํ•˜๊ณ  ํ™•์ธํ•ด๋ณด๋‹ˆ README ๋ฌธ์„œ๊ฐ€ ์—†์–ด์„œ ๋‹ค์‹œ ๋ฐฐํฌํ–ˆ๋‹ค...

๋ฐฐํฌ๋ฅผ ํ•˜๋ ค๋ฉด ๋งค๋ฒˆ ๋ฒ„์ „์„ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด์ค˜์•ผ ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ชฐ๋ผ์„œ

๋ฒ„์ „ ์—…๋ฐ์ดํŠธ ๋ช…๋ น์–ด๋ฅผ ์‹ค์ˆ˜๋กœ ์ž…๋ ฅํ–ˆ๋‹ค๊ฐ€ 1.0.1 ๋ฒ„์ „์„ ๋‚ ๋ฆฌ๊ณ …๐Ÿซ 

์–ด์ฐŒ์ €์ฐŒ ๋ฆฌ๋“œ๋ฏธ ๋ฌธ์„œ๋ฅผ ์ถ”๊ฐ€ํ•œ 1.0.2 ๋ฒ„์ „์„ ์—…๋ฐ์ดํŠธ ํ–ˆ๋‹ค.

 

๐Ÿž ๋ฒ„๊ทธ ๋ฐœ๊ฒฌ

๋ช‡ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฐฐํฌ ์ „์— ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ดค์ง€๋งŒ,

์‹ค์ œ ์‚ฌ์šฉํ•ด๋ณด๋‹ˆ ๋‚ด๊ฐ€ ๊ณ ๋ คํ•˜์ง€ ๋ชป ํ–ˆ๋˜ ์ผ€์ด์Šค๊ฐ€ ์žˆ์—ˆ๋‹ค….๐Ÿ™ƒ

์ง€๊ธˆ๊นŒ์ง€ ๋ฐœ๊ฒฌํ•œ ๋ฒ„๊ทธ๋Š” ๋‘ ๊ฐ€์ง€์ด๋‹ค.

1๏ธโƒฃ ๊ฐ์ฒด ๋ฆฌํ„ด ์‹œ ๊ด„ํ˜ธ ๋ˆ„๋ฝ ๋ฌธ์ œ

// ์›๋ž˜ ์ฝ”๋“œ -> ์ด๋ ‡๊ฒŒ ์ˆ˜์ •๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ...
setValues((prev) => ({ ...prev, [name]: value }));

// ์ž˜๋ชป ์ˆ˜์ •๋œ ๊ฒฐ๊ณผ ๐Ÿคฏ
setValues((prev) => { ...prev, [name]: value });

fix ํ•จ์ˆ˜์—์„œ ๊ฐ์ฒด ๋ฆฌํ„ด์„ ๊ณ ๋ คํ•˜์ง€ ๋ชป ํ–ˆ๊ณ ,

์ด๋กœ ์ธํ•ด --fix๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์ž˜๋ชป ์ˆ˜์ •๋˜์–ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค. ๐Ÿคฏ

 

2๏ธโƒฃ map()์—์„œ JSX ๋ฆฌํ„ด ์‹œ ์ฝ”๋“œ ๊นจ์ง

map() ๋‚ด๋ถ€์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌํ„ดํ•  ๋•Œ,

fix๊ฐ€ ์ ์šฉ๋˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋น„์ •์ƒ์ ์œผ๋กœ ์ˆ˜์ •๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.

์ด ๋ถ€๋ถ„๋„ 1๋ฒˆ๊ณผ ๋™์ผํ•˜๊ฒŒ fix ๋กœ์ง์„ ์ˆ˜์ •ํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค.

๋˜ ๋ง‰์ƒ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด๋‹ˆ,

map() ๋‚ด๋ถ€์—์„œ๋Š” return์„ ์ œ๊ฑฐํ•˜๋Š”๊ฒŒ ์ข€ ๋” ๊น”๋”ํ•ด๋ณด์—ฌ์„œ

์ด ๋ถ€๋ถ„์„ ์ถ”๊ฐ€ํ• ์ง€ ๊ณ ๋ฏผ ์ค‘์ด๋‹ค.

 

๐Ÿ’ญ ๋งˆ๋ฌด๋ฆฌ

์ฒ˜์Œ์—๋Š” ์–ด๋–ป๊ฒŒ ์‹œ์ž‘ํ•ด์•ผ ํ• ์ง€ ๋ชฐ๋ผ์„œ ๊ฐ์„ ์žก๊ธฐ ์–ด๋ ค์› ์ง€๋งŒ,

์ฐจ๊ทผ์ฐจ๊ทผ ์ฐพ์•„๋ณด๋ฉฐ ์ง์ ‘ ๋งŒ๋“ค์–ด๋ณด๋‹ˆ ์ƒ๊ฐ๋ณด๋‹ค ์žฌ๋ฐŒ์—ˆ๋‹ค.

 

ํŠนํžˆ JS ์ฝ”๋“œ๊ฐ€ AST๋กœ ๋ณ€ํ™˜๋œ๋‹ค๋Š” ๋ง์„ ๋งŽ์ด ๋“ค์–ด์™”๋Š”๋ฐ,

์ด๋ฒˆ์— AST ๊ตฌ์กฐ๋ฅผ ์ ์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋‹ˆ ์ข€ ๋” ์ดํ•ดํ•˜๊ธฐ ์ˆ˜์›”ํ•ด์ง„ ๊ฒƒ ๊ฐ™๋‹ค.

 

๋˜, ์ด๋ฒˆ ๊ฒฝํ—˜์„ ํ†ตํ•ด ํŒ€ ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ESLint๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ํ›จ์”ฌ ํšจ์œจ์ ์ด๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

๋งค๋ฒˆ ๊ทœ์น™์„ ๊ธฐ์–ตํ•˜๊ธฐ๋ณด๋‹ค๋Š” --fix๋‚˜ ์ €์žฅ์œผ๋กœ ํ•œ ๋ฒˆ์— ์ •๋ฆฌ๋œ๋‹ค๋ฉด ํŽธํ•  ๊ฒƒ ๊ฐ™๋‹ค.

 

์•„๋ฌดํŠผ ์ด๋ฒˆ ๊ธฐํšŒ์— ๋งŒ๋“ค์–ด๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ์žฌ๋ฐŒ์—ˆ๋‹ค. ๐Ÿ•บ

 

๐Ÿ“š ์ฐธ๊ณ 

https://eslint.org/docs/latest/extend/custom-rules

 

Custom Rules - ESLint - Pluggable JavaScript Linter

A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease.

eslint.org

https://astexplorer.net/

 

AST explorer

 

astexplorer.net

https://blog.eunsukim.me/posts/about-javascript-abstract-syntax-tree-and-eslint-rules

 

TIL - AST(Abstract Syntax Tree)์™€ ESLint Rules

Today I learned - Abstract Syntax Tree์™€ ESLint Rules์— ๊ด€ํ•˜์—ฌ

blog.eunsukim.me

https://fantasmith.com/challenge/opensource/fsd_lint/

 

FSD๋ฅผ ์œ„ํ•œ ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐœ๋ฐœ ์ผ์ง€ | Zen's Atelier

FSD ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ, ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐ ๋ถˆํŽธํ•จ์„ ๋А๊ผˆ๋‹ค. ์ œ๋Œ€๋กœ๋œ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์กด์žฌํ•˜์ง€ ์•Š์•˜๊ณ , ๊ฐœ๋ฐœ์„ ํŽธํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ESLint ๋ชจ๋“ˆ์„ ๋งŒ๋“ค์–ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

fantasmith.com

 

728x90
'๐Ÿ‘€ ํ”„๋กœ์ ํŠธ ๋ฐ ํ™œ๋™/๊ฐœ์ธ ํ”„๋กœ์ ํŠธ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [ChromeExtension] ํ™์ต๋Œ€ ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ € ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ ๋งŒ๋“ค๊ธฐ
_์ด์•Ž
_์ด์•Ž
๊ณต๋ถ€ ๊ธฐ๋ก ๋ธ”๋กœ๊ทธ
  • _์ด์•Ž
    ๊ณต๋ถ€
    _์ด์•Ž
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • โœ๏ธ ๋ชจ๋“  ๊ธ€ (75) N
      • ๐Ÿ“š ํ”„๋ก ํŠธ์—”๋“œ (48) N
        • Web (4) N
        • React (13)
        • Next.js (2)
        • JavaScript (13)
        • TypeScript (2)
        • Dev Setup (1) N
        • git+github (4)
        • HTML+CSS (9)
      • ๐Ÿ‘€ ํ”„๋กœ์ ํŠธ ๋ฐ ํ™œ๋™ (20)
        • ์ฝ”๋“œ์ž‡ ์Šคํ”„๋ฆฐํŠธ 19๊ธฐ (18)
        • ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ (2)
      • ๐Ÿ“ ์ž๋ฃŒ ์ •๋ฆฌ (3) N
        • React ๊ณต์‹๋ฌธ์„œ (3) N
      • โš™๏ธ etc. (4)
  • ๋งํฌ

    • ๐Ÿ‘‹ GitHub
    • ๐Ÿง ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ๊ธฐ๋ก
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ์ธ๊ธฐ ๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.4
_์ด์•Ž
๐Ÿ•บ ESLint ์ปค์Šคํ…€ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋งŒ๋“ค๊ณ  ๋ฐฐํฌํ•˜๊ธฐ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”