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.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill shoul…
3.7K installsUse when doing ANY task involving Supabase. Triggers: Supabase products (Database, Auth, Edge F…
1.7K installsReact Native and Expo best practices for building performant mobile apps. Use when building Rea…
1.3K installsHandles the full DMS Schema Conversion lifecycle including creating migration projects, convert…
29 installsConvert HTML and Markdown content into Portable Text blocks for Sanity.
10 installsUse this skill when the user is doing DOCA version handling — detecting the installed release, …
118 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 ใหม่