Masalah DX pada Proyek Django Tradisional
Pengembangan proyek Django dalam tim sering menghadapi tiga friksi developer experience (DX):
- Tool sprawl dan inkonsistensi format: Penggunaan kombinasi Flake8, Black, dan isort memperlambat feedback loop lokal dan sering menghasilkan konflik konfigurasi antar-developer.
- Kesalahan syntax DTL lolos ke runtime: Django Template Language (DTL) tidak diverifikasi saat interpreter Python membaca kode. Tag template yang tidak ditutup (misalnya
{% if %}tanpa{% endif %}) baru terdeteksi saat view di-render di browser atau saat test runner dijalankan. - Bottleneck pada review PR: Code review terbuang untuk mengomentari spasi, urutan import, atau style template HTML, sementara pipeline CI berjalan lambat akibat menjalankan multiple linter lawas.
Solusinya adalah mengonsolidasikan tooling ke dua komponen modern: Ruff untuk Python (termasuk ruleset Django) dan djLint untuk template DTL, yang diikat langsung via pre-commit hook.
Konfigurasi pyproject.toml
Satukan konfigurasi Ruff dan djLint ke dalam pyproject.toml di root direktori proyek. Konfigurasi ini mengaktifkan linter, auto-formatter, sorting import, dan ruleset flake8-django (kode DJ).
[tool.ruff]
line-length = 88
target-version = "py312"
exclude = [
"*/migrations/*",
".venv",
"staticfiles",
]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort (import sorting)
"UP", # pyupgrade
"DJ", # flake8-django
]
ignore = [
"DJ001", # Hindari warning Model.objects.all() bila tidak relevan
]
[tool.ruff.lint.isort]
known-first-party = ["my_project"]
[tool.djlint]
profile = "django"
indent = 2
max_line_length = 120
blank_line_after_tag = "extends,load"
ignore = "H006,H031"
format_css = true
format_js = true
Konfigurasi .pre-commit-config.yaml
Pre-commit memastikan eksekusi otomatis sebelum commit dibuat di git history. Buat file .pre-commit-config.yaml di root direktori:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9
hooks:
# Linter & autofix (import sorting, ruleset DJ, syntax updates)
- id: ruff
args: [--fix]
# Code formatter pengganti Black
- id: ruff-format
- repo: https://github.com/djlint/djLint
rev: v1.35.2
hooks:
- id: djlint-reformat-django
- id: djlint-django
Catatan: Jalankan perintahpre-commit installsekali di environment lokal Anda untuk mendaftarkan hook ke dalam.git/hooks/pre-commit.
Alur Eksekusi Lokal: Deteksi dan Auto-Fix
Ketika developer menulis kode dengan import berantakan pada views.py dan tag HTML yang rusak pada template DTL, pre-commit mengeksekusi pemeriksaan secara instan.
Contoh Kasus 1: views.py
# Sebelum commit (views.py)
from django.http import JsonResponse
import sys
from .models import Item
import os
def index(request):
return JsonResponse({"status": "ok"})
Contoh Kasus 2: index.html
<!-- Sebelum commit (templates/index.html) -->
{% extends "base.html" %}
{% block content %}
<div class="container">
<h1>Halo Dunia</h1>
<!-- Tag block sengaja tidak ditutup -->
Output Eksekusi Git Hook
$ git add views.py templates/index.html
$ git commit -m "feat: update view and template"
trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check yaml...........................................(no files to check)Skipped
check for added large files..............................................Passed
ruff.....................................................................Failed
- hook id: ruff
- files were modified by this hook
Found 2 errors (2 fixed, 0 remaining).
Sorted imports in views.py.
Removed unused imports: sys, os.
ruff-format..............................................................Passed
djlint-reformat-django...................................................Passed
djlint-django............................................................Failed
- hook id: djlint-django
- exit code: 1
templates/index.html
4:1 DJ011 Tag `block` on line 2 is never closed. (django-tags)
Hasil eksekusi:
- Ruff otomatis merapikan import dan menghapus modul
ossertasysyang tidak digunakan, lalu membatalkan commit agar perubahan dapat di-stage ulang. - djLint memblokir commit karena menemukan tag
{% block %}yang tidak memiliki penutup{% endblock %}, mencegah runtime error di production.
Integrasi pada Pipeline CI (GitHub Actions)
Developer dapat melewati hook lokal menggunakan flag git commit --no-verify. Untuk menjaga standar di repository bersama, jalankan verifikasi pre-commit yang sama di pipeline CI.
Tambahkan file .github/workflows/lint.yml:
name: Code Quality
on:
pull_request:
branches: [main, master]
push:
branches: [main, master]
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pre-commit
- name: Run pre-commit hooks
run: pre-commit run --all-files --show-diff-on-failure
Trade-off dan Limitasi
- djLint Regex Parser: djLint mengandalkan parser berbasis regex dan AST parsial untuk template, bukan parser Django C-level native. Pada struktur template yang sangat kompleks atau tag kustom non-standar, abaikan rule spesifik via konfigurasi
ignoredipyproject.toml. - Cache pre-commit: Saat memperbarui versi hook di
.pre-commit-config.yaml, jalankanpre-commit autoupdatedan bersihkan cache viapre-commit cleanjika ditemukan inkonsistensi binary Ruff lokal.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!