אחרי דחיפה לאוויר צריך לדעת אם השינוי באמת שם. הבדיקה נראית פשוטה, ויש בה שלוש מלכודות שכולן מחזירות תשובה שנראית בדיוק כמו התוצאה הנכונה: עברית שמופיעה בבנדל בשתי צורות שונות, מחרוזת חיפוש שנבלעת ב-shell ומחזירה התאמה לכל שורה בקובץ, ומחרוזת שאינה ייחודית לשינוי. ה-Skill הזה נותן את שיטת האימות שעובדת בלי לפתוח דפדפן, ואת האזהרה שמונעת חסימה של האתר בגלל יותר מדי בקשות אוטומטיות. זהו Skill ל-Claude: תיקייה עם קובץ SKILL.md, שנטענת אוטומטית כשהמשימה מתאימה לתיאור שבראש הקובץ. בניגוד לפרומפט שמדביקים בכל פעם מחדש, Skill מותקן פעם אחת וממשיך לעבוד לבד.
קוד ואיכות · פריסה · Vercel · אימות · curl · בנדל
---
name: deploy-verify
description: "Verify that a deployed change is actually live on a static or Vercel site without opening a browser, using curl and a search inside the built bundle. Covers the Hebrew encoding trap, the shell escaping trap that fakes success, and why flooding the site with requests looks like an outage. Use when a change has just been pushed, when asked whether something is already deployed, or when a deploy looks broken but may not be."
---
# לאמת פריסה בלי דפדפן
## שלוש דרכים לקבל תשובה שגויה
כולן נראות בדיוק כמו התוצאה הנכונה. זו הסיבה שהקובץ הזה קיים.
### 1. עברית מופיעה בבנדל בשתי צורות
לפעמים כטקסט רגיל, ולפעמים כרצף `\uXXXX` **באותיות גדולות**. חיפוש
בצורה אחת בלבד מחזיר "הפריסה נכשלה" על פריסה מוצלחת לחלוטין.
תמיד לבדוק את שתיהן:
```js
const enc = (s) => [...s].map((c) =>
c.charCodeAt(0) > 127
? '\\u' + c.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')
: c).join('')
const ok = js.includes(phrase) || js.includes(enc(phrase))
```
### 2. בניית מחרוזת מקודדת בשורת הפקודה
ה-shell בולע את הבקסלשים, המשתנה יוצא ריק, ו-`grep -c ""` מחזיר את
מספר **כל השורות בקובץ**. כך התקבל דיווח על אלפי התאמות בחיפוש של כלום.
**לכתוב סקריפט לקובץ ולהריץ אותו.** לא פקודה חד שורתית עם עברית או עם
בקסלשים.
### 3. מחרוזת שאינה ייחודית לשינוי
ביטוי שמופיע גם במקום אחר גורם לבדיקה לדווח שההסרה נכשלה, בזמן שהיא
הצליחה.
לבחור מחרוזת שקיימת רק בשינוי הזה, **ולבדוק גם את הכיוון ההפוך**: שהנוסח
הישן נעלם.
## הבדיקה שעובדת
```js
const html = await fetch('https://example.com/', {
headers: { 'User-Agent': 'Mozilla/5.0 Chrome/124' },
}).then((r) => r.text())
const name = html.match(/assets\/index-[A-Za-z0-9_-]*\.js/)[0]
const js = await fetch('https://example.com/' + name).then((r) => r.text())
for (const [label, s, want] of [
['הנוסח החדש', 'המחרוזת החדשה', true],
['הנוסח הישן', 'המחרוזת הישנה', false],
]) {
const has = js.includes(s) || js.includes(enc(s))
console.log(label, has === want ? 'תקין' : 'נכשל')
}
```
## השוואת שמות הקבצים
שם הקובץ **עשוי** להיות שונה באופן לגיטימי, כי פלטפורמת הבנייה עובדת עם
משתני סביבה משלה. לכן שם שונה אינו הוכחה לכישלון. כשהשמות כן יוצאים
זהים, השוואת תוכן בית-בית היא אימות מלא בבקשה אחת.
**האימות החזק הוא לפי תוכן, לא לפי שם.**
## אזהרה: לא להציף את האתר
סריקה של עשרות כתובות ברצף, או לולאה שמושכת שוב ושוב, מפעילה את ההגנה
האוטומטית של פלטפורמות אירוח ומחזירה שגיאת חסימה **לכל כתובת מאותו IP**.
זה נראה בדיוק כמו אתר שנפל, ומבזבז שעה על אבחון תקלה שאתם יצרתם.
לאמת בבקשה אחת אחרי המתנה. לסריקה של הרבה עמודים, לעבוד על תיקיית
הבנייה המקומית ולא על האתר החי.
## אתר עם service worker
אתר שמאחסן מראש עשרות מגהבייט מקריס חלוניות דפדפן מוטמעות. לאמת עם
בקשות רשת בלבד.
וגולש חוזר מקבל את הגרסה מהמטמון עד שה-service worker מתעדכן. "אני לא
רואה את השינוי" אצל המשתמש אינו בהכרח פריסה שנכשלה.
## קוד יציאה אפס אינו הצלחה
פקודה שרצה ברקע יכולה להחזיר אפס, לייצר קובץ ריק, ובגוף הפלט לכתוב
שהעבודה נכשלה. קוד היציאה תיאר את העטיפה, לא את העבודה.
**תמיד לאמת שהתוצר עצמו קיים**, ולא להסתמך על קוד יציאה או על הודעת
סיום.
כליקס לא הצליח להיטען
נסו קודם לרענן את העמוד. אם בדיוק עלתה גרסה חדשה, רענון פותר את זה מיד.
אם הרענון לא עזר, ייתכן שהדפדפן ישן מדי: כליקס מריץ את הכלים על המכשיר שלכם ולא בשרת, ולכן הוא זקוק לדפדפן מ-2022 ומעלה. מה עושים: לעדכן את Chrome או את Firefox, ולפתוח שוב את klixtools.com.