Lintest CLI

Copyright 2020. mornya. All rights reserved.
About
Integrated lint and test environment project.
Features
- TypeScript / ES6+ support with TypeScript.
- Linting TypeScript / JavaScript codes with ESLint.
- Testing codes with Jest.
- All available for Node.js / React.js / Vue.js (Nuxt.js) application
Installation
ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๊ธ๋ก๋ฒ ์์ญ์ ์ค์นํ๋ค.
npm ๋์ yarn ์ฌ์ฉ์, ํ๋ก์ ํธ ๋ฃจํธ ๊ฒฝ๋ก์ package-lock.json ํ์ผ์ด ์กด์ฌํ๋ฉด ์ ๊ฑฐํ๊ณ yarn.lock ํ์ผ๋ง ์ฐธ์กฐ๋๋๋ก ํ๋ค.
$ npm install -g @lintest/cli
or
$ yarn global add @lintest/cli
Execution
Commands
$ lintest [commands] [args...]
์ฌ์ฉ๊ฐ๋ฅํ commands๋ ์๋์ ๊ฐ๋ค.
export: ๋ฆฐํธ ๋ฐ ํ
์คํธ ํ๊ฒฝ์ค์ ๋ด์ฉ์ JSON ํ์ผ๋ก ์ถ๋ ฅ
install: ๋ฆฐํธ ๋ฃฐ ๋ํ๋์ ์ค์น ๋ฐ lintest ์ ๋ณด ์์ฑ, ๋ชจ๋ ์
๊ทธ๋ ์ด๋
lint: ํ๋ก์ ํธ ๋ด ์ฝ๋์ ๋ํ ๋ฆฐํธ ์ํ
test: ํ๋ก์ ํธ ๋ด ํ
์คํธ ์ฝ๋์ ๋ํ ํ
์คํธ์ผ์ด์ค ์ํ
uninstall: ์์ฑ๋ ์ ๋ณด ๋ฐ ์ฌ๋ณผ๋ฆญ๋งํฌ ๋ฑ install/export ์ ์ฒ๋ฆฌ๋ ๊ด๋ จ ํ์ผ ์ ๊ฑฐ
CLI
lintest ํ๊ฒฝ์ค์ ์ ํ๋ก์ ํธ ๋ฃจํธ ๊ฒฝ๋ก ํน์ ํ ๋๋ ํ ๋ฆฌ์ lintest.config.js ํ์ผ๋ก ์์ฑํ๋ฉด ๋๋ค.
ํด๋น ํ์ผ์ด ์กด์ฌํ๋ฉด lintest install ๋ช
๋ น ์ํ์ providerํญ๋ชฉ์ผ๋ก ์ง์ ๋ ๋ํ๋์๊ฐ ํ๋ก์ ํธ์ ์ค์น๋๋ฉฐ, ๋ฆฐํธ ๋ฃฐ์ ํด๋น ๋ํ๋์ ์ค์ ์ ๋ฐ๋ฅด๊ฒ ๋๋ค.
lintest.config.js ํ์ผ์ด ํ๋ก์ ํธ ๋ฃจํธ์ ์กด์ฌํ์ง ์์ผ๋ฉด ํ ๋๋ ํ ๋ฆฌ์์ ์ฐพ๊ณ , ์๋ค๋ฉด ํ๋ก์ ํธ ์์, ์ฐจ์์ ๊ฒฝ๋ก์์ ์ฐพ๋๋ค.
module.exports = {
provider: 'sample',
}
์์ ๊ฐ์ด ์ค์ ํ๋ฉด lintest install ๋ช
๋ น ์คํ์ @lintest/rules-sample ๋ํ๋์๊ฐ ํ๋ก์ ํธ ๋ด ์ค์น๊ฐ ๋๋ฉฐ lint rule์ ํด๋น ๋ํ๋์ ๋ด ์ค์ ์ ๋ฐ๋ฅธ๋ค.
rules ๋ํ๋์ ์์ฑ์ ์๋์์ ๋ค๋ฃฌ๋ค.
๋ฆฐํธ ๋ฐ ํ
์คํธ ์ํ์ CLI๋ก ์คํํ๋ฉฐ, ์ปค๋งจ๋๋ผ์ธ์์ ์๋์ ๊ฐ์ด ์คํ ํ ์ ์๋ค.
$ lintest lint [fix][debug][nocache]
$ lintest test [watch][coverage][nocache]
๋ฆฐํธ ๋ฐ ํ
์คํธ ํ๊ฒฝ์ค์ ๋ด์ฉ์ด ํ์ํ ๊ฒฝ์ฐ export ๋ช
๋ น์ ์ฌ์ฉํ์ฌ ํ๊ฒฝ์ค์ ์ ์ฐธ๊ณ ํ ์ ์๋ค.
์ํ๊ฒฐ๊ณผ๋ ํ๋ก์ ํธ ๋ฃจํธ ๊ฒฝ๋ก์ eslint.config.json ๋ฐ jest.config.json ํ์ผ์ด ์์ฑ๋๋ค.
๋ง์ฝ ์ ์์ ์ธ ์ถ๋ ฅ์ด ๋์ง ์๋๋ค๋ฉด debug ํ๋ผ๋ฏธํฐ๋ก ํ์ธํ๋ค.
$ lintest export [debug]
NPM
NPM ํ๋ก์ ํธ์์๋ npm run ๋ช
๋ น์ผ๋ก ์คํ๋๋๋ก ์๋์ ๊ฐ์ด package.json ํ์ผ ๋ด์ ์ค์ ํ๋ค.
{
"scripts": {
"lint": "lintest lint",
"lint:fix": "lintest lint fix",
"lint:debug": "lintest lint debug nocache",
"test": "lintest test",
"test:watch": "lintest test watch",
"test:coverage": "lintest test coverage nocache"
}
}
ํ๋ก์ ํธ npm install ํ์ lintest ์
๋ฐ์ดํธ ๋ฐ ๋ฃฐ ์
๋ฐ์ดํธ๋ฅผ ์๋์ผ๋ก ์ํํด ์ค ์ ์๋๋ก ์๋์ ๊ฐ์ด ์ค์ ํด๋ ์ข๋ค.
exit 0์ lintest๊ฐ ์ค์น๋์ด ์์ง ์์ ๊ฒฝ์ฐ, ์ค๋ฅ๋ก ์ธํด ๋ค์ ํ๋ก์ธ์ค๊ฐ ๋์ํ์ง ์๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ ์์ข
๋ฃ๋ก ์ฒ๋ฆฌํ๋๋ก ํด์ค๋ค.
{
"scripts": {
"postinstall": "lintest install || exit 0",
"postuninstall": "lintest install || exit 0"
}
}
Testing
ํ
์คํธ์ผ์ด์ค๋ฅผ ์ํํ๊ธฐ ์ํด CLI์ ๋ํ๋์๋ก ์ค์น๋ jest ๋ฐ์ด๋๋ฆฌ๊ฐ ์คํ๋๋ค.
ํ
์คํธ ํ์ผ์ ํ๋ก์ ํธ ๋ด ์กด์ฌํ๋ *.test.{ts|tsx|js|jsx} ํ์ผ๋ค์ด ํ
์คํธ ๋์์ด ๋๋ค.
Setup files
๊ฐ ๋จ์ ํ
์คํธ๋ฅผ ์ํํ๊ธฐ ์ mocking method๋ ์ด๊ธฐ ์ค์ ์ ํ ์ ์๋๋ก ์
์
ํ์ผ์ ์ถ๊ฐ ํ ์ ์๋ค.
์ ์ฉ๋ ํ
์คํธ ์
์
ํ์ผ์ ์๋ ๋ชฉ๋ก์์ ์กด์ฌํ๋ ํ์ผ์ ๋ชจ๋ ์ฐพ์ ์ฌ์ฉํ๊ฒ ๋๋ค.
์์ธํ ๋ด์ฉ์ Jest ๊ด๋ จ ๋ฌธ์๋ฅผ ์ฐธ๊ณ .
<rootDir>/src/test/@setup.ts (or .js)
<rootDir>/src/tests/@setup.ts (or .js)
<rootDir>/test/@setup.ts (or .js)
<rootDir>/tests/@setup.ts (or .js)
<rootDir>/test-setup.ts (or .js)
Test Coverage
์๋ ๋ช
๋ น์ผ๋ก ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง ๋ฐ์ดํฐ๋ฅผ ํ๋ก์ ํธ ๋ด /coverage ๋๋ ํ ๋ฆฌ์ ์์ฑํ ์ ์๋ค.
lintest test coverage
Lint rules package
Naming
ํจํค์ง๋ช
์ @lintest/rules-{ํ๋ก๋ฐ์ด๋๋ช
}์ผ๋ก ์ ์ํ๊ณ NPM @lintest ์กฐ์ง์ ์น์ธ์ ๋ฐ์ ๋ฐฐํฌํจ์ผ๋ก์จ CLI์์ ํด๋น ํจํค์ง๋ฅผ ๋ฐ์ ๋ฆฐํธ ๋ฃฐ์ ์ ์ฉ ํ ์ ์๊ฒ ๋๋ค.
Package defination
package.json์ "main"์ผ๋ก ์ค์ ๋ ํ์ผ(index.js)์ ์๋์ ๊ฐ์ ๋จ์ผ ํํ์ ์ ์ ํ์ผ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ํ๋ค.
์ค์ ๊ฐ๋ฅ ํญ๋ชฉ์ prettier, lintRules, disableLintIgnore, enableCompatibility ๋ฑ์ด ์๋ค.
prettier
prettier ํญ๋ชฉ์ prettier ์ฌ์ฉ์ด ํ์ํ ๋๋ง ๋ช
์ํ๋ฉด ๋๋ค.
lintRules
์๋ ์ํ์ฒ๋ผ ์ค์ ํด์ฃผ๋ฉด lintest์์ ์ค์ ์ ๋ฐ๋ผ ์ฌ๋ฌ ํ๋ฌ๊ทธ์ธ์ ์กฐํฉํ์ฌ ์ต์ข
๋ฆฐํธ ๋ฃฐ์
์ ๋ง๋ค์ด๋ธ๋ค.
lintRules ํ์ ํญ๋ชฉ์ ๋ฃฐ์ ๋ํ ์ ์ธ์ ํ๋ฌ๊ทธ์ธ๋ณ prefix๋ฅผ ๋ถ์ด์ง ์์๋ ๋๋ฉฐ, ๋ถํ์์ ๋ช
์ํ์ง ์์๋ ๋๋ค.
์๋ฅผ ๋ค์ด, typescript ํญ๋ชฉ์ '@typescript-eslint/indent' ๋ฃฐ์ ์ ์ํ ๋ '@typescript-eslint/'๋ ๊ตณ์ด ๋ถ์ฌ์ฃผ์ง ์์๋ 'typescript' ํญ๋ชฉ ํ์์ 'indent'๋ง์ผ๋ก ์ ์ธํด๋ ์ต์ข
๋ฃฐ์ '@typescript-eslint/indent'๋ก ๋ณํ๋๋ค.
lintRules ํ์ ํญ๋ชฉ ์ค vue ํน์ react ๋ฃฐ์ด ๋ช
์๋๋ฉด ๊ด๋ จ ๋ฃฐ์
์ด ํจ๊ป ์ ์ฉ๋๋ค.
vue๋ "eslint-plugin-vue", "@vue/standard", "@vue/typescript" ๋ฑ ์ ์ฉ.
react๋ "eslint-plugin-jsx-a11y", "eslint-plugin-react", "eslint-plugin-react-hooks" ๋ฑ ์ ์ฉ.
Sample
module.exports = {
prettier: {
tabWidth: 2,
useTabs: false,
},
lintRules: {
general: {
'comma-dangle': 'off',
'no-console': 'off',
'no-debugger': 'off',
},
typescript: {
'@typescript-eslint/indent': ['error', 2],
},
react: {
'react/jsx-boolean-value': 'off',
'jsx-wrap-multilines': 'off',
},
reactHooks: {
'rules-of-hooks': 'error',
'exhaustive-deps': 'warn',
},
vue: {
'attribute-hyphenation': 'off',
'vue/html-closing-bracket-spacing': 'off',
'vue/html-indent': ['error', 2],
'html-self-closing': 'off',
},
unicorn: {
'escape-case': 'error',
},
promise: {
'promise/valid-params': 'off',
},
standard: {},
import: {},
jest: {},
lintest: {
report: [1, 'all', 10, 300],
},
},
}
Etcs
๋ฆฐํธ ํผํฌ๋จผ์ค ํฅ์์ ์ํด ์๋์ ๊ฐ์ด performance report๋ฅผ ์ฝ์๋ก ์ถ๋ ฅํ ์ ์๋ค.
๋ฆฐํธ์ ์ํ์๊ฐ์ ์ฒดํฌํด๋ณด๋ฉด์ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๋ ๋ฃฐ์ ๋ํด ๋นํ์ฑํํ๋ฉด ์ํ์๋ ํฅ์์ ๋์์ด ๋๋ค.
$ export TIMING=1
$ npm run lint
Change Log
ํด๋น ํ๋ก์ ํธ์ ๋ณ๊ฒฝ์ฌํญ์ CHANGELOG.md ํ์ผ ์ฐธ์กฐ.
License
ํด๋น ํ๋ก์ ํธ์ ๋ผ์ด์ผ์ค๋ LICENSE ํ์ผ ์ฐธ์กฐ.