เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบžเบงเบเป€เบฎเบปเบฒเปƒเบŠเป‰เป€เบงเบ—เบตเปƒเบ™เบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบขเปˆเบฒเบ‡เบˆเบดเบ‡เบˆเบฑเบ‡ soundQube เป€เบžเบทเปˆเบญเบฎเบฑเบเบชเบฒเบ„เบธเบ™เบ™เบฐเบžเบฒเบšเบฅเบฐเบซเบฑเบ”เบขเบนเปˆเปƒเบ™เบฅเบฐเบ”เบฑเบšเบชเบนเบ‡. เป€เบกเบทเปˆเบญเบฅเบงเบกเป€เบญเบปเบฒเป‚เบ„เบ‡เบเบฒเบ™เบซเบ™เบถเปˆเบ‡เบ—เบตเปˆเบ‚เบฝเบ™เป„เบงเป‰เปƒเบ™ VueJs+เบ•เบปเบงเบžเบดเบก, เบšเบฑเบ™เบซเบฒเป€เบเบตเบ”เบ‚เบถเป‰เบ™. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบขเบฒเบเบšเบญเบเบ—เปˆเบฒเบ™เปƒเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบˆเบฑเบ”เบเบฒเบ™เปเบ™เบงเปƒเบ”เป€เบžเบทเปˆเบญเปเบเป‰เป„เบ‚เบžเบงเบเบกเบฑเบ™.

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบชเบปเบ™เบ—เบฐเบ™เบฒ, เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบ‚เบฝเบ™เบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡, เบเปˆเบฝเบงเบเบฑเบšเป€เบงเบ—เบต SonarQube. เบ—เบดเบ”เบชเบฐเบ”เบตเป€เบฅเบฑเบเบ™เป‰เบญเบ - เบกเบฑเบ™เปเบกเปˆเบ™เบซเบเบฑเบ‡เป‚เบ”เบเบ—เบปเปˆเบงเป„เบ›, เบชเปเบฒเบฅเบฑเบšเบœเบนเป‰เบ—เบตเปˆเป„เบ”เป‰เบเบดเบ™เบเปˆเบฝเบงเบเบฑเบšเบกเบฑเบ™เบ„เบฑเป‰เบ‡เบ—เปเบฒเบญเบดเบ”:

soundQube (เบญเบฐเบ”เบตเบ” sonar) เป€เบ›เบฑเบ™เป€เบงเบ—เบตเปเบซเบผเปˆเบ‡เป€เบ›เบตเบ”เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบงเบ”เบเบฒเบขเปˆเบฒเบ‡เบ•เปเปˆเป€เบ™เบทเปˆเบญเบ‡เปเบฅเบฐเบเบฒเบ™เบงเบฑเบ”เปเบ—เบเบ„เบธเบ™เบ™เบฐเบžเบฒเบšเบฅเบฐเบซเบฑเบ”.
เบฎเบญเบ‡เบฎเบฑเบšเบเบฒเบ™เบงเบดเป€เบ„เบฒเบฐเบฅเบฐเบซเบฑเบ” เปเบฅเบฐเบเบฒเบ™เบเบงเบ”เบซเบฒเบ‚เปเป‰เบœเบดเบ”เบžเบฒเบ”เบ•เบฒเบกเบเบปเบ”เบฅเบฐเบšเบฝเบšเบ‚เบญเบ‡ MISRA C, MISRA C++, MITER/CWE เปเบฅเบฐ CERT Secure Coding Standards programming Standards. เบกเบฑเบ™เบเบฑเบ‡เบชเบฒเบกเบฒเบ”เบฎเบฑเบšเบฎเบนเป‰เบ„เบงเบฒเบกเบœเบดเบ”เบžเบฒเบ”เบˆเบฒเบ OWASP Top 10 เปเบฅเบฐ CWE/SANS Top 25 เบฅเบฒเบเบŠเบทเปˆเบ„เบงเบฒเบกเบœเบดเบ”เบžเบฒเบ”เบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบผเปเบเบผเบก.
เป€เบ–เบดเบ‡เบงเปˆเบฒเบˆเบฐเบกเบตเบ„เบงเบฒเบกเบˆเบดเบ‡เบ—เบตเปˆเบงเปˆเบฒเปเบžเบฅเบฐเบ•เบฐเบŸเบญเบกเปƒเบŠเป‰เป€เบ„เบทเปˆเบญเบ‡เบกเบทเบ—เบตเปˆเบเบฝเบกเบžเป‰เบญเบกเบ•เปˆเบฒเบ‡เป†, SonarQube เบซเบผเบธเบ”เบฅเบปเบ‡เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเปƒเบ™ dashboard เบ”เบฝเบง, เบฎเบฑเบเบชเบฒเบ›เบฐเบซเบงเบฑเบ”เบเบฒเบ™เปเบฅเปˆเบ™เปเบฅเบฐเบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบˆเบถเปˆเบ‡เบŠเปˆเบงเบเปƒเบซเป‰เบ—เปˆเบฒเบ™เป€เบซเบฑเบ™เปเบ™เบงเป‚เบ™เป‰เบกเบ—เบปเปˆเบงเป„เบ›เบ‚เบญเบ‡เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เปƒเบ™เบ„เบธเบ™เบ™เบฐเบžเบฒเบšเบ‚เบญเบ‡เบŠเบญเบšเปเบงเปƒเบ™เบฅเบฐเบซเบงเปˆเบฒเบ‡เบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒ.

เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบชเบฒเบกเบฒเบ”เบžเบปเบšเป„เบ”เป‰เบ—เบตเปˆ เป€เบงเบฑเบšเป„เบŠเบ—เปŒเบ—เบฒเบ‡เบเบฒเบ™

เบˆเปเบฒเบ™เบงเบ™เบ‚เบฐเบซเบ™เบฒเบ”เปƒเบซเบเปˆเบ‚เบญเบ‡เบžเบฒเบชเบฒเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบกเป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™. เบเบฒเบ™เบ•เบฑเบ”เบชเบดเบ™เป‚เบ”เบเบ‚เปเป‰เบกเบนเบ™เบˆเบฒเบเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡, เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบซเบผเบฒเบเบเปˆเบงเบฒ 25 เบžเบฒเบชเบฒ. เป€เบžเบทเปˆเบญเบฎเบญเบ‡เบฎเบฑเบšเบžเบฒเบชเบฒเบชเบฐเป€เบžเบฒเบฐ, เบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบ•เบดเบ”เบ•เบฑเป‰เบ‡ plugin เบ—เบตเปˆเป€เบซเบกเบฒเบฐเบชเบปเบก. เบชเบฐเบšเบฑเบšเบŠเบธเบกเบŠเบปเบ™เบ›เบฐเบเบญเบšเบกเบต plugin เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบš Javascript (เบฅเบงเบกเบ—เบฑเบ‡ typesัript), เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒ wiki เป€เบงเบปเป‰เบฒเบงเปˆเบฒเบเบปเบ‡เบเบฑเบ™เบ‚เป‰เบฒเบก. เบซเบฅเบฑเบ‡ Javascript plugin เบ„เปเบฒเบ•เบญเบš SonarJS, เบชเปเบฒเบฅเบฑเบš Typescript SonarTS respectively

เบฅเบนเบเบ„เป‰เบฒเบขเปˆเบฒเบ‡เป€เบ›เบฑเบ™เบ—เบฒเบ‡เบเบฒเบ™เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เป€เบžเบทเปˆเบญเบชเบปเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡ sonarqube-เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™, เบ—เบตเปˆ, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบˆเบฒเบ config-file, เบชเบปเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™เบ™เบตเป‰เป„เบ›เบซเบฒเป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบ soundQube เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบฅเบงเบกเปเบฅเบฐเบเบฒเบ™เบฅเบงเบšเบฅเบงเบกเบ•เบทเปˆเบกเบญเบตเบ.

เป„เบ› Javascript เบกเบตเปเบกเปˆเบ™ npm wrapper. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เปƒเบซเป‰เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ‚เบฑเป‰เบ™เบ•เบญเบ™เป‚เบ”เบเบ‚เบฑเป‰เบ™เบ•เบญเบ™ soundQube ะฒ Vue- เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹ เบ•เบปเบงเบญเบฑเบเบชเบญเบ™.

เป€เบžเบทเปˆเบญเบ™เบณเปƒเบŠเป‰เป€เบŠเบตเบšเป€เบงเบต soundQube เปƒเบซเป‰เป€เบฎเบปเบฒเปƒเบŠเป‰เบ›เบฐเป‚เบซเบเบ” docker-compose.

sonar.yaml:

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

เป€เบ›เบตเบ”เบ•เบปเบง:

docker-compose -f sonar.yml up

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบตเป‰ soundQube เบˆเบฐเบกเบตเบขเบนเปˆ: http://localhost:9001 .

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube
เบเบฑเบ‡โ€‹เบšเปเปˆโ€‹เบกเบตโ€‹เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹เบขเบนเปˆโ€‹เปƒเบ™โ€‹เบกเบฑเบ™โ€‹เป€เบ—เบทเปˆเบญโ€‹เปเบฅเบฐโ€‹เบงเปˆเบฒโ€‹เปเบกเปˆเบ™โ€‹เบเบธโ€‹เบ•เบดโ€‹เบ—เปเบฒโ€‹. เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเปเบเป‰เป„เบ‚เบชเบฐเบ–เบฒเบ™เบฐเบเบฒเบ™เบ™เบตเป‰. เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เป€เบญเบปเบฒเป‚เบ„เบ‡เบเบฒเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบขเปˆเบฒเบ‡เป€เบ›เบฑเบ™เบ—เบฒเบ‡เบเบฒเบ™เบชเปเบฒเบฅเบฑเบš VueJS+TS+Jest. เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบเบปเป‰เบกเปƒเบชเปˆเบ•เบปเบงเป€เบฎเบปเบฒเป€เบญเบ‡:

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

เบ—เปเบฒเบญเบดเบ”เบžเบงเบเป€เบฎเบปเบฒเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป„เบ”เป‰เบ•เบดเบ”เบ•เบฑเป‰เบ‡เบฅเบนเบเบ„เป‰เบฒ soundQube, เป€เบŠเบดเปˆเบ‡เป€เบญเบตเป‰เบ™เบงเปˆเบฒ sonar-เบชเบฐเปเบเบ™เบชเบณ เบฅเบฑเบš npm เบกเบต wrapper เป€เบ›เบฑเบ™:

yarn add sonarqube-scanner

เปเบฅเบฐเบ—เบฑเบ™เบ—เบตเป€เบžเบตเปˆเบกเบ„เปเบฒเบชเบฑเปˆเบ‡เปƒเบชเปˆ scripts เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบšเบกเบฑเบ™.

package.json:

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

เบ•เปเปˆเป„เบ›, เป€เบžเบทเปˆเบญเปƒเบซเป‰เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เป€เบฎเบฑเบ”เบงเบฝเบ, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป„เบ”เป‰เบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเป‚เบ„เบ‡เบเบฒเบ™เปƒเบ™เป„เบŸเบฅเปŒเบžเบดเป€เบชเบ”. เปƒเบซเป‰เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ”เป‰เบงเบเบžเบทเป‰เบ™เบ–เบฒเบ™.

sonar-project.properties:

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

  • sonar.host.url - เบ—เบตเปˆเบขเบนเปˆ sonar'เบ;
  • sonar.projectKey โ€“ เบ•เบปเบงเบฅเบฐเบšเบธเป‚เบ„เบ‡เบเบฒเบ™เบ—เบตเปˆเป€เบ›เบฑเบ™เป€เบญเบเบฐเบฅเบฑเบเปƒเบ™เป€เบŠเบตเบšเป€เบงเบต sonar'เบ;
  • sonar.projectName โ€“ เบŠเบทเปˆโ€‹เบ‚เบญเบ‡โ€‹เบ•เบปเบ™โ€‹, เบกเบฑเบ™โ€‹เบชเบฒโ€‹เบกเบฒเบ”โ€‹เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เบเบฒเบ™โ€‹เบ›เปˆเบฝเบ™โ€‹เปเบ›เบ‡โ€‹เป„เบ”เป‰โ€‹เบ—เบธเบโ€‹เป€เบงโ€‹เบฅเบฒโ€‹, เบ™เบฑเบšโ€‹เบ•เบฑเป‰เบ‡โ€‹เปเบ•เปˆโ€‹เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹เป„เบ”เป‰โ€‹เบ–เบทเบโ€‹เบเปเบฒโ€‹เบ™เบปเบ”โ€‹เป‚เบ”เบโ€‹ เบฅเบฐเบซเบฑเบ”เป‚เบ„เบ‡เบเบฒเบ™;
  • sonar.เปเบซเบผเปˆเบ‡ - เป‚เบŸเบ™เป€เบ”เบตเบ—เบตเปˆเบกเบตเปเบซเบผเปˆเบ‡, เบ›เบปเบเบเบฐเบ•เบดเปเบฅเป‰เบงเบ™เบตเป‰ src, เปเบ•เปˆเบชเบฒเบกเบฒเบ”เป€เบ›เบฑเบ™เบญเบฑเบ™เปƒเบ”เบเปเป„เบ”เป‰. เป‚เบŸเบ™เป€เบ”เบตเบ™เบตเป‰เบ–เบทเบเบ•เบฑเป‰เบ‡เบ‚เบทเป‰เบ™เบเบฑเบšเป‚เบŸเบ™เป€เบ”เบตเบฎเบฒเบ, เป€เบŠเบดเปˆเบ‡เป€เบ›เบฑเบ™เป‚เบŸเบ™เป€เบ”เบตเบ—เบตเปˆเป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เบ–เบทเบเป€เบ›เบตเบ”เบ•เบปเบง;
  • sonar.tests - เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ—เบตเปˆเป„เบ›เบ„เบฝเบ‡เบ„เบนเปˆเบเบฑเบšเบญเบฑเบ™เบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒ. เบ™เบตเป‰เปเบกเปˆเบ™เป‚เบŸเบ™เป€เบ”เบตเบ—เบตเปˆเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ•เบฑเป‰เบ‡เบขเบนเปˆ. เปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™เบ™เบตเป‰, เบšเปเปˆเบกเบตเป‚เบŸเบ™เป€เบ”เบตเบ”เบฑเปˆเบ‡เบเปˆเบฒเบง, เปเบฅเบฐเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเปเบกเปˆเบ™เบ•เบฑเป‰เบ‡เบขเบนเปˆเบ•เปเปˆเป„เบ›เบเบฑเบšเบญเบปเบ‡เบ›เบฐเบเบญเบšเบ—เบตเปˆเบ–เบทเบเบ—เบปเบ”เบชเบญเบšเบขเบนเปˆเปƒเบ™เป‚เบŸเบ™เป€เบ”เบต 'เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš', เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบšเปเปˆเบชเบปเบ™เปƒเบˆเบกเบฑเบ™เบชเปเบฒเบฅเบฑเบšเปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เปเบฅเบฐเบ™เปเบฒเปƒเบŠเป‰เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ•เปเปˆเป„เบ›;
  • sonar.test.inclusions - เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป‚เบ”เบเปƒเบŠเป‰เบซเบ™เป‰เบฒเบเบฒเบ, เบญเบฒเบ”เบˆเบฐเบกเบตเบญเบปเบ‡เบ›เบฐเบเบญเบšเบˆเปเบฒเบ™เบงเบ™เบซเบ™เบถเปˆเบ‡เบ—เบตเปˆเปเบเบเบญเบญเบเบ”เป‰เบงเบเป€เบ„เบทเปˆเบญเบ‡เปเบฒเบเบˆเบธเบ”;
  • sonar.sourceEncoding - เบเบฒเบ™โ€‹เป€เบ‚เบปเป‰เบฒโ€‹เบฅเบฐโ€‹เบซเบฑเบ”โ€‹เบชเปเบฒโ€‹เบฅเบฑเบšโ€‹เป„เบŸเบฅโ€‹เปŒโ€‹เบ—เบตเปˆโ€‹เบกเบฒโ€‹.

เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบ›เบตเบ”เบ•เบปเบงเบ„เบฑเป‰เบ‡เบ—เปเบฒเบญเบดเบ”เบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™, เบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เปเบกเปˆเบ™เบเบฝเบกเบžเป‰เบญเบก, เบเบปเบเป€เบงเบฑเป‰เบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบเปˆเบญเบ™เบซเบ™เป‰เบฒเบ•เบปเป‰เบ™เบ•เป: เบเบฒเบ™เป€เบ›เบตเบ”เบ•เบปเบงเป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ•เบปเบงเบกเบฑเบ™เป€เบญเบ‡, เป€เบžเบทเปˆเบญเปƒเบซเป‰เบกเบฑเบ™เบชเบฒเบกเบฒเบ”เบชเป‰เบฒเบ‡เบ‚เปเป‰เบกเบนเบ™เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡, เป€เบŠเบดเปˆเบ‡เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เบˆเบฐเปƒเบŠเป‰เปƒเบ™เบžเบฒเบเบซเบฅเบฑเบ‡.

เปเบ•เปˆเป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ™เบตเป‰, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบเปเบฒเบ™เบปเบ”เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป€เบžเบทเปˆเบญเบชเป‰เบฒเบ‡เบ‚เปเป‰เบกเบนเบ™เบ™เบตเป‰. เปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™เบ™เบตเป‰, เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเปเบกเปˆเบ™ เบกเบต. เปเบฅเบฐเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ‚เบญเบ‡เบกเบฑเบ™เบขเบนเปˆเปƒเบ™เบชเปˆเบงเบ™เบ—เบตเปˆเบชเบญเบ”เบ„เป‰เบญเบ‡เบเบฑเบ™เบ‚เบญเบ‡เป„เบŸเบฅเปŒ เบŠเบธเบ” .json.

เบกเบฒเป€เบžเบตเปˆเบกเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰:

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

เบ™เบฑเป‰เบ™เปเบกเปˆเบ™, เบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบ™เบปเบ”เบ—เบธเบ‡เบ•เบปเบงเบกเบฑเบ™เป€เบญเบ‡เบชเปเบฒเบฅเบฑเบšเบ„เบงเบฒเบกเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบ„เบดเบ”เป„เบฅเปˆเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เปเบฅเบฐเปเบซเบผเปˆเบ‡ (เบžเป‰เบญเบกเบเบฑเบšเบ‚เปเป‰เบเบปเบเป€เบงเบฑเป‰เบ™) เบšเบปเบ™เบžเบทเป‰เบ™เบ–เบฒเบ™เบ—เบตเปˆเบกเบฑเบ™เบˆเบฐเบ–เบทเบเบชเป‰เบฒเบ‡เบ•เบฑเป‰เบ‡เบ‚เบถเป‰เบ™.

เบ•เบญเบ™เบ™เบตเป‰เปƒเบซเป‰เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš:

yarn test

เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบซเบฑเบ™เบ”เบฑเปˆเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เป€เบซเบ”เบœเบปเบ™เปเบกเปˆเบ™เบงเปˆเบฒเบšเปเปˆเบกเบตเบฅเบฐเบซเบฑเบ”เบขเบนเปˆเปƒเบ™เบญเบปเบ‡เบ›เบฐเบเบญเบšเบ‚เบญเบ‡เบกเบฑเบ™เป€เบญเบ‡. เปƒเบซเป‰เปเบเป‰เป„เบ‚เบ™เบตเป‰.

HelloWorld.vue:

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

เบ™เบตเป‰เบˆเบฐเบžเบฝเบ‡เบžเปเบ—เบตเปˆเบˆเบฐเบ„เบดเบ”เป„เบฅเปˆเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡.

เบซเบผเบฑเบ‡โ€‹เบˆเบฒเบโ€‹เบเบฒเบ™ restart เบเบฒเบ™โ€‹เบ—เบปเบ”โ€‹เบชเบญเบšโ€‹, เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹เบˆเบฐโ€‹เป€เบฎเบฑเบ”โ€‹เปƒเบซเป‰โ€‹เปเบ™เปˆโ€‹เปƒเบˆเบงเปˆโ€‹เบฒโ€‹เบ™เบตเป‰โ€‹:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เปƒเบ™เบซเบ™เป‰เบฒเบˆเปเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ„เบงเบ™เบˆเบฐเป€เบซเบฑเบ™เบ‚เปเป‰เบกเบนเบ™เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡, เปเบฅเบฐเป‚เบŸเบ™เป€เบ”เบตเบˆเบฐเบ–เบทเบเบชเป‰เบฒเบ‡เบ‚เบทเป‰เบ™เปƒเบ™เป‚เบŸเบ™เป€เบ”เบตเป‚เบ„เบ‡เบเบฒเบ™ เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡ เบเบฑเบšเบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เปƒเบ™เบฎเบนเบšเปเบšเบšเบ—เบปเปˆเบงเป„เบ› LCOV (เบชเปˆเบงเบ™เบ‚เบฐเบซเบเบฒเบ LTP GCOV).

Gcov เป€เบ›เบฑเบ™โ€‹เบ›เบฐโ€‹เป‚เบซเบเบ”โ€‹เปเบˆเบโ€‹เบขเบฒเบ freely เบชเปเบฒโ€‹เบฅเบฑเบšโ€‹เบเบฒเบ™โ€‹เบเบงเบ”โ€‹เบชเบญเบšโ€‹เบเบฒเบ™โ€‹เบ„เบธเป‰เบกโ€‹เบ„เบญเบ‡โ€‹เบฅเบฐโ€‹เบซเบฑเบ”โ€‹. Gcov เบชเป‰เบฒเบ‡เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ—เบตเปˆเปเบ™เปˆเบ™เบญเบ™เบชเปเบฒเบฅเบฑเบšเปเบ•เปˆเบฅเบฐเบ„เปเบฒเบ–เบฐเปเบซเบผเบ‡เปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™เปเบฅเบฐเบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เป€เบžเบตเปˆเบกเบ„เปเบฒเบšเบฑเบ™เบเบฒเบเปƒเบชเปˆเบฅเบฐเบซเบฑเบ”เปเบซเบผเปˆเบ‡. Gcov เบกเบฒเป€เบ›เบฑเบ™เบœเบปเบ™เบ›เบฐเป‚เบซเบเบ”เบกเบฒเบ”เบ•เบฐเบ–เบฒเบ™เป€เบ›เบฑเบ™เบชเปˆเบงเบ™เบซเบ™เบถเปˆเบ‡เบ‚เบญเบ‡เบŠเบธเบ” GCC.
Lcov - เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบšเบฎเบนเบšเบžเบฒเบšเบชเปเบฒเบฅเบฑเบš gcov. เบกเบฑเบ™เบ›เบฐเบเบญเบšเป„เบŸเบฅเปŒ gcov เบชเปเบฒเบฅเบฑเบšเป„เบŸเบฅเปŒเปเบซเบผเปˆเบ‡เบซเบผเบฒเบเปเบฅเบฐเบœเบฐเบฅเบดเบ”เบŠเบธเบ”เบ‚เบญเบ‡เบซเบ™เป‰เบฒ HTML เบ—เบตเปˆเบกเบตเบฅเบฐเบซเบฑเบ”เปเบฅเบฐเบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡. เบซเบ™เป‰เบฒเป€เบงเบฑเบšเบเบฑเบ‡เบ–เบทเบเบชเป‰เบฒเบ‡เบ‚เบทเป‰เบ™เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เปƒเบซเป‰เบเบฒเบ™เบ™เปเบฒเบ—เบฒเบ‡เบ‡เปˆเบฒเบเบ‚เบถเป‰เบ™. Lcov เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบชเบฒเบ, เบซเบ™เป‰เบฒเบ—เบตเปˆ, เปเบฅเบฐเบชเบฒเบ‚เบฒ.

เบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบชเปเบฒเป€เบฅเบฑเบ”, เบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบˆเบฐเบ–เบทเบเบ•เบฑเป‰เบ‡เบขเบนเปˆเปƒเบ™ coverage/lcov.info.
เบžเบงเบเป€เบฎเบปเบฒเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป€เบงเบปเป‰เบฒ sonar'เบ‚เป‰เบญเบเบชเบฒเบกเบฒเบ”เป€เบญเบปเบฒเบกเบฑเบ™เบกเบฒเบˆเบฒเบเปƒเบช? เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เปƒเบซเป‰เป€เบžเบตเปˆเบกเป€เบชเบฑเป‰เบ™เบ•เปเปˆเป„เบ›เบ™เบตเป‰เปƒเบชเปˆเป„เบŸเบฅเปŒเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ‚เบญเบ‡เบกเบฑเบ™. เปเบ•เปˆเบกเบตเบˆเบธเบ”เบซเบ™เบถเปˆเบ‡: เป‚เบ„เบ‡เบเบฒเบ™เบชเบฒเบกเบฒเบ”เบกเบตเบซเบผเบฒเบเบžเบฒเบชเบฒ, เบ™เบฑเป‰เบ™เปเบกเปˆเบ™, เปƒเบ™เป‚เบŸเบ™เป€เบ”เบต src เบกเบตเบฅเบฐเบซเบฑเบ”เปเบซเบผเปˆเบ‡เบชเปเบฒเบฅเบฑเบšเบซเบฅเบฒเบเบžเบฒเบชเบฒเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบกเปเบฅเบฐเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เบเบฑเบšเบซเบ™เบถเปˆเบ‡เบซเบผเบทเบญเบทเปˆเบ™, เปเบฅเบฐเปƒเบ™เบ—เบฒเบ‡เบเบฑเบšเบเบฑเบ™, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบซเบ™เบถเปˆเบ‡เบซเบผเบท plugin เบญเบทเปˆเบ™เบ–เบทเบเบเปเบฒเบ™เบปเบ”เป‚เบ”เบเบเบฒเบ™เบ‚เบฐเบซเบเบฒเบเบ‚เบญเบ‡เบกเบฑเบ™. เปเบฅเบฐเบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบชเบฒเบกเบฒเบ”เบ–เบทเบเป€เบเบฑเบšเป„เบงเป‰เปƒเบ™เบชเบฐเบ–เบฒเบ™เบ—เบตเปˆเบ•เปˆเบฒเบ‡เป†เบชเปเบฒเบฅเบฑเบšเบžเบฒเบชเบฒเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบผเปเบเบผเบกเบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เปเบ•เปˆเบฅเบฐเบžเบฒเบชเบฒเบกเบตเบชเปˆเบงเบ™เบ‚เบญเบ‡เบ•เบปเบ™เป€เบญเบ‡เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ™เบตเป‰. เป‚เบ„เบ‡เบเบฒเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเปƒเบŠเป‰ เบ•เบปเบงเบญเบฑเบเบชเบญเบ™, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบžเบฒเบเบชเปˆเบงเบ™เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบžเบฝเบ‡เปเบ•เปˆเบชเปเบฒเบฅเบฑเบšเบกเบฑเบ™:

sonar-project.properties:

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

เบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เปเบกเปˆเบ™เบเบฝเบกเบžเป‰เบญเบกเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบ›เบตเบ”เบ•เบปเบงเบ„เบฑเป‰เบ‡เบ—เปเบฒเบญเบดเบ”เบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™. เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบขเบฒเบเบˆเบฐเบชเบฑเบ‡เป€เบเบ”เบงเปˆเบฒเป‚เบ„เบ‡เบเบฒเบ™เปเบกเปˆเบ™ sonar'e เบ–เบทเบเบชเป‰เบฒเบ‡เบ‚เบทเป‰เบ™เป‚เบ”เบเบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เปƒเบ™เบ„เบฑเป‰เบ‡ เบ—เบณ เบญเบดเบ”เบ—เบตเปˆเบ—เปˆเบฒเบ™เปเบฅเปˆเบ™เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™ เบชเบณ เบฅเบฑเบšเป‚เบ„เบ‡เบเบฒเบ™เปƒเบ” เปœเบถเปˆเบ‡. เปƒเบ™เป€เบงเบฅเบฒเบ•เปเปˆเบกเบฒ, เบ‚เปเป‰เบกเบนเบ™เบˆเบฐเบ–เบทเบเบชเบฐเบชเบปเบกเป€เบžเบทเปˆเบญเป€เบšเบดเปˆเบ‡เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบ‚เบญเบ‡เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ‚เบญเบ‡เป‚เบ„เบ‡เบเบฒเบ™เปƒเบ™เป„เบฅเบเบฐเป€เบงเบฅเบฒ.

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เปƒเบซเป‰เปƒเบŠเป‰เบ„เปเบฒเบชเบฑเปˆเบ‡เบ—เบตเปˆเบชเป‰เบฒเบ‡เบ‚เบถเป‰เบ™เบเปˆเบญเบ™เบซเบ™เป‰เบฒเบ™เบฑเป‰เบ™ เบŠเบธเบ” .json:

yarn run sonar 

เบซเบกเบฒเบเป€เบซเบ”: เบ—เปˆเบฒเบ™เบเบฑเบ‡เบชเบฒเบกเบฒเบ”เปƒเบŠเป‰เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเป„เบ”เป‰ -X เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบšเบฑเบ™เบ—เบถเบเบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบก.

เบ–เป‰เบฒเป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เบ–เบทเบเป€เบ›เบตเบ”เบ•เบปเบงเบ„เบฑเป‰เบ‡เบ—เปเบฒเบญเบดเบ”, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, binary เบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เบ•เบปเบงเบกเบฑเบ™เป€เบญเบ‡เบˆเบฐเบ–เบทเบเบ”เบฒเบงเป‚เบซเบผเบ”เบเปˆเบญเบ™. เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เบกเบฑเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เปเบฅเบฐเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบเบฒเบ™เบชเบฐเปเบเบ™เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบ sonar'a เบชเปเบฒเบฅเบฑเบš plugins เบ—เบตเปˆเบ•เบดเบ”เบ•เบฑเป‰เบ‡, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบเบฒเบ™เบ„เบดเบ”เป„เบฅเปˆเบžเบฒเบชเบฒเบ—เบตเปˆเบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™. เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบญเบทเปˆเบ™เป†เบ—เบตเปˆเบซเบผเบฒเบเบซเบผเบฒเบเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบ‚เบญเบ‡เบกเบฑเบ™เปเบกเปˆเบ™เบเบฑเบ‡เป‚เบซเบฅเบ”: เป‚เบ›เบฃเป„เบŸเบฅเปŒเบ„เบธเบ™เบ™เบฐเบžเบฒเบš, เบเบปเบ”เบฅเบฐเบšเบฝเบšเบเบฒเบ™เป€เบ„เบทเปˆเบญเบ™เป„เบซเบง, เบ„เบฑเบ‡เป€เบเบฑเบšเบกเป‰เบฝเบ™ metrics, เบเบปเบ”เบฅเบฐเบšเบฝเบšเบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบ.

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบซเบกเบฒเบเป€เบซเบ”: เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบšเปเปˆเบญเบฒเป„เบชเบขเบนเปˆเบเบฑเบšเบžเบงเบเบกเบฑเบ™เปƒเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบžเบฒเบเปƒเบ™เบ‚เบญเบšเบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰, เปเบ•เปˆเบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ•เบดเบ”เบ•เปเปˆเบเบฑเบšเปเบซเบผเปˆเบ‡เบ—เบตเปˆเป€เบ›เบฑเบ™เบ—เบฒเบ‡เบเบฒเบ™เป„เบ”เป‰เบ•เบฐเบซเบผเบญเบ”เป€เบงเบฅเบฒ.

เบ•เปเปˆเป„เบ›, เบเบฒเบ™เบงเบดเป€เบ„เบฒเบฐเป‚เบŸเบ™เป€เบ”เบตเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™ src เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบกเบตเป„เบŸเบฅเปŒเปเบซเบผเปˆเบ‡เบชเปเบฒเบฅเบฑเบšเบ—เบธเบเบ„เบปเบ™ (เบ–เป‰เบฒเบซเบฒเบเบงเปˆเบฒเบชเบฐเป€เบžเบฒเบฐเปƒเบ”เบซเบ™เบถเปˆเบ‡เบšเปเปˆเป„เบ”เป‰เบฅเบฐเบšเบธเบขเปˆเบฒเบ‡เบŠเบฑเบ”เป€เบˆเบ™) เบžเบฒเบชเบฒเบ—เบตเปˆเบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™, เบ”เป‰เบงเบเบเบฒเบ™เบ”เบฑเบ”เบชเบฐเบ™เบตเบ•เปเปˆเบกเบฒเบ‚เบญเบ‡เบžเบงเบเป€เบ‚เบปเบฒ.

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบ•เปเปˆเป„เบ›เปเบกเปˆเบ™เบเบฒเบ™เบงเบดเป€เบ„เบฒเบฐเบญเบทเปˆเบ™เป†, เป€เบŠเบดเปˆเบ‡เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเป„เบ”เป‰เบชเบธเบกเปƒเบชเปˆเปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰ (เบ•เบปเบงเบขเปˆเบฒเบ‡เป€เบŠเบฑเปˆเบ™: linting, เบเบฒเบ™เบเบงเบ”เบชเบญเบšเบเบฒเบ™เบŠเปเป‰เบฒเบŠเป‰เบญเบ™เบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ”, เปเบฅเบฐเบญเบทเปˆเบ™เป†).

เปƒเบ™เบ•เบญเบ™เบ—เป‰เบฒเบเบ‚เบญเบ‡เบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™, เบ‚เปเป‰เบกเบนเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เบ—เบตเปˆเป€เบเบฑเบšเบเปเบฒเป„เบ”เป‰เบ–เบทเบเบฅเบงเบšเบฅเบงเบก, เป€เบเบฑเบšเป„เบงเป‰เปเบฅเบฐเบ–เบทเบเบชเบปเปˆเบ‡เป„เบ›เบซเบฒเป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบ.

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เป€เบซเบฑเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเป€เบเบตเบ”เบ‚เบถเป‰เบ™เปƒเบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบšเบ‚เบญเบ‡เป€เบงเบฑเบš:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เป€เบซเบฑเบ™เป„เบ”เป‰, เบšเบฒเบ‡เบชเบดเปˆเบ‡เบšเบฒเบ‡เบขเปˆเบฒเบ‡เป€เบฎเบฑเบ”เบงเบฝเบ, เปเบฅเบฐเปเบกเป‰เบเบฐเบ—เบฑเป‰เบ‡เบชเบฐเปเบ”เบ‡เปƒเบซเป‰เป€เบซเบฑเบ™เบšเบฒเบ‡เบ›เบฐเป€เบžเบ”เบ‚เบญเบ‡เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡, เปเบ•เปˆเบกเบฑเบ™เบšเปเปˆเบเบปเบ‡เบเบฑเบšเบžเบงเบเป€เบฎเบปเบฒ เบกเบต- เบฅเบฒเบโ€‹เบ‡เบฒเบ™โ€‹.

เปƒเบซเป‰เบ„เบดเบ”เบญเบญเบ. เปƒเบซเป‰เป€เบšเบดเปˆเบ‡เป‚เบ„เบ‡เบเบฒเบ™เปƒเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบก, เปƒเบซเป‰เบ„เบฅเบดเบเปƒเบชเปˆเบกเบนเบ™เบ„เปˆเบฒเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡, เปเบฅเบฐ "เบ•เบปเบเบฅเบปเบ‡" เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบšเบปเบ”เบฅเบฒเบเบ‡เบฒเบ™เป€เบญเบเบฐเบชเบฒเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เปƒเบ™เบ—เบตเปˆเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเป€เบซเบฑเบ™, เบ™เบญเบเป€เบซเบ™เบทเบญเป„เบ›เบˆเบฒเบเป€เบญเบเบฐเบชเบฒเบ™เบ•เบปเป‰เบ™เบ•เป, เบเบงเบ”เบชเบญเบš HelloWorld.vue, เบเบฑเบ‡เบกเบตเป„เบŸเบฅเปŒ main.ts, เป€เบŠเบดเปˆเบ‡เป€เบฎเบฑเบ”เปƒเบซเป‰เป€เบชเบเบžเบฒเบšเบ—เบฑเบ‡เปเบปเบ”เบ‚เบญเบ‡เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡. เปเบ•เปˆเบงเบดเบ—เบตเบเบฒเบ™เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบเบปเบเป€เบงเบฑเป‰เบ™เบกเบฑเบ™เบˆเบฒเบเบเบฒเบ™เบ„เบดเบ”เป„เบฅเปˆเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡. เปเบกเปˆเบ™เปเบฅเป‰เบง, เบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เปเบกเปˆเบ™เบ–เบทเบเบ•เป‰เบญเบ‡, เปเบ•เปˆเบกเบฑเบ™เบขเบนเปˆเปƒเบ™เบฅเบฐเบ”เบฑเบš เบกเบต, เปเบ•เปˆเป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เบ”เบฑเบ”เบชเบฐเบ™เบตเบกเบฑเบ™, เบชเบฐเบ™เบฑเป‰เบ™เบกเบฑเบ™เบชเบดเป‰เบ™เบชเบธเบ”เบฅเบปเบ‡เปƒเบ™เบเบฒเบ™เบ„เบดเบ”เป„เบฅเปˆเบ‚เบญเบ‡เบกเบฑเบ™.

เปƒเบซเป‰เปเบเป‰เป„เบ‚เบšเบฑเบ™เบซเบฒเบ™เบตเป‰:

sonar-project.properties:

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

เบ‚เป‰เบญเบเบ•เป‰เบญเบ‡เบเบฒเบ™เบ„เบงเบฒเบกเบเบฐเบˆเปˆเบฒเบ‡เปเบˆเป‰เบ‡: เบ™เบญเบเบˆเบฒเบเป‚เบŸเบ™เป€เบ”เบตเบ—เบตเปˆเบฅเบฐเบšเบธเป„เบงเป‰เปƒเบ™เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเบ™เบตเป‰, เป‚เบŸเบ™เป€เบ”เบตเบ—เบฑเบ‡เบซเบกเบปเบ”เบ—เบตเปˆเบฅเบฐเบšเบธเป„เบงเป‰เปƒเบ™เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเบเปเปˆเบ–เบทเบเป€เบžเบตเปˆเบกเป€เบ‚เบปเป‰เบฒ. sonar.test.inclusions.

เบซเบผเบฑเบ‡เบˆเบฒเบเป€เบ›เบตเบ”เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™, เบžเบงเบเป€เบฎเบปเบฒเป€เบซเบฑเบ™เบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบ–เบทเบเบ•เป‰เบญเบ‡:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบ‚เปโ€‹เปƒเบซเป‰โ€‹เป€เบšเบดเปˆเบ‡โ€‹เปƒเบ™โ€‹เบˆเบธเบ”โ€‹เบ•เปเปˆโ€‹เป„เบ› - เป‚เบ›เบผเป„เบŸเบฅเปŒเบ„เบธเบ™เบ™เบฐเบžเบฒเบš. เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เป€เบงเบปเป‰เบฒเบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™ sonar'om เบซเบผเบฒเบเบžเบฒเบชเบฒเปƒเบ™เป€เบงเบฅเบฒเบ”เบฝเบงเบเบฑเบ™. เบ™เบตเป‰เปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบฅเบฑเบ‡เป€เบซเบฑเบ™เปเบ—เป‰เป†. เปเบ•เปˆเบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เบงเปˆเบฒเป‚เบ„เบ‡เบเบฒเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบ–เบทเบเบ‚เบฝเบ™เป„เบงเป‰เปƒเบ™ TS, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เป€เบ›เบฑเบ™เบซเบเบฑเบ‡เบˆเบถเปˆเบ‡เป€เบกเบทเปˆเบญเบเป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เบ”เป‰เบงเบเบเบฒเบ™เบซเบกเบนเบ™เปƒเบŠเป‰เปเบฅเบฐเบเบฒเบ™เบเบงเบ”เบชเบญเบšเบ—เบตเปˆเบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™. เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบเปเบฒเบ™เบปเบ”เบžเบฒเบชเบฒเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบงเบดเป€เบ„เบฒเบฐเป‚เบ”เบเบเบฒเบ™เป€เบžเบตเปˆเบกเบซเบ™เบถเปˆเบ‡เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบเบฑเบšเป„เบŸเบฅเปŒเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ sonar'A:

sonar-project.properties:

...
sonar.language=ts
...

เบฅเบญเบ‡เปเบฅเปˆเบ™เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เบญเบตเบเบ„เบฑเป‰เบ‡ เปเบฅเบฐเป€เบšเบดเปˆเบ‡เบœเบปเบ™:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เป„เบ”เป‰เบซเบกเบปเบ”เป„เบ›.

เบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเป€เบšเบดเปˆเบ‡เบšเบฑเบ™เบ—เบถเบเบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™, เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เป€เบซเบฑเบ™เป€เบชเบฑเป‰เบ™เบ•เปเปˆเป„เบ›เบ™เบตเป‰:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบ™เบฑเป‰เบ™เปเบกเปˆเบ™, เป„เบŸเบฅเปŒเป‚เบ„เบ‡เบเบฒเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบžเบฝเบ‡เปเบ•เปˆเบšเปเปˆเป„เบ”เป‰เบ–เบทเบเบ”เบฑเบ”เบชเบฐเบ™เบต.

เบชเบฐเบ–เบฒเบ™เบฐเบเบฒเบ™เปเบกเปˆเบ™เบ”เบฑเปˆเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰: เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบขเปˆเบฒเบ‡เป€เบ›เบฑเบ™เบ—เบฒเบ‡เบเบฒเบ™ VueJs เบขเบนเปˆเปƒเบ™ plugin SonarJSเบœเบนเป‰เบ—เบตเปˆเบฎเบฑเบšเบœเบดเบ”เบŠเบญเบš Javascript.

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เปเบ•เปˆเบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบ™เบตเป‰เบšเปเปˆเปเบกเปˆเบ™เบขเบนเปˆเปƒเบ™ plugin SonarTS เบเบฒเบ™ TS, เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบ—เบตเปˆเบ›เบตเป‰เบขเปˆเบฒเบ‡เป€เบ›เบฑเบ™เบ—เบฒเบ‡เบเบฒเบ™เป„เบ”เป‰เป€เบ›เบตเบ”เบขเบนเปˆเปƒเบ™เบ•เบปเบงเบ•เบดเบ”เบ•เบฒเบกเปเบกเบ‡เป„เบกเป‰ sonar'A:

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

เบ™เบตเป‰เปเบกเปˆเบ™เบšเบฒเบ‡เบ„เปเบฒเบ•เบญเบšเบˆเบฒเบเบซเบ™เบถเปˆเบ‡เปƒเบ™เบœเบนเป‰เบ•เบฒเบ‡เบซเบ™เป‰เบฒเบˆเบฒเบเบ™เบฑเบเบžเบฑเบ”เบ—เบฐเบ™เบฒ SonarQube, เบขเบทเบ™เบขเบฑเบ™เบ„เบงเบฒเบกเบˆเบดเบ‡เบ™เบตเป‰.

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เปเบ•เปˆเบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เป€เบฎเบฑเบ”เบงเบฝเบเบชเปเบฒเบฅเบฑเบšเบžเบงเบเป€เบฎเบปเบฒ, เบ—เปˆเบฒเบ™เบ„เบฑเบ”เบ„เป‰เบฒเบ™. เปเบกเปˆเบ™เปเบฅเป‰เบง, เปƒเบซเป‰เบฅเบญเบ‡เบกเบฑเบ™เปœเป‰เบญเบเปœเบถเปˆเบ‡ "เปเบฎเบ".
เบ–เป‰เบฒเบกเบตเบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™ .vue- เป„เบŸเบฅโ€‹เปŒโ€‹ sonar'เป‚เบญเป‰, เปเบฅเป‰เบงเบฅเบญเบ‡เบšเบญเบเบฅเบฒเบงเปƒเบซเป‰เบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒ เบ•เบปเบงเบญเบฑเบเบชเบญเบ™.

เบกเบฒเป€เบžเบตเปˆเบกเบžเบฒเบฃเบฒเบกเบดเป€เบ•เบต:

sonar-project.properties:

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

เบกเบฒเป€เบ›เบตเบ”เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เปเบฅเบฐ, voila, เบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เปเบกเปˆเบ™เบเบฑเบšเบ„เบทเบ™เบชเบนเปˆเบ›เบปเบเบเบฐเบ•เบด, เปเบฅเบฐเบกเบตเป‚เบ›เบฃเป„เบŸเบฅเปŒเบ”เบฝเบงเบชเปเบฒเบฅเบฑเบš เบ•เบปเบงเบญเบฑเบเบชเบญเบ™. เบ™เบฑเป‰เบ™เปเบกเปˆเบ™, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบˆเบฑเบ”เบเบฒเบ™เปเบเป‰เป„เบ‚เบšเบฑเบ™เบซเบฒเปƒเบ™เบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™ VueJs+TS เบเบฒเบ™ soundQube.

เปƒเบซเป‰เบžเบฐเบเบฒเบเบฒเบกเบ•เปเปˆเป„เบ›เปเบฅเบฐเบ›เบฑเบšเบ›เบธเบ‡เบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เป€เบฅเบฑเบเบ™เป‰เบญเบ.

เบชเบดเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เป€เบฎเบฑเบ”เบกเบฒเป€เบ–เบดเบ‡เบ•เบญเบ™เบ™เบฑเป‰เบ™:

  • เป€เบžเบตเปˆเบกเปƒเบชเปˆเป‚เบ„เบ‡เบเบฒเบ™ sonar- เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™;
  • เบ•เบฑเป‰เบ‡โ€‹เบ„เปˆเบฒ เบกเบต เป€เบžเบทเปˆเบญเบชเป‰เบฒเบ‡เบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡;
  • เบเบณเบ™เบปเบ”เบ„เปˆเบฒ sonar- เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™;
  • เปเบเป‰โ€‹เป„เบ‚โ€‹เบšเบฑเบ™โ€‹เบซเบฒโ€‹เบชเบฐโ€‹เบซเบ™เบฑเบšโ€‹เบชเบฐโ€‹เบซเบ™เบนเบ™โ€‹ .vue-files + เบ•เบปเบงเบญเบฑเบเบชเบญเบ™.

เบ™เบญเบเป€เบซเบ™เบทเบญเบˆเบฒเบเบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡, เบกเบตเป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบ—เบตเปˆเป€เบ›เบฑเบ™เบ›เบฐเป‚เบซเบเบ”เบญเบทเปˆเบ™เป†เบ—เบตเปˆเบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆเบชเปเบฒเบฅเบฑเบšเบ„เบธเบ™เบ™เบฐเบžเบฒเบšเบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ”, เบ•เบปเบงเบขเปˆเบฒเบ‡, เบเบฒเบ™เบŠเปเป‰เบฒเบŠเป‰เบญเบ™เบฅเบฐเบซเบฑเบ”เปเบฅเบฐเบˆเปเบฒเบ™เบงเบ™เบชเบฒเบ (เบเปˆเบฝเบงเบ‚เป‰เบญเบ‡เบเบฑเบšเบเบฒเบ™เบ„เบดเบ”เป„เบฅเปˆเบ„เปˆเบฒเบชเปเบฒเบ›เบฐเบชเบดเบ”เบ—เบตเปˆเบเปˆเบฝเบงเบ‚เป‰เบญเบ‡เบเบฑเบšเบ„เบงเบฒเบกเบชเบฑเบšเบชเบปเบ™เบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ”) เบ‚เบญเบ‡เป‚เบ„เบ‡เบเบฒเบ™.

เปƒเบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เปƒเบ™เบ›เบฐเบˆเบธเบšเบฑเบ™เบ‚เบญเบ‡ plugin เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบš TS (SonarTS) เบˆเบฐเบšเปเปˆเป€เบฎเบฑเบ”เบงเบฝเบ CPD (Copy Paste Detector) เปเบฅเบฐเบเบฒเบ™เบ™เบฑเบšเบชเบฒเบเบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ” .vue- เป„เบŸเบฅโ€‹เปŒโ€‹.

เป€เบžเบทเปˆเบญเบชเป‰เบฒเบ‡เบชเบฐเบ–เบฒเบ™เบฐเบเบฒเบ™เบชเบฑเบ‡เป€เบ„เบฒเบฐเบ‚เบญเบ‡เบเบฒเบ™เบŠเปเป‰เบฒเบŠเป‰เบญเบ™เบฅเบฐเบซเบฑเบ”, เบžเบฝเบ‡เปเบ•เปˆเป€เบฎเบฑเบ”เบŠเป‰เปเบฒเป„เบŸเบฅเปŒเบญเบปเบ‡เบ›เบฐเบเบญเบšเบ—เบตเปˆเบกเบตเบŠเบทเปˆเบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™เปเบฅเบฐเป€เบžเบตเปˆเบกเบกเบฑเบ™เปƒเบชเปˆเบฅเบฐเบซเบฑเบ”. main.ts เบŸเบฑเบ‡เบŠเบฑเบ™ dummy เปเบฅเบฐเป€เบฎเบฑเบ”เบŠเป‰เปเบฒเบกเบฑเบ™เบ”เป‰เบงเบเบŠเบทเปˆเบญเบทเปˆเบ™. เป€เบžเบทเปˆเบญเบเบงเบ”เบชเบญเบšเบเบฒเบ™เบŠเปเป‰เบฒเบŠเป‰เบญเบ™เป€เบŠเบฑเปˆเบ™เปƒเบ™ .vue, เปเบฅเบฐเปƒเบ™ .ts - เป„เบŸเบฅโ€‹เปŒโ€‹.

main.ts:

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

เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ™เบตเป‰, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป„เบ”เป‰เบชเบฐเปเบ”เบ‡เบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™เบŠเบปเปˆเบงเบ„เบฒเบงเบเปˆเบฝเบงเบเบฑเบšเป€เบชเบฑเป‰เบ™เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ:

sonar-project.properties:

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

เบกเบฒเป€เบฅเบตเปˆเบกเป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เปƒเปเปˆเบžเป‰เบญเบกเบเบฑเบšเบเบฒเบ™เบ—เบปเบ”เบชเบญเบš:

yarn test && yarn run sonar

เปเบ™เปˆเบ™เบญเบ™, เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบซเบผเบธเบ”เบฅเบปเบ‡, เปเบ•เปˆเบ•เบญเบ™เบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเป„เบ”เป‰เบชเบปเบ™เปƒเบˆเป€เบฅเบทเปˆเบญเบ‡เบ™เบฑเป‰เบ™.

เปƒเบ™เปเบ‡เปˆเบ‚เบญเบ‡เบเบฒเบ™เบŠเปเป‰เบฒเบเบฑเบ™เบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ”, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบซเบฑเบ™:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เป€เบžเบทเปˆเบญเบเบงเบ”เบชเบญเบšเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเปƒเบŠเป‰ CPD- เบœเบปเบ™โ€‹เบ›เบฐโ€‹เป‚เบซเบเบ” - jscpd:

npx jscpd src

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบชเปเบฒเบฅเบฑเบšเป€เบชเบฑเป‰เบ™เบฅเบฐเบซเบฑเบ”:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบšเบฒเบ‡เบ—เบตเบ™เบตเป‰เบˆเบฐเบ–เบทเบเปเบเป‰เป„เบ‚เปƒเบ™เบชเบฐเบšเบฑเบš plugin เปƒเบ™เบญเบฐเบ™เบฒเบ„เบปเบ” SonarJS(TS). เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบขเบฒเบโ€‹เบˆเบฐโ€‹เบชเบฑเบ‡โ€‹เป€เบเบ”โ€‹เบงเปˆเบฒโ€‹เบžเบงเบโ€‹เป€เบ‚เบปเบฒโ€‹เป€เบˆเบปเป‰เบฒโ€‹เปเบกเปˆเบ™โ€‹เบ„เปˆเบญเบเป†โ€‹เป€เบฅเบตเปˆเบกโ€‹เบ•เบปเป‰เบ™โ€‹เบ—เบตเปˆโ€‹เบˆเบฐโ€‹เบฅเบงเบกโ€‹เบ—เบฑเบ‡โ€‹เบชเบญเบ‡ plugins เบ™เบตเป‰โ€‹เป€เบ›เบฑเบ™โ€‹เบซเบ™เบถเปˆเบ‡โ€‹ SonarJS, เบ—เบตเปˆเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบ„เบดเบ”เบงเปˆเบฒเบ–เบทเบเบ•เป‰เบญเบ‡.

เบ•เบญเบ™เบ™เบตเป‰เบ‚เป‰เบญเบเบขเบฒเบเบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเบ—เบฒเบ‡เป€เบฅเบทเบญเบเปƒเบ™เบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡เบ‚เปเป‰เบกเบนเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡.

เบกเบฒเบฎเบญเบ”เบ›เบฐเบˆเบธ, เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เป€เบซเบฑเบ™เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเปƒเบ™เบ‚เปเป‰เบเปเบฒเบ™เบปเบ”เบชเปˆเบงเบ™เบฎเป‰เบญเบเบชเปเบฒเบฅเบฑเบšเป‚เบ„เบ‡เบเบฒเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”, เปเบฅเบฐเบชเปเบฒเบฅเบฑเบšเป„เบŸเบฅเปŒเป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐ. เปเบ•เปˆเบกเบฑเบ™เป€เบ›เบฑเบ™เป„เบ›เป„เบ”เป‰เบ—เบตเปˆเบˆเบฐเบ‚เบฐเบซเบเบฒเบเบ•เบปเบงเบŠเบตเป‰เบงเบฑเบ”เบ™เบตเป‰เบ”เป‰เบงเบเบ‚เปเป‰เบกเบนเบ™เบเปˆเบฝเบงเบเบฑเบšเบ›เบฐเบฅเบดเบกเบฒเบ™ เบซเบ™เปˆเบงเบเบšเปเบฅเบดเบเบฒเบ™-tests เบชเปเบฒโ€‹เบฅเบฑเบšโ€‹เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹, เป€เบŠเบฑเปˆเบ™โ€‹เบ”เบฝเบงโ€‹เบเบฑเบ™โ€‹เบเบฑเบšโ€‹เปƒเบ™โ€‹เบชเบฐโ€‹เบžเบฒเบšโ€‹เบ‚เบญเบ‡โ€‹เป„เบŸเบฅโ€‹เปŒโ€‹.

เบกเบตเบซเป‰เบญเบ‡เบชเบฐเบซเบกเบธเบ”เบ—เบตเปˆเบชเบฒเบกเบฒเบ” เบกเบต- เบ›เปˆเบฝเบ™โ€‹เบšเบปเบ”โ€‹เบฅเบฒเบโ€‹เบ‡เบฒเบ™โ€‹เป€เบ›เบฑเบ™โ€‹เบฎเบนเบšโ€‹เปเบšเบšโ€‹เบชเปเบฒโ€‹เบฅเบฑเบšโ€‹เบเบฒเบ™โ€‹ sonar'A:
เบ‚เปเป‰โ€‹เบกเบนเบ™โ€‹เบเบฒเบ™โ€‹เบ—เบปเบ”โ€‹เบชเบญเบšโ€‹เบ—เบปเปˆเบงโ€‹เป„เบ›โ€‹ - https://docs.sonarqube.org/display/SONAR/Generic+Test+Data.

เบกเบฒเบ•เบดเบ”เบ•เบฑเป‰เบ‡เบซเป‰เบญเบ‡เบชเบฐเปเบธเบ”เบ™เบตเป‰เปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ:

yarn add jest-sonar-reporter

เปเบฅเบฐเป€เบžเบตเปˆเบกเบกเบฑเบ™เปƒเบชเปˆเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ เบกเบต:

package.json:

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

เบ•เบญเบ™เบ™เบตเป‰เปƒเบซเป‰เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš:

yarn test

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เป„เบŸเบฅเปŒเบˆเบฐเบ–เบทเบเบชเป‰เบฒเบ‡เบ‚เบทเป‰เบ™เปƒเบ™เบฎเบฒเบเบ‚เบญเบ‡เป‚เบ„เบ‡เบเบฒเบ™ test-report.xml.

เปƒเบซเป‰เป€เบฎเบปเบฒเปƒเบŠเป‰เบกเบฑเบ™เปƒเบ™เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ sonar'A:

sonar-project.properties:

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

เปเบฅเบฐเบฃเบตเบชเบฐเบ•เบฒเบ”เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™:

yarn run sonar

เปƒเบซเป‰เบ‚เบญเบ‡เป€เบšเบดเปˆเบ‡เบชเบดเปˆเบ‡เบ—เบตเปˆเบกเบตเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เปƒเบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบš sonar'A:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เปเบฅเบฐเบšเปเปˆเบกเบตเบซเบเบฑเบ‡เบ›เปˆเบฝเบ™เปเบ›เบ‡. เบ„เบงเบฒเบกเบˆเบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒ Sonar เบšเปเปˆเป„เบ”เป‰เบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเป„เบŸเบฅเปŒเบ—เบตเปˆเบญเบฐเบ—เบดเบšเบฒเบเป„เบงเป‰เปƒเบ™เบšเบปเบ”เบฅเบฒเบเบ‡เบฒเบ™ Jest เป€เบ›เบฑเบ™เป„เบŸเบฅเปŒ เบซเบ™เปˆเบงเบเบšเปเบฅเบดเบเบฒเบ™- เบเบฒเบ™โ€‹เบ—เบปเบ”โ€‹เบชเบญเบšโ€‹. เป€เบžเบทเปˆเบญเปเบเป‰เป„เบ‚เบชเบฐเบ–เบฒเบ™เบฐเบเบฒเบ™เบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเปƒเบŠเป‰เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ sonar sonar.tests, เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบŠเบตเป‰เบšเบญเบเบขเปˆเบฒเบ‡เบŠเบฑเบ”เป€เบˆเบ™เป‚เบŸเบ™เป€เบ”เบตเบ—เบตเปˆเบกเบตเบเบฒเบ™เบ—เบปเบ”เบชเบญเบš (เบžเบงเบเป€เบฎเบปเบฒเบกเบตเบžเบฝเบ‡เปเบ•เปˆเบซเบ™เบถเปˆเบ‡เบชเปเบฒเบฅเบฑเบšเปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™):

sonar-project.properties:

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

เบกเบฒเป€เบฅเบตเปˆเบกเป€เบ„เบทเปˆเบญเบ‡เบชเบฐเปเบเบ™เปƒเปเปˆ:

yarn run sonar

เบกเบฒเป€เบšเบดเปˆเบ‡เบชเบดเปˆเบ‡เบ—เบตเปˆเบกเบตเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เปƒเบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบš:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เป€เบซเบฑเบ™เบˆเปเบฒเบ™เบงเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ เบซเบ™เปˆเบงเบเบšเปเบฅเบดเบเบฒเบ™-tests เปเบฅเบฐ, เบชเบปเบšเบœเบปเบ™เบชเปเบฒเป€เบฅเบฑเบ”เป‚เบ”เบเบเบฒเบ™เบ„เบฅเบดเบเปƒเบชเปˆเบžเบฒเบเปƒเบ™, เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เป€เบซเบฑเบ™เบเบฒเบ™เปเบœเปˆเบเบฐเบˆเบฒเบเบ‚เบญเบ‡เบˆเปเบฒเบ™เบงเบ™เบ™เบตเป‰เปƒเบ™เบšเบฑเบ™เบ”เบฒเป„เบŸเบฅเปŒเป‚เบ„เบ‡เบเบฒเบ™:

เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เป‚เบ„เบ‡เบเบฒเบ™ VueJS+TS เบเบฑเบš SonarQube

เบชเบฐเบซเบฅเบธเบš

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เป€เบšเบดเปˆเบ‡เป€เบ„เบทเปˆเบญเบ‡เบกเบทเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบงเบดเป€เบ„เบฒเบฐเบขเปˆเบฒเบ‡เบ•เปเปˆเป€เบ™เบทเปˆเบญเบ‡ soundQube. เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹เป„เบ”เป‰โ€‹เบ›เบฐโ€‹เบชเบปเบกโ€‹เบ›เบฐโ€‹เบชเบฒเบ™โ€‹เบขเปˆเบฒเบ‡โ€‹เบชเปเบฒโ€‹เป€เบฅเบฑเบ”โ€‹เบœเบปเบ™โ€‹เป€เบ‚เบปเป‰เบฒโ€‹เป„เบ›โ€‹เปƒเบ™โ€‹เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹เป€เบ›เบฑเบ™โ€‹เบฅเบฒเบโ€‹เบฅเบฑเบโ€‹เบญเบฑเบโ€‹เบชเบญเบ™โ€‹เปƒเบ™โ€‹ VueJs+TS. เปเบเป‰เป„เบ‚เบšเบฑเบ™เบซเบฒเบ„เบงเบฒเบกเป€เบ‚เบปเป‰เบฒเบเบฑเบ™เป„เบ”เป‰เบšเบฒเบ‡เบขเปˆเบฒเบ‡. เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เป€เบžเบตเปˆเบกเป€เบ™เบทเป‰เบญเปƒเบ™เบ‚เปเป‰เบกเบนเบ™เบ‚เบญเบ‡เบ•เบปเบงเบŠเบตเป‰เบงเบฑเบ”เบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš. เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบเบงเบ”เป€เบšเบดเปˆเบ‡เบžเบฝเบ‡เปเบ•เปˆเบซเบ™เบถเปˆเบ‡เบ‚เบญเบ‡เป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบ„เบธเบ™เบ™เบฐเบžเบฒเบšเบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ” (เบšเบฒเบ‡เบ—เบตเบญเบฒเบ”เบˆเบฐเป€เบ›เบฑเบ™เบซเบ™เบถเปˆเบ‡เบ•เบปเป‰เบ™เบ•เป), เปเบ•เปˆ soundQube เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบกเบฒเบ”เบ•เบฐเบ–เบฒเบ™เบ„เบธเบ™เบ™เบฐเบžเบฒเบšเบญเบทเปˆเบ™เป†, เบฅเบงเบกเบ—เบฑเบ‡เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ„เบงเบฒเบกเบ›เบญเบ”เป„เบž. เปเบ•เปˆเบšเปเปˆเปเบกเปˆเบ™เบ„เบธเบ™เบชเบปเบกเบšเบฑเบ”เบ—เบฑเบ‡เปเบปเบ”เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบกเบตเบขเบนเปˆเปƒเบ™ เบŠเบธเบกเบŠเบปเบ™- เบชเบฐโ€‹เบšเบฑเบšโ€‹. เบซเบ™เบถเปˆเบ‡เปƒเบ™เบฅเบฑเบเบชเบฐเบ™เบฐเบ—เบตเปˆเบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆเปเบฅเบฐเป€เบ›เบฑเบ™เบ›เบฐเป‚เบซเบเบ”เปเบกเปˆเบ™เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡ soundQube เบเบฑเบšเบฅเบฐเบšเบปเบšเบเบฒเบ™เบˆเบฑเบ”เบเบฒเบ™เบ„เบฑเบ‡เป€เบเบฑเบšเบฅเบฐเบซเบฑเบ”เบ•เปˆเบฒเบ‡เป†, เป€เบŠเบฑเปˆเบ™ GitLab เปเบฅเบฐ BitBucket. เป€เบžเบทเปˆเบญเบ›เป‰เบญเบ‡เบเบฑเบ™ merge pull(merge) เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป'a เป„เบ›เบซเบฒเบชเบฒเบ‚เบฒเบ•เบปเป‰เบ™เบ•เปเบ‚เบญเบ‡ repository เปƒเบ™เป€เบงเบฅเบฒเบ—เบตเปˆเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบ–เบทเบเบŠเบธเบ”เป‚เบŠเบก. เปเบ•เปˆเบ™เบตเป‰เปเบกเปˆเบ™เป€เบฅเบทเปˆเบญเบ‡เบชเปเบฒเบฅเบฑเบšเบšเบปเบ”เบ„เบงเบฒเบกเบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™เบซเบกเบปเบ”.

PS: เบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เบ—เบตเปˆเบญเบฐเบ—เบดเบšเบฒเบเบขเบนเปˆเปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเปƒเบ™เบฎเบนเบšเปเบšเบšเบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ”เปเบกเปˆเบ™เบกเบตเบขเบนเปˆเปƒเบ™ เบชเป‰เบญเบกเบ‚เบญเบ‡เบ‚เป‰เบญเบ.

เบžเบฝเบ‡เปเบ•เปˆเบœเบนเป‰เปƒเบŠเป‰เบฅเบปเบ‡เบ—เบฐเบšเบฝเบ™เบชเบฒเบกเบฒเบ”เป€เบ‚เบปเป‰เบฒเบฎเปˆเบงเบกเปƒเบ™เบเบฒเบ™เบชเปเบฒเบซเบผเบงเบ”. เป€เบ‚เบปเป‰เบฒโ€‹เบชเบนเปˆโ€‹เบฅเบฐโ€‹เบšเบปเบšเบเบฐเบฅเบธเบ™เบฒ.

เป€เบˆเบปเป‰เบฒเปƒเบŠเป‰เป€เบงเบ—เบต SonarQube เบšเป:

  • 26,3%เปเบกเปˆเบ™เปเบฅเป‰เบง5

  • 15,8%เบงเบฑเบ™เบ—เบต 3

  • 15,8%เบ‚เป‰เบญเบเป„เบ”เป‰เบเบดเบ™เบเปˆเบฝเบงเบเบฑเบšเป€เบงเบ—เบตเบ™เบตเป‰เปเบฅเบฐเบ•เป‰เบญเบ‡เบเบฒเบ™เปƒเบŠเป‰ 3

  • 10,5%เบ‚เป‰เบญเบเป„เบ”เป‰เบเบดเบ™เบเปˆเบฝเบงเบเบฑเบšเป€เบงเบ—เบตเบ™เบตเป‰เปเบฅเบฐเบšเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เปƒเบŠเป‰ 2

  • 0,0%เบ‚เป‰เบญเบเบเปเบฒเบฅเบฑเบ‡เปƒเบŠเป‰เปเบžเบฅเบฐเบ•เบฐเบŸเบญเบกเบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™ 0

  • 31,6%เบ„เบฑเป‰เบ‡เบ—เปเบฒเบญเบดเบ”เบ—เบตเปˆเบ‚เป‰เบญเบเป„เบ”เป‰เบเบดเบ™เบเปˆเบฝเบงเบเบฑเบšเบ™เบฒเบ‡6

19 เบœเบนเป‰เปƒเบŠเป‰เบฅเบปเบ‡เบ„เบฐเปเบ™เบ™เบชเบฝเบ‡. 3 เบœเบนเป‰เปƒเบŠเป‰เบ‡เบปเบ”.

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™