Standar Coding
Gaya Kode dan Konvensi
Section titled “Gaya Kode dan Konvensi”Mengikuti standar coding yang konsisten membuat codebase lebih mudah dibaca, dipelihara, dan dikontribusikan.
Standar Kode Go
Section titled “Standar Kode Go”Format Kode
Section titled “Format Kode”Gunakan alat format Go standar:
# Format all codegofmt -w .
# Use goimports for import organizationgoimports -w .Wajib: Semua kode Go harus lulus gofmt dan goimports sebelum commit.
Konvensi Penamaan
Section titled “Konvensi Penamaan”Paket:
- Huruf kecil, satu kata jika memungkinkan
package application,package events- Hindari underscore atau mixed caps
Nama Exported:
- PascalCase untuk tipe, fungsi, konstanta
type WebviewWindow struct,func NewApplication()
Nama Unexported:
- camelCase untuk tipe, fungsi, variabel internal
type windowImpl struct,func createWindow()
Interface:
- Dinamai berdasarkan perilaku:
Reader,Writer,Handler - Interface satu method: nama dengan akhiran
-er
// Goodtype Closer interface { Close() error}
// Avoidtype CloseInterface interface { Close() error}Penanganan Error
Section titled “Penanganan Error”Selalu periksa error:
// Goodresult, err := doSomething()if err != nil { return fmt.Errorf("failed to do something: %w", err)}
// Bad - ignoring errorsresult, _ := doSomething()Gunakan error wrapping:
// Wrap errors to provide contextif err := validate(); err != nil { return fmt.Errorf("validation failed: %w", err)}Buat tipe error kustom jika diperlukan:
type ValidationError struct { Field string Value string}
func (e *ValidationError) Error() string { return fmt.Sprintf("invalid value %q for field %q", e.Value, e.Field)}Komentar dan Dokumentasi
Section titled “Komentar dan Dokumentasi”Komentar paket:
// Package application provides the core Wails application runtime.//// It handles window management, event dispatching, and service lifecycle.package applicationDeklarasi exported:
// NewApplication creates a new Wails application with the given options.//// The application must be started with Run() or RunWithContext().func NewApplication(opts Options) *Application { // ...}Komentar implementasi:
// processEvent handles incoming events from the runtime.// It dispatches to registered handlers and manages event lifecycle.func (a *Application) processEvent(event *Event) { // Validate event before processing if event == nil { return }
// Find and invoke handlers // ...}Struktur Fungsi dan Method
Section titled “Struktur Fungsi dan Method”Jaga fungsi tetap fokus:
// Good - single responsibilityfunc (w *Window) setTitle(title string) { w.title = title w.updateNativeTitle()}
// Bad - doing too muchfunc (w *Window) updateEverything() { w.setTitle(w.title) w.setSize(w.width, w.height) w.setPosition(w.x, w.y) // ... 20 more operations}Gunakan early return:
// Goodfunc validate(input string) error { if input == "" { return errors.New("empty input") }
if len(input) > 100 { return errors.New("input too long") }
return nil}
// Avoid deep nestingConcurrency
Section titled “Concurrency”Gunakan context untuk pembatalan:
func (a *Application) RunWithContext(ctx context.Context) error { select { case <-ctx.Done(): return ctx.Err() case <-a.done: return nil }}Lindungi state bersama dengan mutex:
type SafeCounter struct { mu sync.Mutex count int}
func (c *SafeCounter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.count++}Hindari goroutine leak:
// Good - goroutine has exit conditionfunc (a *Application) startWorker(ctx context.Context) { go func() { for { select { case <-ctx.Done(): return // Clean exit case work := <-a.workChan: a.process(work) } } }()}Testing
Section titled “Testing”Penamaan file test:
// Tests: window_test.goTable-driven test:
func TestValidate(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"empty input", "", true}, {"valid input", "hello", false}, {"too long", strings.Repeat("a", 101), true}, }
for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := validate(tt.input) if (err != nil) != tt.wantErr { t.Errorf("validate() error = %v, wantErr %v", err, tt.wantErr) } }) }}Standar JavaScript/TypeScript
Section titled “Standar JavaScript/TypeScript”Format Kode
Section titled “Format Kode”Gunakan Prettier untuk format konsisten:
{ "semi": false, "singleQuote": true, "tabWidth": 2, "trailingComma": "es5"}Konvensi Penamaan
Section titled “Konvensi Penamaan”Variabel dan fungsi:
- camelCase:
const userName = "John"
Class dan tipe:
- PascalCase:
class WindowManager
Konstanta:
- UPPER_SNAKE_CASE:
const MAX_RETRIES = 3
TypeScript
Section titled “TypeScript”Gunakan tipe eksplisit:
// Goodfunction greet(name: string): string { return `Hello, ${name}`}
// Avoid implicit anyfunction process(data) { // Bad return data}Definisikan interface:
interface WindowOptions { title: string width: number height: number}
function createWindow(options: WindowOptions): void { // ...}Format Pesan Commit
Section titled “Format Pesan Commit”Gunakan Conventional Commits:
<type>(<scope>): <subject>
<body>
<footer>Tipe:
feat: Fitur barufix: Perbaikan bugdocs: Perubahan dokumentasirefactor: Refactoring kodetest: Menambah atau memperbarui teschore: Tugas maintenance
Contoh:
feat(window): add SetAlwaysOnTop method
Implement SetAlwaysOnTop for keeping windows above others.Adds platform implementations for macOS, Windows, and Linux.
Closes #123fix(events): prevent event handler memory leak
Event listeners were not being properly cleaned up whenwindows were closed. This adds explicit cleanup in thewindow destructor.Panduan Pull Request
Section titled “Panduan Pull Request”Sebelum Submit
Section titled “Sebelum Submit”- Kode lulus
gofmtdangoimports - Semua tes lulus (
go test ./...) - Kode baru memiliki tes
- Dokumentasi diperbarui jika diperlukan
- Pesan commit mengikuti konvensi
- Tidak ada konflik merge dengan
master
Template Deskripsi PR
Section titled “Template Deskripsi PR”## DescriptionBrief description of what this PR does.
## Type of Change- [ ] Bug fix- [ ] New feature- [ ] Breaking change- [ ] Documentation update
## TestingHow was this tested?
## Checklist- [ ] Tests pass- [ ] Documentation updated- [ ] No breaking changes (or documented)Proses Code Review
Section titled “Proses Code Review”Sebagai Reviewer
Section titled “Sebagai Reviewer”- Bersikap konstruktif dan hormat
- Fokus pada kualitas kode, bukan preferensi pribadi
- Jelaskan mengapa perubahan disarankan
- Setujui setelah puas
Sebagai Author
Section titled “Sebagai Author”- Tanggapi semua komentar
- Minta klarifikasi jika diperlukan
- Lakukan perubahan yang diminta atau jelaskan mengapa tidak
- Terbuka terhadap feedback
Praktik Terbaik
Section titled “Praktik Terbaik”Performa
Section titled “Performa”- Hindari optimisasi prematur
- Profil sebelum mengoptimalkan
- Gunakan benchmark untuk kode kritis performa
func BenchmarkProcess(b *testing.B) { for i := 0; i < b.N; i++ { process(testData) }}Keamanan
Section titled “Keamanan”- Validasi semua input pengguna
- Sanitasi data sebelum ditampilkan
- Gunakan
crypto/randuntuk data acak - Jangan pernah log informasi sensitif
Dokumentasi
Section titled “Dokumentasi”- Dokumentasikan API exported
- Sertakan contoh dalam dokumentasi
- Perbarui docs saat mengubah API
- Jaga README tetap mutakhir
Kode Spesifik Platform
Section titled “Kode Spesifik Platform”Penamaan File
Section titled “Penamaan File”window.go // Common interfacewindow_darwin.go // macOS implementationwindow_windows.go // Windows implementationwindow_linux.go // Linux implementationBuild Tags
Section titled “Build Tags”//go:build darwin
package application
// macOS-specific codeLinting
Section titled “Linting”Jalankan linter sebelum commit:
# golangci-lint (recommended)golangci-lint run
# Individual lintersgo vet ./...staticcheck ./...Pertanyaan?
Section titled “Pertanyaan?”Jika Anda tidak yakin tentang standar apa pun:
- Periksa kode yang ada untuk contoh
- Tanya di Discord
- Buka diskusi di GitHub