- การทำ Code Review ด้วย SonarQube สำหรับ React และ Laravel
- 3. ติดตั้ง SonarQube ด้วย Docker Compose
- 4. สร้าง Project และ Token
- 5. การตรวจสอบ React ด้วย SonarQube
- 6. ตัวอย่างปัญหา React ที่ SonarQube ช่วยตรวจพบ
- 7. การตรวจสอบ Laravel ด้วย SonarQube
- 8. ตัวอย่างปัญหา Laravel ที่ควรตรวจสอบ
- 9. React + Laravel แบบ Monorepo
- 10. Quality Gate คืออะไร
- 11. Quality Profile
- 12. ใช้ SonarQube กับ GitHub Actions
- 13. ทำให้ CI/CD หยุดเมื่อ Quality Gate ไม่ผ่าน
- 14. Community Build กับ Pull Request Review
- 15. SonarQube ไม่ได้แทน Human Code Review
- 16. Workflow ที่แนะนำสำหรับ React + Laravel
- 17. แนวทางใช้งานในทีมพัฒนา
- 18. Checklist
- 19. สรุป
#การทำ Code Review ด้วย SonarQube สำหรับ React และ Laravel
การตรวจสอบคุณภาพโค้ดก่อนนำขึ้นระบบจริงไม่ควรพึ่งเฉพาะการอ่านโค้ดโดยนักพัฒนาเท่านั้น เพราะปัญหาหลายประเภท เช่น โค้ดซ้ำ ความซับซ้อน ช่องโหว่ หรือ Code Smell สามารถตรวจจับแบบอัตโนมัติได้
SonarQube เป็นแพลตฟอร์มสำหรับทำ Static Code Analysis และ Automated Code Review โดยสามารถนำไปใช้ในกระบวนการพัฒนา React และ Laravel รวมถึงเชื่อมต่อกับ CI/CD เพื่อกำหนดว่าโค้ดที่ไม่ผ่านมาตรฐานจะไม่สามารถผ่าน Quality Gate ได้
SonarQube ไม่ได้แทนที่ Human Code Review แต่ทำหน้าที่เป็น Automated Reviewer เพื่อช่วยตรวจจับปัญหาที่สามารถตรวจสอบด้วยกฎและการวิเคราะห์แบบ Static Analysis ก่อนให้นักพัฒนาตรวจสอบ Design, Business Logic และ Architecture ต่อไป
#1. SonarQube ตรวจสอบอะไรได้บ้าง
SonarQube วิเคราะห์ Source Code แล้วรายงานประเด็นด้านคุณภาพและความปลอดภัย เช่น
- Reliability
- Maintainability
- Security
- Security Hotspots
- Duplicated Code
- Complexity
- Test Coverage
- Coding Standard
- Technical Debt
แนวคิดโดยรวมสามารถเขียนเป็น Pipeline ได้ดังนี้
Developer
│
▼
Git Push / Pull Request
│
▼
Unit Test + Coverage
│
▼
SonarScanner
│
▼
SonarQube Server
│
├── Reliability
├── Security
├── Maintainability
├── Duplication
└── Coverage
│
▼
Quality Gate
│
├── PASS → Build / Deploy
└── FAIL → แก้ไขโค้ด
#2. React และ Laravel ใช้กับ SonarQube ได้หรือไม่
ได้
SonarQube รองรับการวิเคราะห์ JavaScript และ TypeScript และระบุ React JSX เป็นหนึ่งใน Framework/Tool ที่รองรับ
สำหรับฝั่ง Backend ตัว PHP Analyzer รองรับ Laravel โดยตรง
ดังนั้น Full Stack Application ที่ใช้
React
+
Laravel API
+
SonarQube
สามารถนำทั้ง Frontend และ Backend เข้าสู่กระบวนการตรวจสอบคุณภาพโค้ดได้
#3. ติดตั้ง SonarQube ด้วย Docker Compose
สำหรับเครื่อง Development สามารถรัน SonarQube Community Build ด้วย Docker Compose ได้
สร้างไฟล์
docker-compose.yml
ตัวอย่าง
services:
sonarqube:
image: sonarqube:community
container_name: sonarqube
depends_on:
- db
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarqube
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
ports:
- "9000:9000"
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
db:
image: postgres:17-alpine
container_name: sonarqube-db
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
POSTGRES_DB: sonarqube
volumes:
- postgresql_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
postgresql_data:
รัน
docker compose up -d
ตรวจสอบ Container
docker compose ps
จากนั้นเปิด
http://localhost:9000
สำหรับการติดตั้งครั้งแรกให้เข้าสู่ระบบและเปลี่ยนรหัสผ่านผู้ดูแลระบบตามขั้นตอนของ SonarQube
สำหรับ Production ควร Pin Docker Image เป็น Version ที่ต้องการแทนการอ้างอิง Tag แบบลอย และควรใช้ Database, Backup, TLS/Reverse Proxy และ Resource Configuration ที่เหมาะสมกับระบบจริง
#4. สร้าง Project และ Token
ใน SonarQube ให้สร้าง Project เช่น
react-app
laravel-api
หรือถ้าเป็น Monorepo อาจสร้างเป็น
fullstack-app
จากนั้นสร้าง Analysis Token
ตัวอย่าง
SONAR_TOKEN=sqp_xxxxxxxxxxxxxxxxx
ไม่ควรเขียน Token ลงใน Source Code หรือ Commit ลง Git
แนะนำให้เก็บเป็น
Environment Variable
หรือ
GitHub Actions Secrets
#5. การตรวจสอบ React ด้วย SonarQube
สมมติ Project
react-app/
├── src/
├── public/
├── coverage/
├── package.json
├── vite.config.ts
└── sonar-project.properties
#5.1 สร้าง Test Coverage
SonarQube ไม่ได้รัน Unit Test ให้เรา แต่จะอ่าน Coverage Report ที่สร้างจาก Test Framework
ตัวอย่าง React + Vitest
ติดตั้ง
npm install -D vitest @vitest/coverage-v8
ใน package.json
{
"scripts": {
"test": "vitest",
"test:coverage": "vitest run --coverage"
}
}
ตัวอย่าง vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'lcov']
}
}
})
รัน
npm run test:coverage
จะได้ไฟล์ เช่น
coverage/lcov.info
SonarQube ใช้ LCOV Report สำหรับ Coverage ของ JavaScript/TypeScript
#5.2 สร้าง sonar-project.properties สำหรับ React
สร้าง
sonar-project.properties
ตัวอย่าง
sonar.projectKey=react-app
sonar.projectName=React App
sonar.sources=src
sonar.tests=src
sonar.test.inclusions=**/*.test.js,**/*.test.jsx,**/*.test.ts,**/*.test.tsx,**/*.spec.js,**/*.spec.jsx,**/*.spec.ts,**/*.spec.tsx
sonar.exclusions=**/*.test.js,**/*.test.jsx,**/*.test.ts,**/*.test.tsx,**/*.spec.js,**/*.spec.jsx,**/*.spec.ts,**/*.spec.tsx,**/node_modules/**,**/dist/**,**/coverage/**
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.sourceEncoding=UTF-8
#5.3 รัน SonarScanner
กำหนด Environment Variable
Linux/macOS
export SONAR_HOST_URL=http://localhost:9000
export SONAR_TOKEN=sqp_xxxxxxxxx
จากนั้น
sonar-scanner
เมื่อ Scan เสร็จให้เปิด SonarQube Dashboard
React App
├── Issues
├── Security
├── Reliability
├── Maintainability
├── Coverage
└── Duplications
#6. ตัวอย่างปัญหา React ที่ SonarQube ช่วยตรวจพบ
ตัวอย่าง
function UserProfile({ user }: any) {
if (user != null) {
console.log(user)
}
return (
<div>
{user.name}
</div>
)
}
ประเด็นที่ Automated Code Review อาจช่วยชี้ให้เห็นขึ้นอยู่กับ Rule/Profile ที่เปิดใช้ เช่น
- ใช้
anyมากเกินไป - Logic ที่อาจทำให้เกิด Null/Undefined Problem
- Debug/Console Code ที่ไม่ควรอยู่ใน Production
- Code Smell
- Complexity
- Duplicate Logic
แนวทางปรับปรุงอาจเป็น
type User = {
id: number
name: string
}
type Props = {
user?: User
}
export function UserProfile({ user }: Props) {
if (!user) {
return <p>User not found</p>
}
return (
<div>
{user.name}
</div>
)
}
#7. การตรวจสอบ Laravel ด้วย SonarQube
ตัวอย่าง Project
laravel-api/
├── app/
├── bootstrap/
├── config/
├── database/
├── routes/
├── tests/
├── vendor/
├── composer.json
└── sonar-project.properties
#7.1 สร้าง PHPUnit Coverage
Laravel สามารถใช้ PHPUnit สร้าง Clover XML Coverage Report ได้
เครื่องที่รัน Coverage ต้องมี Coverage Driver เช่น Xdebug หรือ PCOV
ตัวอย่าง
./vendor/bin/phpunit --coverage-clover coverage.xml
จะได้
coverage.xml
SonarQube สามารถอ่าน PHP Coverage ในรูปแบบ Clover XML
#7.2 sonar-project.properties สำหรับ Laravel
sonar.projectKey=laravel-api
sonar.projectName=Laravel API
sonar.sources=app,routes,config,database
sonar.tests=tests
sonar.exclusions=vendor/**,storage/**,bootstrap/cache/**,public/build/**,node_modules/**
sonar.php.coverage.reportPaths=coverage.xml
sonar.sourceEncoding=UTF-8
จากนั้นรัน
sonar-scanner
#8. ตัวอย่างปัญหา Laravel ที่ควรตรวจสอบ
ตัวอย่าง Controller
public function show($id)
{
$user = DB::select(
"SELECT * FROM users WHERE id = " . $id
);
return response()->json($user);
}
Code ลักษณะนี้ควรได้รับการตรวจสอบอย่างจริงจัง เพราะการต่อ SQL String กับ Input จากภายนอกสามารถสร้างความเสี่ยงด้าน Security ได้
แนวทางที่ปลอดภัยกว่า เช่นใช้ Eloquent
public function show(int $id)
{
$user = User::findOrFail($id);
return response()->json($user);
}
หรือใช้ Query Builder/Parameterized Query ตามความเหมาะสม
#9. React + Laravel แบบ Monorepo
ตัวอย่าง
fullstack-app/
├── frontend/
│ ├── src/
│ ├── coverage/
│ └── package.json
│
├── backend/
│ ├── app/
│ ├── routes/
│ ├── tests/
│ └── coverage.xml
│
└── sonar-project.properties
สามารถ Scan ทั้งสองภาษาใน Project เดียวได้
ตัวอย่าง
sonar.projectKey=fullstack-app
sonar.projectName=React Laravel Full Stack
sonar.sources=frontend/src,backend/app,backend/routes,backend/config
sonar.tests=frontend/src,backend/tests
sonar.test.inclusions=frontend/src/**/*.test.js,frontend/src/**/*.test.jsx,frontend/src/**/*.test.ts,frontend/src/**/*.test.tsx,frontend/src/**/*.spec.js,frontend/src/**/*.spec.jsx,frontend/src/**/*.spec.ts,frontend/src/**/*.spec.tsx,backend/tests/**
sonar.exclusions=frontend/src/**/*.test.js,frontend/src/**/*.test.jsx,frontend/src/**/*.test.ts,frontend/src/**/*.test.tsx,frontend/src/**/*.spec.js,frontend/src/**/*.spec.jsx,frontend/src/**/*.spec.ts,frontend/src/**/*.spec.tsx,frontend/node_modules/**,frontend/dist/**,frontend/coverage/**,backend/vendor/**,backend/storage/**,backend/bootstrap/cache/**
sonar.javascript.lcov.reportPaths=frontend/coverage/lcov.info
sonar.php.coverage.reportPaths=backend/coverage.xml
sonar.sourceEncoding=UTF-8
Workflow คือ
React Tests
│
└── coverage/lcov.info
│
▼
SonarScanner
▲
│
┌───────┘
│
Laravel Tests
│
└── coverage.xml
SonarQube จะรวมข้อมูล Static Analysis และ Coverage ของหลายภาษาไว้ใน Dashboard ของ Project เดียว
#10. Quality Gate คืออะไร
Quality Gate คือเงื่อนไขที่ใช้ตัดสินว่า Code Quality ผ่านเกณฑ์หรือไม่
แนวคิดตัวอย่าง
Coverage >= 80%
Duplicated Code <= 3%
New Critical Issues = 0
Security Hotspots ต้องได้รับการ Review
SonarQube มี Quality Gate มาตรฐานของระบบ และสามารถสร้าง Custom Quality Gate ให้เหมาะกับทีมได้
แนวทางที่แนะนำคือให้ความสำคัญกับ New Code ก่อน เพื่อป้องกันไม่ให้ Technical Debt ใหม่เพิ่มเข้ามาในระบบ
#11. Quality Profile
Quality Profile คือชุดของ Rules สำหรับแต่ละภาษา
เช่น
JavaScript / TypeScript
├── Reliability Rules
├── Security Rules
└── Maintainability Rules
PHP
├── Reliability Rules
├── Security Rules
└── Maintainability Rules
ทีมสามารถสร้าง Custom Quality Profile เพื่อเปิด/ปิด Rules ให้สอดคล้องกับ Coding Standard ขององค์กรได้
#12. ใช้ SonarQube กับ GitHub Actions
ตัวอย่าง Workflow สำหรับ Repository ที่มี
frontend = React
backend = Laravel
สร้าง
.github/workflows/sonarqube.yml
name: SonarQube Analysis
on:
push:
branches:
- main
jobs:
sonar:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Install React dependencies
working-directory: frontend
run: npm ci
- name: React tests and coverage
working-directory: frontend
run: npm run test:coverage
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
coverage: xdebug
- name: Install Laravel dependencies
working-directory: backend
run: composer install --no-interaction --prefer-dist
- name: Laravel tests and coverage
working-directory: backend
run: ./vendor/bin/phpunit --coverage-clover coverage.xml
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v8
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
กำหนด GitHub Secrets
SONAR_TOKEN
SONAR_HOST_URL
ตัวอย่าง
SONAR_HOST_URL=https://sonarqube.example.com
หาก SonarQube อยู่ใน Private Network ที่ GitHub-hosted Runner เข้าถึงไม่ได้ ควรใช้ Self-hosted Runner หรือออกแบบ Network Access ที่ปลอดภัย ไม่ควรเปิด SonarQube ออกอินเทอร์เน็ตโดยไม่มี TLS, Authentication และ Network Protection ที่เหมาะสม
#13. ทำให้ CI/CD หยุดเมื่อ Quality Gate ไม่ผ่าน
สามารถกำหนดให้ Scanner รอผล Quality Gate ได้ เช่น
sonar.qualitygate.wait=true
แนวคิด Pipeline จะเป็น
Push Code
│
▼
Test
│
▼
Coverage
│
▼
SonarQube Scan
│
▼
Quality Gate
│
├── PASS ──► Build / Deploy
│
└── FAIL ──► Stop Pipeline
ช่วยป้องกัน Code ที่ไม่ผ่านเกณฑ์เข้าสู่ Production
#14. Community Build กับ Pull Request Review
SonarQube Community Build เหมาะสำหรับการวิเคราะห์ Main Branch และเริ่มต้นใช้งาน Automated Code Review
หากต้องการความสามารถระดับ
Feature Branch Analysis
Pull Request Analysis
Pull Request Decoration
ควรตรวจสอบ Edition ของ SonarQube ที่ใช้งาน เพราะความสามารถในการวิเคราะห์หลาย Branch และ Pull Request เป็นความสามารถของ SonarQube Server ระดับสูงกว่าชุด Community Build
ดังนั้นในการสอนหรือทดลองสามารถเริ่มจาก
SonarQube Community Build
+
main branch analysis
จากนั้นจึงขยายไปสู่ PR-based Quality Gate เมื่อระบบต้องการ Workflow ที่เข้มขึ้น
#15. SonarQube ไม่ได้แทน Human Code Review
สิ่งที่ SonarQube เหมาะกับการตรวจสอบ
Syntax / Static Pattern
Code Smell
Security Rule
Duplication
Complexity
Coverage
Coding Standard
แต่ Human Reviewer ยังควรตรวจ
Business Logic
Architecture
Domain Model
API Design
UX
Naming Context
Performance Architecture
Maintainability เชิงระบบ
ความถูกต้องตาม Requirement
แนวทางที่เหมาะสมคือ
Automated Review
+
Human Review
+
Automated Test
#16. Workflow ที่แนะนำสำหรับ React + Laravel
Developer
│
▼
Feature Development
│
├── React
└── Laravel
│
▼
Lint
│
▼
Unit Test
│
├── Vitest/Jest
└── PHPUnit/Pest
│
▼
Coverage Report
│
├── LCOV
└── Clover XML
│
▼
SonarScanner
│
▼
SonarQube
│
▼
Quality Gate
│
├── PASS
│ │
│ ▼
│ Human Review
│ │
│ ▼
│ Merge
│
└── FAIL
│
▼
Fix Code
#17. แนวทางใช้งานในทีมพัฒนา
สำหรับทีมขนาดเล็ก
Developer
↓
Push
↓
CI Test
↓
SonarQube
↓
Merge
สำหรับทีมที่ต้องการ Quality Control มากขึ้น
Developer
↓
Pull Request
↓
Automated Test
↓
SonarQube Analysis
↓
Quality Gate
↓
Human Code Review
↓
Merge
↓
Deploy
#18. Checklist
ก่อน Merge Code สามารถใช้ Checklist ดังนี้
[ ] Unit Test ผ่าน
[ ] Coverage Report ถูกสร้าง
[ ] SonarQube Scan สำเร็จ
[ ] Quality Gate ผ่าน
[ ] ไม่มี Issue ระดับสำคัญที่ยังไม่ได้จัดการ
[ ] Security Hotspot ได้รับการ Review
[ ] Duplicated Code อยู่ในเกณฑ์
[ ] New Code Coverage ผ่านเกณฑ์
[ ] Human Code Review ผ่าน
#19. สรุป
การนำ SonarQube มาใช้กับ React และ Laravel ช่วยเพิ่ม Automated Quality Control ให้กับกระบวนการพัฒนาซอฟต์แวร์
โครงสร้างที่แนะนำคือ
React
│
├── Vitest/Jest
└── LCOV
│
▼
SonarQube
▲
│
Laravel
│
├── PHPUnit/Pest
└── Clover XML
จากนั้นใช้ Quality Gate เป็นเกณฑ์ควบคุมก่อน Merge หรือ Deploy
แนวคิดสำคัญที่สุดไม่ใช่การพยายามแก้ Technical Debt เก่าทั้งหมดในครั้งเดียว แต่คือการทำให้ New Code มีคุณภาพ และไม่เพิ่มปัญหาใหม่เข้าไปในระบบ
#References
-
SonarQube Server — JavaScript/TypeScript/CSS
https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/languages/javascript-typescript-css -
SonarQube Server — PHP
https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/languages/php -
SonarQube Community Build — Analysis Overview
https://docs.sonarsource.com/sonarqube-community-build/analyzing-source-code/analysis-overview -
SonarQube Server — SonarScanner CLI
https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/scanners/sonarscanner -
SonarQube Server — Test Coverage Parameters
https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/test-coverage/test-coverage-parameters -
SonarQube Server — Quality Gates
https://docs.sonarsource.com/sonarqube-server/quality-standards-administration/managing-quality-gates/introduction-to-quality-gates -
SonarQube Server — Quality Profiles
https://docs.sonarsource.com/sonarqube-server/quality-standards-administration/managing-quality-profiles/introduction -
Official SonarQube Docker Image
https://hub.docker.com/_/sonarqube -
Official SonarQube Scan GitHub Action
https://github.com/SonarSource/sonarqube-scan-action