✓ เสร็จแล้ว
JSON Diff Visualizer
เว็บ tool สำหรับเปรียบ JSON สอง version แบบ side-by-side พร้อม highlight การเปลี่ยนแปลงแบบ nested
สารบัญ
ปัญหาที่แก้
เมื่อ API response เปลี่ยน หรือ config เก่ากับใหม่ต่างกัน ต้องการเห็นความต่างชัดๆ แบบ nested โดยไม่ต้องใช้ jq หรือ diff ใน terminal
ฟีเจอร์
- วางหรือพิมพ์ JSON ทั้งสองฝั่งได้เลย
- แสดงความต่างเป็น tree — ไม่ใช่แค่ text diff
- เขียว = เพิ่มใหม่, แดง = ลบออก, เหลือง = เปลี่ยนค่า
- คลิก node เพื่อ expand/collapse nested objects
- copy path ของ key ที่เปลี่ยนแปลง (เช่น
user.address.city) - แสดง diff stats: N added, M removed, K changed
Stack
- Astro (static, island)
- TypeScript — diff algorithm
- ไม่มี library diff — เขียน recursive diff เอง
Diff Algorithm
type DiffResult =
| { type: 'unchanged'; value: unknown }
| { type: 'added'; value: unknown }
| { type: 'removed'; value: unknown }
| { type: 'changed'; from: unknown; to: unknown }
| { type: 'object'; children: Record<string, DiffResult> }
| { type: 'array'; children: DiffResult[] };
function diffJson(left: unknown, right: unknown): DiffResult {
if (left === right) return { type: 'unchanged', value: left };
if (isPlainObject(left) && isPlainObject(right)) {
const keys = new Set([...Object.keys(left), ...Object.keys(right)]);
const children: Record<string, DiffResult> = {};
for (const key of keys) {
if (!(key in left)) children[key] = { type: 'added', value: right[key] };
else if (!(key in right)) children[key] = { type: 'removed', value: left[key] };
else children[key] = diffJson(left[key], right[key]);
}
return { type: 'object', children };
}
if (Array.isArray(left) && Array.isArray(right)) {
const children = Array.from(
{ length: Math.max(left.length, right.length) },
(_, i) => {
if (i >= left.length) return { type: 'added', value: right[i] };
if (i >= right.length) return { type: 'removed', value: left[i] };
return diffJson(left[i], right[i]);
}
);
return { type: 'array', children };
}
return { type: 'changed', from: left, to: right };
}
สิ่งที่เรียนรู้
- เขียน recursive tree comparison ที่ handle nested objects/arrays ได้ถูกต้อง
- Render tree ที่ collapsible โดยไม่ใช้ framework (Vanilla JS + custom element)
- Handle edge case:
nullvsundefined, empty array vs empty object, number0vsfalse
ลิ้งค์
เว็บ tool พร้อมใช้งานทั้งหมดเป็น Astro static page — ทำงานได้ 100% ฝั่ง client ไม่มี server ไม่มีข้อมูล upload ออกไปไหน