SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์šฐ๋ฆฌ๋Š” ์—…๋ฌด์— ํ”Œ๋žซํผ์„ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์†Œ๋‚˜ํ๋ธŒ ์ฝ”๋“œ ํ’ˆ์งˆ์„ ๋†’์€ ์ˆ˜์ค€์œผ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์„ฑ๋œ ํ”„๋กœ์ ํŠธ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ๊ฒฝ์šฐ VueJs+ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ, ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€ ๋” ์ž์„ธํžˆ ๋ง์”€ ๋“œ๋ฆฌ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์ด ๊ธ€์—์„œ๋Š” ์œ„์—์„œ ์“ด ๊ฒƒ์ฒ˜๋Ÿผ SonarQube ํ”Œ๋žซํผ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์•ฝ๊ฐ„์˜ ์ด๋ก  - ์ฒ˜์Œ์œผ๋กœ ๋“ฃ๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•œ ์ผ๋ฐ˜์ ์ธ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์†Œ๋‚˜ํ๋ธŒ (์ด์ „์˜ ์†Œ๋‚˜)๋Š” ์ง€์†์ ์ธ ๊ฒ€์‚ฌ ๋ฐ ์ฝ”๋“œ ํ’ˆ์งˆ ์ธก์ •์„ ์œ„ํ•œ ์˜คํ”ˆ ์†Œ์Šค ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.
MISRA C, MISRA C++, MITRE/CWE ๋ฐ CERT ๋ณด์•ˆ ์ฝ”๋”ฉ ํ‘œ์ค€์˜ ๊ทœ์น™์— ๋”ฐ๋ผ ์ฝ”๋“œ ๋ถ„์„ ๋ฐ ์˜ค๋ฅ˜ ๊ฐ์ง€๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ OWASP ์ƒ์œ„ 10๊ฐœ ๋ฐ CWE/SANS ์ƒ์œ„ 25๊ฐœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์˜ค๋ฅ˜ ๋ชฉ๋ก์—์„œ ์˜ค๋ฅ˜๋ฅผ ์ธ์‹ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ”Œ๋žซํผ์ด ๋‹ค์–‘ํ•œ ๊ธฐ์„ฑ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  SonarQube๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‹จ์ผ ๋Œ€์‹œ๋ณด๋“œ๋กœ ์ถ•์†Œํ•˜์—ฌ ์‹คํ–‰ ๊ธฐ๋ก์„ ์œ ์ง€ํ•จ์œผ๋กœ์จ ๊ฐœ๋ฐœ ์ค‘ ์†Œํ”„ํŠธ์›จ์–ด ํ’ˆ์งˆ ๋ณ€ํ™”์˜ ์ผ๋ฐ˜์ ์ธ ์ถ”์„ธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต์‹ ์›น ์‚ฌ์ดํŠธ

๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ€ ์ง€์›๋ฉ๋‹ˆ๋‹ค. ์œ„ ๋งํฌ์˜ ์ •๋ณด๋กœ ํŒ๋‹จํ•˜๋ฉด 25๊ฐœ ์ด์ƒ์˜ ์–ธ์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜๋ ค๋ฉด ์ ์ ˆํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฒ„์ „์—๋Š” ์ž‘์—…์„ ์œ„ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ (typesัript ํฌํ•จ), Wiki์—์„œ๋Š” ๊ทธ ๋ฐ˜๋Œ€๋ผ๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ๋’ค์— ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋‹ต๋ณ€ SonarJS, Typescript์˜ ๊ฒฝ์šฐ ์†Œ๋‚˜TS ๊ฐ๊ฐ.

๊ณต์‹ ํด๋ผ์ด์–ธํŠธ๋Š” ์ ์šฉ ๋ฒ”์œ„ ์ •๋ณด๋ฅผ ๋ณด๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์†Œ๋‚˜ํ๋ธŒ ์Šค์บ๋„ˆ, ๋‹ค์Œ์˜ ์„ค์ •์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์ •-file, ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์†Œ๋‚˜ํ๋ธŒ ์ถ”๊ฐ€ ํ†ตํ•ฉ ๋ฐ ์ง‘๊ณ„๋ฅผ ์œ„ํ•ด.

์— ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ์ด npm ๋ž˜ํผ. ์ด์ œ ๋‹จ๊ณ„๋ณ„ ๊ตฌํ˜„์„ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์†Œ๋‚˜ํ๋ธŒ ะฒ ๋ทฐ-ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ดํ”„ ์Šคํฌ๋ฆฝํŠธ.

์„œ๋ฒ„๋ฅผ ๋ฐฐํฌํ•˜๋ ค๋ฉด ์†Œ๋‚˜ํ๋ธŒ ์ด์ ์„ ํ™œ์šฉํ•˜์ž ๋„์ปค ์ž‘์„ฑ.

sonar.yaml:

version: '1'
    services:
        simplesample-sonar:
            image: sonarqube:lts
            ports:
                - 9001:9000
                - 9092:9092
            network_mode: bridge

์‹œ์ž‘ํ•˜๋‹ค:

docker-compose -f sonar.yml up

๊ทธํ›„์— ์†Œ๋‚˜ํ๋ธŒ ๋‹ค์Œ์—์„œ ์ด์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค: http://localhost:9001 .

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ
์•„์ง ํ”„๋กœ์ ํŠธ๊ฐ€ ์—†์œผ๋ฉฐ ๊ณตํ‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ƒํ™ฉ์„ ๋ฐ”๋กœ์žก๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ณต์‹ ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งก์•˜์Šต๋‹ˆ๋‹ค. VueJS+TS+Jest. ์šฐ๋ฆฌ ์ž์‹ ์„ ํ–ฅํ•ด ๊ตฌ๋ถ€๋ฆฌ์ž:

git clone https://github.com/vuejs/vue-test-utils-typescript-example.git

๋จผ์ € ํด๋ผ์ด์–ธํŠธ๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค ์†Œ๋‚˜ํ๋ธŒ๋ผ๋Š” ์†Œ๋‚˜ ์Šค์บ๋„ˆ~์„ ์œ„ํ•ด npm ๋ž˜ํผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

yarn add sonarqube-scanner

๊ทธ๋ฆฌ๊ณ  ์ฆ‰์‹œ ๋ช…๋ น์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค. ์Šคํฌ๋ฆฝํŠธ ๊ทธ๊ฒƒ์œผ๋กœ ์ž‘์—…ํ•ฉ๋‹ˆ๋‹ค.

ํŒจํ‚ค์ง€.json:

{
 โ€ฆ 
   scripts: {
      ...
      "sonar": "sonar-scanner"
      ...
   },
 โ€ฆ
}

๋‹ค์Œ์œผ๋กœ, ์Šค์บ๋„ˆ๊ฐ€ ์ž‘๋™ํ•˜๋ ค๋ฉด ํŠน์ˆ˜ ํŒŒ์ผ์—์„œ ํ”„๋กœ์ ํŠธ ์„ค์ •์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์†Œ๋‚˜ ํ”„๋กœ์ ํŠธ.์†์„ฑ:

sonar.host.url=http://localhost:9001

sonar.projectKey=test-project-vuejs-ts
sonar.projectName=Test Application (VueJS+TS)

sonar.sources=src
# sonar.tests=
sonar.test.inclusions=src/**/*tests*/**
sonar.sourceEncoding=UTF-8

  • ์†Œ๋‚˜.ํ˜ธ์ŠคํŠธ.url - ์ฃผ์†Œ ์†Œ๋‚˜'ใ…;
  • sonar.projectKey โ€“ ์„œ๋ฒ„์˜ ๊ณ ์œ ํ•œ ํ”„๋กœ์ ํŠธ ์‹๋ณ„์ž ์†Œ๋‚˜'ใ…;
  • sonar.ํ”„๋กœ์ ํŠธ ์ด๋ฆ„ โ€“ ์ด๋ฆ„์€ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‹ค์Œ์œผ๋กœ ์‹๋ณ„๋˜๋ฏ€๋กœ ์–ธ์ œ๋“ ์ง€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธํ‚ค;
  • ์†Œ๋‚˜ ์†Œ์Šค โ€“ ์†Œ์Šค๊ฐ€ ์žˆ๋Š” ํด๋”, ์ผ๋ฐ˜์ ์œผ๋กœ ์ด ํด๋” SRC, ๊ทธ๋Ÿฌ๋‚˜ ๋ฌด์—‡์ด๋“  ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํด๋”๋Š” ์Šค์บ๋„ˆ๊ฐ€ ์‹คํ–‰๋˜๋Š” ํด๋”์ธ ๋ฃจํŠธ ํด๋”๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
  • ์†Œ๋‚˜.ํ…Œ์ŠคํŠธ โ€“ ์ด์ „ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๊ฐ€ ์œ„์น˜ํ•œ ํด๋”์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ์—๋Š” ํ•ด๋‹น ํด๋”๊ฐ€ ์—†์œผ๋ฉฐ ํ…Œ์ŠคํŠธ๋Š” 'ํด๋”์—์„œ ํ…Œ์ŠคํŠธ์ค‘์ธ ๊ตฌ์„ฑ ์š”์†Œ ์˜†์— ์žˆ์Šต๋‹ˆ๋‹ค.test'์ด๋ฏ€๋กœ ์ง€๊ธˆ์€ ์ด๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๋‹ค์Œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ์†Œ๋‚˜.ํ…Œ์ŠคํŠธ.ํฌํ•จ โ€“ ๋งˆ์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ŠคํŠธ ๊ฒฝ๋กœ์—๋Š” ์—ฌ๋Ÿฌ ์š”์†Œ๊ฐ€ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋˜์–ด ๋‚˜์—ด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • sonar.source์ธ์ฝ”๋”ฉ โ€“ ์†Œ์Šค ํŒŒ์ผ ์ธ์ฝ”๋”ฉ.

์Šค์บ๋„ˆ๋ฅผ ์ฒ˜์Œ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์ฃผ์š” ์ด์ „ ์ž‘์—…์„ ์ œ์™ธํ•œ ๋ชจ๋“  ๊ฒƒ์ด ์ค€๋น„๋ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์—”์ง„ ์ž์ฒด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์Šค์บ๋„ˆ๊ฐ€ ์ดํ›„์— ์‚ฌ์šฉํ•  ์ ์šฉ ๋ฒ”์œ„์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ์ด ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํ…Œ์ŠคํŠธ ์—”์ง„์„ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ์—์„œ ํ…Œ์ŠคํŠธ ์—”์ง„์€ ๋†๋‹ด. ํ•ด๋‹น ์„ค์ •์€ ํŒŒ์ผ์˜ ํ•ด๋‹น ์„น์…˜์— ์žˆ์Šต๋‹ˆ๋‹ค. package.json.

๋‹ค์Œ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

"collectCoverage": true,
"collectCoverageFrom": [
      "src/**/*",
      "!src/main.ts",
      "!src/App.vue",
      "!src/**/*.d.*",
      "!src/**/*__tests__*"
],

์ฆ‰, ์ ์šฉ ๋ฒ”์œ„๋ฅผ ๊ณ„์‚ฐํ•ด์•ผ ํ•˜๋Š” ํ•„์š”์„ฑ๊ณผ ๊ทธ๊ฒƒ์ด ํ˜•์„ฑ๋  ์†Œ์Šค(์˜ˆ์™ธ ํฌํ•จ)์— ๋Œ€ํ•œ ํ”Œ๋ž˜๊ทธ ์ž์ฒด๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

yarn test

์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์ด์œ ๋Š” ์ปดํฌ๋„ŒํŠธ ์ž์ฒด์— ์ฝ”๋“œ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

HelloWorld.vue:

...
methods: {
    calc(n) {
      return n + 1;
    }
  },
mounted() {
  this.msg1 = this.msg + this.calc(1);
},
...

์ด๋Š” ์ ์šฉ ๋ฒ”์œ„๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•œ ํ›„ ๋‹ค์Œ ์‚ฌํ•ญ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

ํ™”๋ฉด์— ์ ์šฉ ๋ฒ”์œ„์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ํ”„๋กœ์ ํŠธ ํด๋”์— ํด๋”๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ ์šฉ ๋ฒ”์œ„ ๋ฒ”์šฉ ํ˜•์‹์˜ ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ์ •๋ณด ํฌํ•จ LCOV(LTP GCOV ํ™•์žฅ).

Gcov ์ฝ”๋“œ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด๋ฃŒ๋กœ ๋ฐฐํฌ๋˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ์ž…๋‹ˆ๋‹ค. Gcov๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ๊ฐ ๋ช…๋ น๋ฌธ์— ๋Œ€ํ•œ ์ •ํ™•ํ•œ ์‹คํ–‰ ํšŸ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์†Œ์Šค ์ฝ”๋“œ์— ์ฃผ์„์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. Gcov๋Š” GCC ํŒจํ‚ค์ง€์˜ ์ผ๋ถ€๋กœ ํ‘œ์ค€ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.
๋ฆฌ์ฝ”๋ธŒ - gcov์šฉ ๊ทธ๋ž˜ํ”ฝ ์ธํ„ฐํŽ˜์ด์Šค. ์—ฌ๋Ÿฌ ์†Œ์Šค ํŒŒ์ผ์— ๋Œ€ํ•œ gcov ํŒŒ์ผ์„ ์กฐํ•ฉํ•˜๊ณ  ์ฝ”๋“œ ๋ฐ ์ ์šฉ ๋ฒ”์œ„ ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ HTML ํŽ˜์ด์ง€ ์„ธํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ํƒ์ƒ‰์„ ๋” ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ํŽ˜์ด์ง€๋„ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. Lcov๋Š” ๋ฌธ์ž์—ด, ํ•จ์ˆ˜ ๋ฐ ๋ถ„๊ธฐ์˜ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ์ ์šฉ ๋ฒ”์œ„ ์ •๋ณด๋Š” ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ ์šฉ ๋ฒ”์œ„/lcov.info.
์šฐ๋ฆฌ๋Š” ๋งํ•  ํ•„์š”๊ฐ€ ์†Œ๋‚˜'์–ด๋””์„œ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‚˜์š”? ๋”ฐ๋ผ์„œ ๊ตฌ์„ฑ ํŒŒ์ผ์— ๋‹ค์Œ ์ค„์„ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•œ ๊ฐ€์ง€ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค๊ตญ์–ด, ์ฆ‰ ํด๋”์— ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. SRC ์—ฌ๋Ÿฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋Œ€ํ•œ ์†Œ์Šค ์ฝ”๋“œ์™€ ํ•˜๋‚˜ ๋˜๋Š” ๋‹ค๋ฅธ ์–ธ์–ด์™€์˜ ์ œํœด๊ฐ€ ์žˆ์œผ๋ฉฐ, ํ•˜๋‚˜ ๋˜๋Š” ๋‹ค๋ฅธ ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ์‚ฌ์šฉ์€ ํ™•์žฅ์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ ์šฉ ๋ฒ”์œ„ ์ •๋ณด๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋งˆ๋‹ค ๋‹ค๋ฅธ ์œ„์น˜์— ์ €์žฅ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฐ ์–ธ์–ด์—๋Š” ์ด๋ฅผ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ ์ž์ฒด ์„น์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ํƒ€์ดํ”„ ์Šคํฌ๋ฆฝํŠธ, ๋”ฐ๋ผ์„œ ์ด์— ๋Œ€ํ•œ ์„ค์ • ์„น์…˜์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์†Œ๋‚˜ ํ”„๋กœ์ ํŠธ.์†์„ฑ:

sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.info

์Šค์บ๋„ˆ์˜ ์ฒซ ๋ฒˆ์งธ ์‹คํ–‰์„ ์œ„ํ•œ ๋ชจ๋“  ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์†Œ๋‚˜'e๋Š” ํŠน์ • ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ์Šค์บ๋„ˆ๋ฅผ ์ฒ˜์Œ ์‹คํ–‰ํ•  ๋•Œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ดํ›„์—๋Š” ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ํ”„๋กœ์ ํŠธ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์—ญํ•™์  ๋ณ€ํ™”๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ •๋ณด๊ฐ€ ์ถ•์ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์•ž์—์„œ ๋งŒ๋“  ๋ช…๋ น์„ ์‚ฌ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. package.json:

yarn run sonar 

์ฐธ๊ณ  : ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -X ๋” ์ž์„ธํ•œ ๋กœ๊น…์„ ์›ํ•˜์‹œ๋ฉด

์Šค์บ๋„ˆ๊ฐ€ ์ฒ˜์Œ์œผ๋กœ ์‹œ์ž‘๋œ ๊ฒฝ์šฐ ์Šค์บ๋„ˆ ์ž์ฒด์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ๋จผ์ € ๋‹ค์šด๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„ ์„œ๋ฒ„ ๊ฒ€์ƒ‰์ด ์‹œ์ž‘๋˜๊ณ  ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์†Œ๋‚˜'a ์„ค์น˜๋œ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋Œ€ํ•ด ์ง€์›๋˜๋Š” ์–ธ์–ด๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ์ž‘์—…์„ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๊ธฐํƒ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋„ ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ํ’ˆ์งˆ ํ”„๋กœํ•„, ํ™œ์„ฑ ๊ทœ์น™, ์ง€ํ‘œ ์ €์žฅ์†Œ, ์„œ๋ฒ„ ๊ทœ์น™.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์ฐธ๊ณ  : ์ด ๊ธฐ์‚ฌ์˜ ํ‹€ ๋‚ด์—์„œ ์ด์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์–ธ์ œ๋“ ์ง€ ๊ณต์‹ ์†Œ์Šค์— ๋ฌธ์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ ํด๋” ๋ถ„์„์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค SRC ํ›„์† ์ธ๋ฑ์‹ฑ์„ ํ†ตํ•ด ์ง€์›๋˜๋Š” ๋ชจ๋“  ์–ธ์–ด(ํŠน์ • ์–ธ์–ด๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ)์— ๋Œ€ํ•œ ์†Œ์Šค ํŒŒ์ผ์˜ ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

๋‹ค์Œ์—๋Š” ์ด ๊ธฐ์‚ฌ์—์„œ ๋‹ค๋ฃจ์ง€ ์•Š๋Š” ๋‹ค์–‘ํ•œ ๋‹ค๋ฅธ ๋ถ„์„(์˜ˆ: ๋ฆฐํŒ…, ์ฝ”๋“œ ์ค‘๋ณต ๊ฐ์ง€ ๋“ฑ)์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

์Šค์บ๋„ˆ ์ž‘์—…์ด ๋๋‚˜๋ฉด ์ˆ˜์ง‘๋œ ๋ชจ๋“  ์ •๋ณด๊ฐ€ ์ง‘๊ณ„, ๋ณด๊ด€๋˜์–ด ์„œ๋ฒ„๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

๊ทธ ํ›„์— ์›น ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€ ์ด๋ฏธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

๋ณด์‹œ๋‹ค์‹œํ”ผ ๋ญ”๊ฐ€ ํšจ๊ณผ๊ฐ€ ์žˆ์—ˆ๊ณ  ์‹ฌ์ง€์–ด ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋ณด๋„๋„ ๋ณด์—ฌ ์ฃผ์—ˆ์ง€๋งŒ ์šฐ๋ฆฌ์˜ ๊ฒƒ๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋†๋‹ด-๋ณด๊ณ ์„œ.

๊ทธ๊ฒƒ์„ ์•Œ์•„ ๋ด…์‹œ๋‹ค. ํ”„๋กœ์ ํŠธ๋ฅผ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ณ  ์ ์šฉ ๋ฒ”์œ„ ๊ฐ’์„ ํด๋ฆญํ•œ ๋‹ค์Œ ์ž์„ธํ•œ ํŒŒ์ผ ๋ณด๊ณ ์„œ๋ฅผ "์ „์ฒด" ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์—ฌ๊ธฐ์„œ๋Š” ๊ฒ€์‚ฌ๋œ ๊ธฐ๋ณธ ํŒŒ์ผ ์™ธ์—๋„ HelloWorld.vue, ํŒŒ์ผ๋„ ์žˆ์Šต๋‹ˆ๋‹ค main.ts, ์ด๋Š” ๋ณด๋„์˜ ์ „์ฒด ๊ทธ๋ฆผ์„ ๋ง์นฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์™œ ๋ณด์žฅ ๋ฒ”์œ„ ๊ณ„์‚ฐ์—์„œ ์ œ์™ธํ–ˆ๋Š”์ง€์š”. ์˜ˆ, ๋ชจ๋“  ๊ฒƒ์ด ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ˆ˜์ค€์— ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋†๋‹ด, ๊ทธ๋Ÿฌ๋‚˜ ์Šค์บ๋„ˆ๊ฐ€ ์ด๋ฅผ ์ƒ‰์ธํ™”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ตญ ๊ณ„์‚ฐ์— ํฌํ•จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์†Œ๋‚˜ ํ”„๋กœ์ ํŠธ.์†์„ฑ:

...
sonar.exclusions=src/main.ts
...

๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ง€์ •๋œ ํด๋” ์™ธ์—๋„ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋‚˜์—ด๋œ ๋ชจ๋“  ํด๋”๋„ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์†Œ๋‚˜.ํ…Œ์ŠคํŠธ.ํฌํ•จ.

์Šค์บ๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์˜ฌ๋ฐ”๋ฅธ ์ •๋ณด๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

๋‹ค์Œ ์š”์ ์„ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ’ˆ์งˆ ํ”„๋กœํ•„. ์œ„์—์„œ ์ง€์›์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์†Œ๋‚˜๋™์‹œ์— ์—ฌ๋Ÿฌ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋ณด๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‹ค์Œ ์–ธ์–ด๋กœ ์ž‘์„ฑ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. TS, ๊ทธ๋ ‡๋‹ค๋ฉด ๋ถˆํ•„์š”ํ•œ ์กฐ์ž‘๊ณผ ํ™•์ธ์œผ๋กœ ์Šค์บ๋„ˆ์— ๋ถ€๋‹ด์„ ์ฃผ๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ตฌ์„ฑ ํŒŒ์ผ์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€ํ•˜์—ฌ ๋ถ„์„ํ•  ์–ธ์–ด๋ฅผ ์„ค์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์†Œ๋‚˜'ใ…:

์†Œ๋‚˜ ํ”„๋กœ์ ํŠธ.์†์„ฑ:

...
sonar.language=ts
...

์Šค์บ๋„ˆ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์ปค๋ฒ„๋ ฅ์ด ์™„์ „ ์—†์–ด์กŒ์Šต๋‹ˆ๋‹ค.

์Šค์บ๋„ˆ ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด ๋‹ค์Œ ์ค„์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์ฆ‰, ํ”„๋กœ์ ํŠธ ํŒŒ์ผ์ด ์ƒ‰์ธํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์ƒํ™ฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ณต์‹์ ์œผ๋กœ ์ง€์›๋ฉ๋‹ˆ๋‹ค. VueJ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์žˆ์Šต๋‹ˆ๋‹ค SonarJS, ๋ˆ„๊ฐ€ ์ฑ…์ž„์„ ์ง€๋Š”๊ฐ€ ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

ํ•˜์ง€๋งŒ ์ด ์ง€์›์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์—†์Šต๋‹ˆ๋‹ค ์†Œ๋‚˜TS ์— TS, ๋ฒ„๊ทธ ์ถ”์ ๊ธฐ์—์„œ ๊ณต์‹ ํ‹ฐ์ผ“์ด ๊ฐœ์„ค๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์†Œ๋‚˜'ใ…:

  1. https://jira.sonarsource.com/browse/MMF-1441
  2. https://github.com/SonarSource/SonarJS/issues/1281

๋‹ค์Œ์€ ์ด ์‚ฌ์‹ค์„ ํ™•์ธํ•˜๋Š” SonarQube ๊ฐœ๋ฐœ์ž ๋Œ€ํ‘œ ์ค‘ ํ•œ ์‚ฌ๋žŒ์˜ ๋‹ต๋ณ€์ž…๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

ํ•˜์ง€๋งŒ ๋ชจ๋“  ๊ฒƒ์ด ์šฐ๋ฆฌ์—๊ฒŒ ๋„์›€์ด ๋˜์—ˆ๋‹ค๊ณ  ๋‹น์‹ ์€ ๋ฐ˜๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ์‘, ์ข€ ํ•ด๋ณด์ž "๋งˆ๊ตฌ ์ž๋ฅด๊ธฐ".
์ง€์›์ด ์žˆ๋Š” ๊ฒฝ์šฐ .vue-ํŒŒ์ผ ์†Œ๋‚˜'์•„, ๊ทธ๋Ÿผ ๊ทธ์—๊ฒŒ ๊ทธ๊ฒƒ๋“ค์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ๊ฐํ•˜๋ผ๊ณ  ๋งํ•ด๋ณด์ž ํƒ€์ดํ”„ ์Šคํฌ๋ฆฝํŠธ.

๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์†Œ๋‚˜ ํ”„๋กœ์ ํŠธ.์†์„ฑ:

...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...

์Šค์บ๋„ˆ๋ฅผ ์‹คํ–‰ํ•ด ๋ด…์‹œ๋‹ค:

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

๊ทธ๋ฆฌ๊ณ  ์งœ์ž”, ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์œผ๋กœ ๋Œ์•„์™”์Šต๋‹ˆ๋‹ค. ํƒ€์ดํ”„ ์Šคํฌ๋ฆฝํŠธ. ์ฆ‰, ์šฐ๋ฆฌ๋Š” ์ง€์› ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. VueJs+TS ์— ์†Œ๋‚˜ํ๋ธŒ.

๋” ๋‚˜์•„๊ฐ€ ์ปค๋ฒ„๋ฆฌ์ง€ ์ •๋ณด๋ฅผ ์กฐ๊ธˆ ๋” ๊ฐœ์„ ํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ ์šฐ๋ฆฌ๊ฐ€ ํ•œ ์ผ:

  • ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€๋จ ์†Œ๋‚˜-์Šค์บ๋„ˆ;
  • ์„ค์ • ๋†๋‹ด ์ ์šฉ ๋ฒ”์œ„ ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด;
  • ๊ตฌ์„ฑ๋œ ์†Œ๋‚˜-์Šค์บ๋„ˆ;
  • ์ง€์› ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค .vue-ํŒŒ์ผ + ํƒ€์ดํ”„ ์Šคํฌ๋ฆฝํŠธ.

ํ…Œ์ŠคํŠธ ๋ฒ”์œ„ ์™ธ์—๋„ ์ฝ”๋“œ ํ’ˆ์งˆ์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ํฅ๋ฏธ๋กญ๊ณ  ์œ ์šฉํ•œ ๊ธฐ์ค€์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ”„๋กœ์ ํŠธ์˜ ์ฝ”๋“œ ์ค‘๋ณต ๋ฐ ์ค„ ์ˆ˜(์ฝ”๋“œ ๋ณต์žก์„ฑ๊ณผ ๊ด€๋ จ๋œ ๊ณ„์ˆ˜ ๊ณ„์‚ฐ์— ํฌํ•จ)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž‘์—…์„ ์œ„ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ํ˜„์žฌ ๊ตฌํ˜„์—์„œ TS (์†Œ๋‚˜TS) ์ž‘๋™ ์•ˆ ํ•  ๊ฒƒ์ด๋‹ค CPD(๋ณต์‚ฌ ๋ถ™์—ฌ๋„ฃ๊ธฐ ๊ฐ์ง€๊ธฐ) ์ฝ”๋“œ ์ค„์„ ์„ธ๋Š” ์ค‘ .vue-ํŒŒ์ผ.

์ฝ”๋“œ ์ค‘๋ณต์˜ ํ•ฉ์„ฑ ์ƒํ™ฉ์„ ๋งŒ๋“ค๋ ค๋ฉด ๊ตฌ์„ฑ ์š”์†Œ ํŒŒ์ผ์„ ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๋ณต์ œํ•˜๊ณ  ์ฝ”๋“œ์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. main.ts ๋”๋ฏธ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ค‘๋ณต์„ ํ™•์ธํ•˜๋ ค๋ฉด .vue,์—์„œ .ts -ํŒŒ์ผ.

main.ts:

...
function name(params:string): void {
  console.log(params);
}
...

์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ๊ตฌ์„ฑ ์ค„์„ ์ผ์‹œ์ ์œผ๋กœ ์ฃผ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์†Œ๋‚˜ ํ”„๋กœ์ ํŠธ.์†์„ฑ:

...
sonar.exclusions=src/main.ts
...

ํ…Œ์ŠคํŠธ์™€ ํ•จ๊ป˜ ์Šค์บ๋„ˆ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

yarn test && yarn run sonar

๋ฌผ๋ก  ์šฐ๋ฆฌ์˜ ๋ณด์žฅ ๋ฒ”์œ„๋Š” ๋–จ์–ด์ง€๊ฒ ์ง€๋งŒ ์ง€๊ธˆ์€ ๊ทธ๊ฒƒ์— ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ ์ค„์„ ๋ณต์ œํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค CPD-๊ณต์ต์‚ฌ์—… - jscpd:

npx jscpd src

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์ฝ”๋“œ ์ค„์˜ ๊ฒฝ์šฐ:

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์•„๋งˆ๋„ ์ด ๋ฌธ์ œ๋Š” ํ–ฅํ›„ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฒ„์ „์—์„œ ํ•ด๊ฒฐ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์†Œ๋‚˜JS(TS). ๋‚˜๋Š” ๊ทธ๋“ค์ด ์ ์ฐจ์ ์œผ๋กœ ์ด ๋‘ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ•˜๋‚˜๋กœ ๋ณ‘ํ•ฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. SonarJS, ๋‚ด ์ƒ๊ฐ์—” ๊ทธ๊ฒŒ ๋งž๋Š” ๊ฒƒ ๊ฐ™์•„.

์ด์ œ ๋ณด์žฅ ์ •๋ณด๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ์˜ต์…˜์„ ๊ณ ๋ คํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ ์ „์ฒด ํ”„๋กœ์ ํŠธ, ํŠนํžˆ ํŒŒ์ผ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ๋ฐฑ๋ถ„์œจ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ˆ˜๋Ÿ‰์— ๋Œ€ํ•œ ์ •๋ณด๋กœ ์ด ์ง€ํ‘œ๋ฅผ ํ™•์žฅํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์œ„-ํŒŒ์ผ ์ปจํ…์ŠคํŠธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ํ•  ์ˆ˜ ์žˆ๋Š” ๋„์„œ๊ด€์ด ์žˆ์–ด์š” ๋†๋‹ด-๋ณด๊ณ ์„œ๋ฅผ ๋‹ค์Œ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์†Œ๋‚˜'ใ…:
์ผ๋ฐ˜ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ - https://docs.sonarqube.org/display/SONAR/Generic+Test+Data.

ํ”„๋กœ์ ํŠธ์— ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

yarn add jest-sonar-reporter

๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์„ ๊ตฌ์„ฑ์— ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค. ๋†๋‹ด:

ํŒจํ‚ค์ง€.json:

โ€ฆ
"testResultsProcessor": "jest-sonar-reporter"
โ€ฆ

์ด์ œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

yarn test

๊ทธ๋Ÿฐ ๋‹ค์Œ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ๋ณด๊ณ ์„œ.xml.

๊ตฌ์„ฑ์— ์‚ฌ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์†Œ๋‚˜'ใ…:

์†Œ๋‚˜ ํ”„๋กœ์ ํŠธ.์†์„ฑ:

โ€ฆ
sonar.testExecutionReportPaths=test-report.xml
โ€ฆ

๊ทธ๋ฆฌ๊ณ  ์Šค์บ๋„ˆ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜์‹ญ์‹œ์˜ค.

yarn run sonar

์ธํ„ฐํŽ˜์ด์Šค์—์„œ ๋ฌด์—‡์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์†Œ๋‚˜'ใ…:

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

๊ทธ๋ฆฌ๊ณ  ์•„๋ฌด๊ฒƒ๋„ ๋ณ€ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค Sonar๋Š” Jest ๋ณด๊ณ ์„œ์— ์„ค๋ช…๋œ ํŒŒ์ผ์„ ํŒŒ์ผ๋กœ ๊ฐ„์ฃผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹จ์œ„-ํ…Œ์ŠคํŠธ. ์ด ์ƒํ™ฉ์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ์„ฑ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์†Œ๋‚˜ ์†Œ๋‚˜.ํ…Œ์ŠคํŠธ, ํ…Œ์ŠคํŠธ๊ฐ€ ํฌํ•จ๋œ ํด๋”๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค(ํ˜„์žฌ๋Š” ํ•˜๋‚˜๋งŒ ์žˆ์Œ).

์†Œ๋‚˜ ํ”„๋กœ์ ํŠธ.์†์„ฑ:

โ€ฆ
sonar.tests=src/components/__tests__
โ€ฆ

์Šค์บ๋„ˆ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

yarn run sonar

์ธํ„ฐํŽ˜์ด์Šค์—์„œ ๋ฌด์—‡์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

์ด์ œ ์šฐ๋ฆฌ๋Š” ์šฐ๋ฆฌ์˜ ์ˆซ์ž๋ฅผ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋‹จ์œ„-ํ…Œ์ŠคํŠธ๋ฅผ โ€‹โ€‹์ˆ˜ํ–‰ํ•˜๊ณ  ๋‚ด๋ถ€๋ฅผ ํด๋ฆญํ•˜์—ฌ ์‹คํŒจํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ๊ฐ„์— ์ด ๋ฒˆํ˜ธ์˜ ๋ถ„ํฌ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

SonarQube์™€ VueJS+TS ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ

๊ฒฐ๋ก 

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ์ง€์†์ ์ธ ๋ถ„์„์„ ์œ„ํ•œ ๋„๊ตฌ๋ฅผ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์†Œ๋‚˜ํ๋ธŒ. ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์œผ๋กœ ์ž‘์„ฑ๋œ ํ”„๋กœ์ ํŠธ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ํ†ตํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค. VueJs+TS. ์ผ๋ถ€ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ์ง€ํ‘œ์˜ ์ •๋ณด ๋‚ด์šฉ์„ ๋Š˜๋ ธ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ์ฝ”๋“œ ํ’ˆ์งˆ ๊ธฐ์ค€ ์ค‘ ํ•˜๋‚˜๋งŒ(์•„๋งˆ๋„ ์ฃผ์š” ๊ธฐ์ค€ ์ค‘ ํ•˜๋‚˜) ์กฐ์‚ฌํ–ˆ์ง€๋งŒ ์†Œ๋‚˜ํ๋ธŒ ์•ˆ์ „ ํ…Œ์ŠคํŠธ๋ฅผ ํฌํ•จํ•œ ๊ธฐํƒ€ ํ’ˆ์งˆ ๊ธฐ์ค€์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ ์ค‘ ์ผ๋ถ€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ-๋ฒ„์ „. ํฅ๋ฏธ๋กญ๊ณ  ์œ ์šฉํ•œ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋Š” ํ†ตํ•ฉ์ž…๋‹ˆ๋‹ค. ์†Œ๋‚˜ํ๋ธŒ GitLab, BitBucket ๋“ฑ ๋‹ค์–‘ํ•œ ์ฝ”๋“œ ์ €์žฅ์†Œ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์„ ๊ฐ–์ถ”๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ‘ํ•ฉ ํ’€(๋ณ‘ํ•ฉ) ์š”์ฒญ'๋ฒ”์œ„๊ฐ€ ์ €ํ•˜๋˜๋ฉด ์ €์žฅ์†Œ์˜ ์ฃผ์š” ๋ถ„๊ธฐ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ธฐ์‚ฌ์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค.

์ถ”์‹ : ์ฝ”๋“œ ํ˜•์‹์œผ๋กœ ๊ธฐ์‚ฌ์— ์„ค๋ช…๋œ ๋ชจ๋“  ๋‚ด์šฉ์€ ๋‹ค์Œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ํฌํฌ.

๋“ฑ๋ก๋œ ์‚ฌ์šฉ์ž๋งŒ ์„ค๋ฌธ ์กฐ์‚ฌ์— ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ์ œ๋ฐœ

SonarQube ํ”Œ๋žซํผ์„ ์‚ฌ์šฉํ•˜์‹œ๋‚˜์š”?

  • 26,3%์˜ˆ5

  • 15,8%3

  • 15,8%์ด ํ”Œ๋žซํผ์— ๋Œ€ํ•ด ๋“ค์—ˆ๊ณ  ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค3

  • 10,5%์ด ํ”Œ๋žซํผ์— ๋Œ€ํ•ด ๋“ค์—ˆ์ง€๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค2

  • 0,0%๋‹ค๋ฅธ ํ”Œ๋žซํผ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค0

  • 31,6%์ฒ˜์Œ์œผ๋กœ ๊ทธ๋…€์— ๋Œ€ํ•ด ๋“ค์–ด๋ดค์Šต๋‹ˆ๋‹ค6

19๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ํˆฌํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. 3๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๊ถŒํ–ˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€