Profile
Published on

איך לשלב Prettier בפרויקט קיים

Authors

זה לגמרי הגיוני למחוק חתיכה של קוד ולהשאיר רווח  מעצבן  כזה , כי אחרי שנייה, בצורה אוטומטית בIDE או אוטומטית האצבעות לוחצות על Format Document. אבל זה הופך להיות לא הגיוני כשמפתח לא מקפיד על זה (וראיתי דברים). ואז מה? להעיר לו בCode Review על רווח מיותר? באמת?

אז יש לנו פרויקטים חיים ובועטים, עם קוד ישן ומכוער, וגם פרויקטים חדשים עם מתכנתים ישנים ומכוערים (כמובן שלא), ואנחנו רוצים להתחיל לשלוט בהם.

נו, מה הבעיה?

בגדול, יש לנו שתי דרכים לגשת לזה, ולכל אחת מהן יש מחיר כואב:

1. שינוי לאורך זמן

בגישה זו, אנחנו מחילים את הפורמט רק על קבצים שנגענו בהם.

הבעיה: זה הופך את ה-Code Review לסיוט. קשה להבדיל בין שינויי לוגיקה לבין שינויי עיצוב ("רעש"), ומפתחים שונאים לראות שינויים מאסיביים ב-PR שלהם בקבצים שהם בקושי נגעו בהם.

2. הגישה הכוללת

לפרמט את כל הפרויקט בבת-אחת.

הבעיה: זה יוצר שני מכשולים עיקריים. הראשון הוא Merge Conflicts מול כל מי שמחזיק גרסה לוקאלית לא עדכנית. השני, והחמור יותר, הוא אובדן ההיסטוריה. ברגע שקומיט אחד נוגע בכל השורות בקוד, פקודת git blame הופכת לחסרת תועלת. במקום לראות מי כתב את הלוגיקה המקורית, אנחנו תמיד נאשים את מי שנגע בכל הקוד כדי לפרמט אותו.

הבחירה שלי: לפרמט הכל

למה? כי את בעיית הקונפליקטים קל לפתור (אם כולם מריצים Prettier, הקונפליקטים נעלמים), ואת בעיית ההיסטוריה אפשר לפתור בעזרת פיצ'ר חכם (ופחות מוכר) של Git שמאפשר לנו "להעלים" קומיטים ספציפיים מההיסטוריה.

כדי שהקסם הזה יעבוד בלי תקלות, אנחנו לא זורקים את הכל בקומיט אחד ענק. במקום זה, נפצל את המהלך לשני שלבים (שני קומיטים) נפרדים (טוב, עדיין אחד מהם יהיה ענק), כשלכל אחד מטרה ברורה:

קומיט 1: הניקוי הגדול

בשלב הזה אנחנו מריצים את ה-Prettier על כל הקבצים בפרויקט.

הקומיט הזה הולך להיות ענק מבחינת כמות השורות שהוא משנה, אבל הוא חייב להכיל שינויי עיצוב בלבד (White-space, פסיקים, רווחים). שום לוגיקה לא משתנה כאן.

המטרה: ליישר קו שבו כל הקוד בפרויקט עומד בסטנדרט החדש. את הקומיט הזה אנחנו הולכים "להעלים" אחר כך.

קומיט 2: מנגנונים לשמירה על המצב הקיים

מיד אחרי הניקוי, אנחנו מכניסים את התשתית שתשמור על הסדר:

  1. אוטומציה (Husky + Lint-staged): כדי לוודא שכל קובץ חדש או ערוך יעבור פירמוט אוטומטי לפני שהוא נכנס לגיט.

  2. בדיקות (CI): כדי למנוע מ-PR לא מפורמט להיכנס ל-Main.

  3. ההסתרה (Git Blame Ignore): כאן אנחנו מוסיפים קובץ קונפיגורציה מיוחד שאומר לגיט: "רואה את הקומיט הקודם (קומיט 1)? תתעלם ממנו כשאתה מחשב git blame".

למה חייבים לפצל?

זה הקטע הקריטי. הפיצ'ר של גיט שמתעלם מקומיטים (ignore-revs) עובד ברמת הקומיט השלם.

אם נערבב את שינויי הפורמט יחד עם שינויי הקונפיגורציה (הוספת סקריפטים ל-package.json, הגדרות CI וכו') בקומיט אחד, ונבקש מגיט להתעלם ממנו – אנחנו בעצם "נעלים" מההיסטוריה גם את השינויים התשתיתיים החשובים האלו.

הפיצול מבטיח שרק "הרעש" של הפירמוט ייעלם, בעוד ששינויי התשתית יישארו גלויים וברורים בהיסטוריה.


איך מיישמים את זה בפועל

עכשיו, בואו נעשה את זה צעד אחר צעד.

שלב 1: קומיט הניקוי הגדול

אם לא התקנתם את prettier בפרויקט, תעצרו רגע ותתקינו עם קונפיגורציה.

עכשיו, הרגע האמיתי – נריץ את Prettier על כל הפרויקט:

npx prettier . --write

חשוב: לפני שממשיכים, וודאו שהרצתם את הפרויקט והבדיקות עברו בהצלחה. השלב הזה חייב לשנות רק פורמט, לא לוגיקה.

עכשיו נעשה commit:

git add .
git commit -m "chore: format entire codebase with prettier"

הקטע הקריטי ביותר: מיד אחרי הקומיט, תשמרו את ה-SHA שלו:

git rev-parse HEAD

הפלט יהיה משהו כמו: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0

העתיקו את ה-SHA הזה למקום זמני (Notepad, מסמך, או סתם תשאירו את הטרמינל פתוח). נצטרך אותו בשלב הבא!

שלב 2: קומיט התשתית והסתרת ההיסטוריה

עכשיו נתקין את הכלים שישמרו על הסדר מכאן והלאה:

npm install --save-dev husky lint-staged
npx husky init

נגדיר את lint-staged בקובץ package.json:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx,json,css,md,mdx}": ["prettier --write"]
  }
}

נוסיף Pre-commit Hook. פתחו את הקובץ .husky/pre-commit והוסיפו:

npx lint-staged

עכשיו הקסם: ניצור קובץ בשם .git-blame-ignore-revs בשורש הפרויקט, ונדביק לתוכו את ה-SHA ששמרנו קודם:

# Format entire codebase with prettier
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0

זהו! עכשיו נעשה commit לכל השינויים האלו:

git add .
git commit -m "chore: add prettier automation and ignore formatting commit"

שלב 3: אוטומציה של הקונפיגורציה

יש בעיה קטנה: גיט לא משתמש בקובץ .git-blame-ignore-revs באופן אוטומטי. כל מפתח צריך להגדיר את זה ידנית במחשב שלו.

הפתרון? נוסיף סקריפט postinstall ב-package.json שיגדיר את זה אוטומטית:

{
  "scripts": {
    "postinstall": "git config --local blame.ignoreRevsFile .git-blame-ignore-revs || true"
  }
}

הסקריפט הזה ירוץ אוטומטית אחרי כל npm install, וידאג שהקונפיגורציה המקומית של Git תצביע על הקובץ שלנו.

ה-|| true בסוף מוודא שהסקריפט לא ייכשל אם משהו השתבש (למשל, אם מישהו הריץ npm install מחוץ לריפו של Git).

שלב 4: הגנה ב-CI

כדי למנוע מקוד לא מפורמט להיכנס למאסטר, נוסיף בדיקה ל-CI Pipeline (למשל ב-GitHub Actions):

name: Code Quality

on: [pull_request]

jobs:
  format-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '24'
      - run: npm ci
      - run: npx prettier . --check

הפקודה --check לא משנה קבצים, היא רק בודקת אם הם מפורמטים נכון. אם לא – ה-CI ייכשל.


בדיקה: האם זה עובד?

בואו נוודא שהכל עבד כמו שצריך. נריץ git blame על קובץ שהשתנה בקומיט הפורמט:

git blame src/utils/helpers.js

אם ההגדרה עבדה, אתם אמורים לראות את מי שכתב את הקוד המקורי, לא את הקומיט שפירמט אותו.

סיכום

השיטה הזו נותנת לנו את הטוב משני העולמות:

✅ פורמט אחיד על כל הפרויקט
✅ היסטוריה נקייה ב-git blame
✅ אכיפה אוטומטית של הסטנדרט בעתיד
✅ מניעת regression ב-CI

כן, זה לוקח קצת זמן להתקין. אבל אחרי שעושים את זה פעם אחת, כל הצוות נהנה מקוד נקי ועקבי בלי לשלם על זה במטבע של היסטוריה מבולגנת.

טיפ אחרון: כשאתם מריצים את זה בפרויקט אמיתי, תעדכנו את כל הצוות מראש. תבקשו מכולם למשוך את השינויים ולהריץ npm install מיד אחרי המיזוג למאסטר, כדי למנוע קונפליקטים מיותרים.

בהצלחה! 🚀