Custom ESLint Plugin 만들기

장유진·2024년 2월 28일
2

ESLint

목록 보기
1/2
post-thumbnail

ESLint 공식문서에서 제공하는 Custom Rule Tutorial을 따라 custom plugin을 만들어보았다.

1) npm 프로젝트 만들기

eslint-plugin-yujijang 이라는 이름의 npm 프로젝트를 생성해주었다.

$ cd eslint-plugin-yujijang
$ npm init -y
$ npm install eslint --save-dev

2) Custom Rule 만들기

foo라는 이름의 const 변수는 반드시 “bar”라는 값을 가져야 한다는 enforce-foo-bar 규칙을 만들고자 한다.

rules 디렉토리 아래에 enforce-foo-bar.js라는 파일을 생성한 후, 다음와 같이 코드를 작성해준다.


module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description:
        "Enforce that a variable named `foo` can only be assigned a value of 'bar'.",
    },
    fixable: 'code',
    schema: [],
  },
  create(context) {
    return {
      VariableDeclarator(node) {
        if (node.parent.kind === 'const') {
          if (node.id.type === 'Identifier' && node.id.name === 'foo') {
            if (
              node.init &&
              node.init.type === 'Literal' &&
              node.init.value !== 'bar'
            ) {
              context.report({
                node,
                message:
                  'Value other than "bar" assigned to `const foo`. Unexpected value: {{ notBar }}.',
                data: {
                  notBar: node.init.value,
                },
                fix(fixer) {
                  return fixer.replaceText(node.init, '"bar"');
                },
              });
            }
          }
        }
      },
    };
  },
};

3) 테스트 코드 작성하기

enforce-foo-bar가 정상적으로 동작하는지 확인하는 테스트 코드를 작성한다.

tests 폴더 아래에 enforce-foo-bar.test.js 파일을 생성한 후, 다음와 같이 코드를 작성한다.

const { RuleTester } = require("eslint");
const fooBarRule = require("../rules/enforce-foo-bar.js");
 
const ruleTester = new RuleTester({
  parserOptions: { ecmaVersion: 2015 },
});
 
ruleTester.run("enforce-foo-bar", fooBarRule, {
  valid: [
    {
      code: "const foo = 'bar';",
    },
  ],
  invalid: [
    {
      code: "const foo = 'baz';",
      output: 'const foo = "bar";',
      errors: 1,
    },
  ],
});
 
console.log("All tests passed!");

다음 커멘드를 통해 테스트를 실행하면

$ node tests/enforce-foo-bar.test.js

이런 결과가 나온다.

4) 작성한 rule을 plugin에 넣기

index.js 파일을 생성한 후, 다음과 같이 코드를 작성한다.

const enforceFooBar = require("./rules/enforce-foo-bar.js");
 
module.exports = { rules: { "enforce-foo-bar": enforceFooBar } };

5) 작성한 plugin을 local에서 사용하기

❗️이 방법은 eslint 8.23.0 이상의 eslint.config.js에서만 사용 가능하다.❗️

ESLint v8.21.0에서 새로운 config 시스템이 도입되어 .eslintrc 대신 eslint.config.js 파일을 사용할 수 있게 되었다. 또한 v8.23.0부터는 ESLint CLI에서 eslint.config.js를 사용할 수 있게 되었다. v8에서는 기존의 .eslintrc가 여전히 지원되지만 v9부터는 지원되지 않고 eslint.config.js만 사용 가능하다. (참고)

custom plugin을 npm에 배포하기 전에 사용해보고 싶거나, custom plugin을 npm에 배포하고 싶지 않을 경우에 eslint.config.js 파일에 다음과 같은 설정을 적용해 local에 작성된 custom plugin을 사용할 수 있다.

const eslintPluginYujijang = require("./eslint-plugin-yujijang");
 
module.exports = [
    {
        files: ["**/*.js"],
        languageOptions: {
            sourceType: "commonjs",
            ecmaVersion: "latest",
        },
        // Using the eslint-plugin-example plugin defined locally
        plugins: {"yujijang": eslintPluginYujijang},
        rules: {
            "example/enforce-foo-bar": "error",
        },
    }
]

6) Custom plugin publish

아주 간단한 과정을 통해 npm에 내 플러그인을 배포할 수 있다.
우선 package.json에 다음과 같은 설정을 해준다.

{
  "name": "eslint-plugin-yujijang",
  "version": "1.0.0",
  "description": "Eslint custom rulel made by yujijang",
  "main": "index.js",
  "scripts": {
    "test": "node tests/enforce-foo-bar.test.js"
  },
  "peerDependencies": {
    "eslint": ">=7.0.0"
  },
  "keywords": [
    "eslint",
    "eslintplugin",
    "eslint-plugin"
  ],
  "author": "yujijang",
  "license": "ISC",
  "devDependencies": {
    "eslint": "^7.32.0"
  }
}

https://www.npmjs.com/ 에서 회원가입을 진행해준 후, 터미널에 아래 커맨드를 입력하여 배포를 완료한다.

$ npm adduser // 회원가입한 정보 입력
$ npm publish

7) 배포한 custom plugin 사용하기

사용하고자 하는 프로젝트에서 custom plugin을 설치해준다.

$ yarn add -D eslint-plugin-yujijang

eslint 설정 파일(.eslintrc 또는 eslint.config.js)을 작성한다.

module.exports = {
    ...
    plugins: ['yujijang'],
    rules: {
        ...
        'yujijang/enforce-foo-bar': 'error',
    }
    ...
}

이제 최종적으로 내가 설정한 eslint custom rule이 적용된 것을 볼 수 있다.

8) plugin에 recommended config 추가하기

앞에서 만든 eslint-plugin-yujijang의 index.js에 recommended config를 추가할 수 있다.

를 참고하여 작성해보았다.

index.js에 다음과 같이 config를 작성하면 된다.

const enforceFooBar = require("./rules/enforce-foo-bar.js");
 
module.exports = {
  configs: {
    recommended: {
      plugins: ["yujijang"],
      rules: {
        "yujijang/enforce-foo-bar": "error",
      },
    },
  },
  rules: { "enforce-foo-bar": enforceFooBar },
};

이 recommended config를 사용하기 위해서는 eslint 설정 파일(.eslintrc 또는 eslint.config.js)의 extends에 "plugin: yujijang/recommended"를 추가해주면 된다.

module.exports = {
    ...
    extends: ['plugin:yujijang/recommended']
    ...
}
profile
프론트엔드 개발자

0개의 댓글