Summary
ใช้ skill นี้เมื่อ user ไม่เห็น version ใหม่หลัง deploy, browser โหลด JS เก่า, หรือ popup แจ้ง version update ขึ้นซ้ำ / ไม่ขึ้นเลย — แก้ bug VersionChecker ใน project ที่ใช้ react-ts-template-2023
pratchaya0/ssd-agent-skills · Archived
ใช้ skill นี้เมื่อ user ไม่เห็น version ใหม่หลัง deploy, browser โหลด JS เก่า, หรือ popup แจ้ง version update ขึ้นซ้ำ / ไม่ขึ้นเลย — แก้ bug VersionChecker ใน project ที่ใช้ react-ts-template-2023
npx skills add pratchaya0/ssd-agent-skills --skill ssd-bug-std-version-checker
ใช้ skill นี้เมื่อ user ไม่เห็น version ใหม่หลัง deploy, browser โหลด JS เก่า, หรือ popup แจ้ง version update ขึ้นซ้ำ / ไม่ขึ้นเลย — แก้ bug VersionChecker ใน project ที่ใช้ react-ts-template-2023
This repository is archived — consider an actively maintained alternative.
มาตรฐานการพัฒนาซอฟต์แวร์ของทีม SSD: React/TypeScript, .NET Core, Python, Git — ใช้เมื่อเขียนโค้…
37 installsใช้ skill นี้เมื่อใช้งาน Redux ใน React, สร้าง slice, ตั้งค่า rootReducer, หรือ dispatch/subscr…
2 installsใช้ skill นี้เมื่อสร้าง form ใน React ด้วย Formik, ต้องการ validation, ปรับแต่ง MUI component ใ…
2 installsใช้ skill นี้เมื่อเขียน React component, กำหนด Props type, ใช้ Refs/Fragments, ตั้งชื่อ compone…
2 installsRelated neighbors and high-traction skills in the same topics — useful to compare before installing.
Use when doing ANY task involving Supabase. Triggers: Supabase products (Database, Auth, Edge F…
263K installsHandles the full DMS Schema Conversion lifecycle including creating migration projects, convert…
3.2K installsOther skills from pratchaya0/ssd-agent-skills.
npx skills add pratchaya0/ssd-agent-skills
Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.
main
Parsed from SKILL.md frontmatter.
Files included with this skill beyond the listing page.
SKILL.md
7,194 B
SUMMARY.md
373 B
config.json อัปเดตแล้วแต่ browser ยังอ่านค่าเก่าvite.config.ts: chunkFileNames ไม่มี [hash] → browser cache JS chunk เก่าหลัง deployVersionChecker.tsx: emptyCache() เป็น sync → window.location.reload() ยิงก่อน cache ถูกลบจริงVersionChecker.tsx: ไม่มี guard → getData() ถูกเรียกซ้อนกัน, popup ซ้ำ, reload ซ้ำVersionChecker.tsx: fetch ใช้ browser cache → อ่าน config.json เก่าvite.config.tsเพิ่ม [hash] ใน chunkFileNames — สำคัญที่สุด บังคับ browser โหลด JS ใหม่ทุกครั้งที่ deploy
output: {
entryFileNames: `assets/js/[name].[hash].js`,
assetFileNames: `assets/[ext]/[name].[hash].[ext]`,
chunkFileNames: `assets/js/[name].[hash].js`, // ก่อนหน้านี้ไม่มี [hash]
},
src/app/layout/components/VersionChecker.tsxแทนที่ไฟล์ทั้งหมดด้วย version ที่แก้ไขแล้ว:
import React, { useEffect, useRef } from "react";
import { APP_INFO, VERSION_CHECKER } from "../../../Const";
import { swalConfirm } from "../../modules/_common";
function VersionChecker() {
const { version } = APP_INFO;
const { CHECK_VERSION_EVERY_MINUTE, CONFIRM_BEFORE_REFRESH, ENABLE_VERSION_CHECKER } = VERSION_CHECKER;
const isCheckingRef = useRef(false);
const isPromptOpenRef = useRef(false);
const isReloadingRef = useRef(false);
const checkVersionLoop = 1000 * 60 * CHECK_VERSION_EVERY_MINUTE;
const getData = async () => {
// guard: ป้องกันเรียกซ้อน
if (!ENABLE_VERSION_CHECKER || isCheckingRef.current || isReloadingRef.current) {
return;
}
isCheckingRef.current = true;
try {
const response = await fetch(`${window.location.origin}/config.json`, {
cache: "no-store", // บังคับไม่ใช้ browser cache
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
});
if (!response.ok) {
throw new Error(`Failed to fetch config.json: ${response.status}`);
}
const configData = await response.json();
if (configData.version !== version) {
if (CONFIRM_BEFORE_REFRESH) {
if (isPromptOpenRef.current) {
return; // ป้องกัน popup ซ้ำ
}
isPromptOpenRef.current = true;
try {
const res = await swalConfirm("Warning", "Your version is outdated. Refresh now?");
if (res.isConfirmed) {
await emptyCache();
}
} finally {
isPromptOpenRef.current = false;
}
} else {
await emptyCache();
}
}
} catch (error) {
console.error("Version check failed", error); // ไม่ใช้ alert()
} finally {
isCheckingRef.current = false;
}
};
const emptyCache = async () => {
if (isReloadingRef.current) {
return; // ป้องกัน reload ซ้ำ
}
isReloadingRef.current = true;
try {
if ("caches" in window) {
const names = await caches.keys();
// await ให้ลบ cache เสร็จก่อนค่อย reload
await Promise.all(names.map((name) => caches.delete(name)));
}
} finally {
window.location.reload();
}
};
useEffect(() => {
void getData();
const interval = setInterval(() => {
void getData();
}, checkVersionLoop);
return () => clearInterval(interval);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return <></>;
}
export default VersionChecker;
| จุดที่เปลี่ยน | ก่อน | หลัง | เหตุผล |
|---|---|---|---|
chunkFileNames |
[name].js |
[name].[hash].js |
บังคับ browser โหลด JS ใหม่หลัง deploy |
emptyCache |
sync, forEach | async, Promise.all + await |
รับประกันว่า cache ถูกลบก่อน reload |
| guard refs | ไม่มี | isCheckingRef, isPromptOpenRef, isReloadingRef |
ป้องกัน race condition |
| fetch cache | browser default | cache: "no-store" |
ป้องกันอ่าน config.json เก่า |
| error handling | alert() |
console.error() |
ไม่รบกวน user เมื่อ network fail ชั่วคราว |
| prompt text | "your version is out-dated..." |
"Your version is outdated. Refresh now?" |
ภาษาที่อ่านง่ายขึ้น |
# 1. Build ต้องผ่าน
npm run build
# 2. ตรวจว่า chunk files มี hash ใน dist/
ls dist/assets/js/
# ควรเห็น: index.abc123.js, vendor.def456.js (มี hash ทุกไฟล์)
# 3. ทดสอบ flow
# - เปิด DevTools → Network tab → เปิด "Disable cache"
# - Reload หน้า → ตรวจว่า config.json fetch มี Cache-Control: no-store
# - เปลี่ยน version ใน config.json → รอ interval หรือ reload → popup ต้องขึ้น 1 ครั้งเท่านั้น
# - กด refresh → หน้าต้องโหลด version ใหม่