- 키워드: eslint, custom rule, eslint plugin, spellcheck, generator-eslint, Yeoman, AST
- 상황
- 프로젝트에서 자주 쓰이는 단어들이 있는데, 디자이너에게 전달받은 문구에 오타가 있는 경우가 잦다.
- Lint를 이용하여 코드 레벨에서 오타를 잡아낼 수 있으면 좋겠다고 생각했다.
- IDE에 사전을 등록하는 기능은 있지만, 오타를 감지하고 수정해주는 rule까지는 설정할 수 없기 때문에 custom rule을 만들어보기로 한다.
- 해결 과정
- eslint custom rule을 만들 수 있는 generator-eslint package를 이용하기로 한다.
(https://www.npmjs.com/package/generator-eslint)
README 대로 Yeoman과 generator-eslint 패키지를 설치한다.
npm i -g yo npm i -g generator-eslint
- README대로 eslint plugin 개발 환경을 만든다.
이 때 plugin 이름과 rule 이름은 원하는대로 설정한다.mkdir eslint-plugin-loplat-test cd eslint-plugin-loplat-test yo eslint:plugin // ? Does this plugin contain custom ESLint rules? Yes // ? Does this plugin contain one or more processors? No yo eslint:rule // ? Where will this rule be published? ESLint Plugin
- 그리고 lib/rules/spellcheck.js 에서 원하는 custom rule을 작성한다.
rule 작성 규칙은 eslint 문서를 참고한다. (https://eslint.org/docs/developer-guide/working-with-rules#contextreport)
rule을 적용할 node type은 AST explorer에서 확인한다.(https://astexplorer.net/)
작성한 custom rule은 아래와 같은 상황의 오류를 감지/보고한다.// lib/rules/spellcheck.js /** * @fileoverview test * @author loplat */ 'use strict'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ /** * @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { type: 'problem', // `problem`, `suggestion`, or `layout` fixable: 'code', // Or `code` or `whitespace` schema: [] // Add a schema if the rule has options }, create(context) { // variables should be defined here const dictionary = { 메세지: '메시지', Loplat: 'loplat', 'loplat x': 'loplat X', 'loplat I': 'loplat i' }; return { // visitor functions for different types of nodes Literal(node) { // Literal type 일때 const text = node.raw; Object.entries(dictionary).forEach(([wrong, correct]) => { if (text.includes(wrong)) { // 오타가 있으면 context.report({ node, message: "'{{ correct }}'가 맞는 표현입니다.", data: { correct }, fix: (fixer) => fixer.replaceText(node, text.replace(wrong, correct)) // 올바른 표현으로 교정 }); } }); } }; } };
- Literal type의 AST node일 경우 &&
- node의 text가 '메세지', 'Loplat', 'loplat x', 'loplat I'를 포함할 경우 &&
- context.report를 이용하여 오류 message를 보고하고, fix 속성을 이용하여 올바른 표현으로 교정한다. - 작성한 rule을 tests/lib/rules/spellckeck.js를 통해 테스트한다.
테스트 파일은 아래와 같이 작성했다.// tests/lib/rules/spellckeck.js /** * @fileoverview test * @author loplat */ 'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ const rule = require('../../../lib/rules/spellcheck'), RuleTester = require('eslint').RuleTester; //------------------------------------------------------------------------------ // Tests //------------------------------------------------------------------------------ const dictionary = { 메세지: '메시지', Loplat: 'loplat', 'loplat x': 'loplat X', 'loplat I': 'loplat i' }; const ruleTester = new RuleTester(); ruleTester.run('spellcheck', rule, { valid: Object.values(dictionary).map((correct) => ({ code: `console.log('${correct}')` })), invalid: Object.entries(dictionary).map(([wrong, correct]) => ({ code: `console.log('${wrong}')`, output: `console.log('${correct}')`, errors: [{ message: `'${correct}'가 맞는 표현입니다.`, type: 'Literal' }] })) });
ruleTester를 통해 valid한 경우와 invalid한 경우에 대한 예시 code를 작성할 수 있다.
invalid한 경우엔 error message가 어떻게 나오는 지(errors), 어떻게 fix 되어야하는지(output) 테스트할 수 있다.
테스트 파일은 yarn test로 테스트 가능하다.
yarn test // 결과 spellckeck valid ✔ console.log('메시지') ✔ console.log('loplat') ✔ console.log('loplat X') ✔ console.log('loplat i') invalid ✔ console.log('메세지') ✔ console.log('Loplat') ✔ console.log('loplat x') ✔ console.log('loplat I') 8 passing (56ms)
- 이제 custom rule을 실제 프로젝트에서 import 해야한다.
먼저 custom eslint plugin을 npm에 배포한다.npm publish
- plugin이 정상적으로 배포되면, plugin을 사용할 프로젝트에서 설치한다.
yarn add -D eslint-plugin-loplat-test
.eslintrc.js 에서 plugin과 rule을 추가한다.
// .eslintrc.js plugins: ['loplat-test'], rules: { 'loplat-test/spellcheck': 'error' },
- 이제 ESLint custom rule이 적용된 것을 확인할 수 있다!
eslint fix를 적용해 오타를 수정할 수 있다.
- eslint custom rule을 만들 수 있는 generator-eslint package를 이용하기로 한다.
'프론트엔드' 카테고리의 다른 글
backdrop-filter, box-shadow 크로스 브라우징하기 (0) | 2022.07.03 |
---|---|
gitbook-cli cb.apply error 해결하기 (1) | 2022.06.18 |
iframe으로 Vue to React Migration 준비하기 (0) | 2022.06.12 |
JENNIFER Front로 웹사이트 모니터링하기 (0) | 2022.05.22 |
package.json에서 yarn resolutions 적용하기 (0) | 2022.05.21 |