איך משתמשים ב-Baseline בפרויקט

1. מבוא

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

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

2. הגדרת ההדגמה במחשב המקומי

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

git clone git@github.com:GoogleChromeLabs/baseline-demos.git
cd baseline-demos/tooling/webpack

בשלב הזה, ההדגמה כבר תכלול את Baseline, אבל כדאי לבדוק קומיט שמתחיל מאפס:

git checkout d3793f25

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

nvm install
nvm use

מכאן, מתקינים את החבילות של הפרויקט:

npm install

כדי לראות את ההדגמה, מריצים את הפקודה הבאה:

npm start

עוברים אל http://localhost:8080. ההדגמה עצמה היא רשימה של כרטיסים שאפשר לסנן באמצעות שדה טופס בחלק העליון של הדף. האפליקציה עצמה משתמשת בשילוב של תכונות שהגיעו לסף של Baseline.

בסיום ההדגמה, עוברים לטרמינל ומקישים על Ctrl+C כדי להפסיק את ההרצה של ההדגמה בכל שלב.

3. איך משלבים את Baseline בפרויקט

בהדגמה הזו לא מצוינת הגדרת Browserslist בהתחלה. ‫Browserslist היא תחביר קומפקטי של שאילתות שמציין לשרשרות כלים אילו גרסאות דפדפן מינימליות צריכות להיות נתמכות. לדוגמה, שימוש בשאלת last 3 years יגדיר טווח רחב של יעדים. בהדגמה הזו נציין שאילתת Browserslist שתואמת ליעדי Baseline שבהם אפשר להשתמש בשרשרת הכלים. יעדי בסיס יכולים להיות אחת מהאפשרויות הבאות:

  • יעדים משתנים, שמתעדכנים לאורך זמן עם יציאת דפדפנים חדשים:
    • Baseline Newly available, שמתייחס לתכונות חדשות שניתנות להפעלה הדדית ומיושמות בכל הדפדפנים העיקריים בכל זמן שהוא מהיום ועד לפני 30 חודשים.
    • Baseline Widely available, שכולל תכונות שניתנות להפעלה הדדית והוטמעו בסט הליבה של הדפדפנים לפני 30 חודשים או יותר.
  • טירגוטים קבועים, שמייצגים גרסאות של דפדפנים בנקודת זמן קבועה. הם מופיעים כשנים מ-2016 עד השנה הנוכחית.

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

"browserslist": "baseline widely available"

4. בחירה ביעדי בסיס שונים כדי לראות שינויים בפלט של הקוד

בחרת עכשיו ב-Baseline Widely available כיעד לפרויקט ההדגמה. בשלב הבא, צריך לבנות את הפרויקט:

npm run build

יש הרבה פלט נוסף כי האפשרות debug ל-@babel/preset-env מוגדרת כ-true ב-babel.config.js של הפרויקט. קודם כול, מציינים את הגודל של ה-CSS ושל ה-JavaScript בנתונים הסטטיסטיים של ה-bundler:

assets by status 213 KiB [emitted]
  asset js/home.5f3c5480.js 208 KiB [emitted] [immutable] [minimized] (name: home) 2 related assets
  asset css/home.20db50ef.css 3.64 KiB [emitted] [immutable] (name: home) 1 related asset
  asset index.html 564 bytes [emitted]

שימו לב שחבילת ה-JavaScript היא 208KiB, וקובץ ה-CSS הוא 3.64KiB. הפרויקט הזה משתמש ב-core-js כדי להחיל polyfills של JavaScript וב-autoprefixer כדי להחיל קידומות ספציפיות לספקים על מאפייני CSS שעדיין לא ניתנים להפעלה הדדית באופן מלא. ההגדרות core-js ו-autoprefixer מושפעות מהשאילתה שנבחרה ב-Browserslist של דפדפני הבסיס.

עוד דבר שחשוב לשים לב אליו בפלט הוא איך השאילתה שלכם ב-Browserslist לגבי Baseline Widely available מתורגמת לשאילתה ב-Browserslist. בפרויקט, זה ייראה בערך כך:

Using targets: {
  "chrome": "108",
  "edge": "108",
  "firefox": "108",
  "ios": "16",
  "safari": "16"
}

שימו לב ל-polyfills שמוזרקים על ידי core-js בפלט של ה-build:

The corejs3 polyfill added the following polyfills:
  es.iterator.constructor { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }
  es.iterator.filter { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }
  es.iterator.map { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }

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

"browserslist": "baseline 2016"

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

npm run build

קודם כל, שימו לב לשינוי בגודל הקובץ של JavaScript ו-CSS של הפרויקט בנתוני ה-bundler:

assets by status 237 KiB [emitted]
  asset js/home.b228612d.js 232 KiB [emitted] [immutable] [minimized] (name: home) 2 related assets
  asset css/home.0c3e4fd7.css 3.91 KiB [emitted] [immutable] (name: home) 1 related asset
  asset index.html 564 bytes [emitted]

אפשר לראות שגודל חבילת ה-JavaScript גדל בכמעט 30KiB. קובץ ה-CSS של הפרויקט גדול רק במעט, כי autoprefixer הוסיף עוד קידומות ספקים על סמך היעד הבסיסי משנת 2016. שימו לב גם לשינוי בשאילתת Browserslist:

Using targets: {
  "chrome": "53",
  "edge": "14",
  "firefox": "49",
  "ios": "10",
  "safari": "10"
}

בהשוואה ליעד הבסיסי שזמין באופן נרחב, גרסאות הדפדפן האלה הן מוקדמות בהרבה – מוקדמות מספיק כדי שגרסת Edge שהוגדרה כיעד במקרה הזה היא גרסה שלפני Chromium.

גם הפוליפילים שמוזרקים על ידי core-js ישתנו, וזה הרבה יותר מאשר אם נבחר היעד 'זמינות בסיסית':

The corejs3 polyfill added the following polyfills:
  es.array.filter { "edge":"14" }
  es.iterator.constructor { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.iterator.filter { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.object.to-string { "edge":"14", "firefox":"49" }
  es.array.includes { "firefox":"49" }
  es.string.includes { "edge":"14" }
  es.array.map { "firefox":"49" }
  es.iterator.map { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.symbol { "edge":"14", "firefox":"49" }
  es.symbol.description { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.array.iterator { "chrome":"53", "edge":"14", "firefox":"49" }
  web.dom-collections.iterator { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.array.push { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.regexp.to-string { "edge":"14" }
  es.array.from { "edge":"14", "firefox":"49" }
  es.regexp.exec { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
  es.regexp.test { "edge":"14" }
  es.error.cause { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }

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

5. טירגוט דפדפנים במורד הזרם

לסיכום, קבוצת הדפדפנים העיקרית שאליה מכוונת Baseline כוללת את הדפדפנים הבאים:

  • Chrome
  • ‫Chrome ב-Android
  • Firefox
  • ‫Firefox ב-Android
  • Edge
  • ‫Safari ב-macOS
  • ‫Safari ב-iOS

עם זאת, אפשר לטרגט דפדפנים שנקראים 'דפדפנים במורד הזרם'. הדפדפנים האלה הם דפדפנים שהמנועים שלהם נגזרים מדפדפן שנכלל בקבוצת הדפדפנים המרכזיים – לרוב Chromium. הדפדפנים האלה כוללים את Opera,‏ Samsung Internet ועוד. אפשר לטרגט את הדפדפנים האלה בנוסף לדפדפנים שנכללים בסט הדפדפנים הבסיסי, על ידי הוספת with downstream לכל שאילתה תקפה של Baseline Browserslist:

"browserslist": "baseline widely available with downstream"

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

npm start

לאחר מכן, שימו לב לשינוי בשאילתת Browserslist:

Using targets: {
  "android": "108",
  "chrome": "108",
  "edge": "108",
  "firefox": "108",
  "ios": "16",
  "opera": "94",
  "opera_mobile": "80",
  "safari": "16",
  "samsung": "21"
}

אפשר גם לטרגט דפדפנים במורד הזרם לפי שנה. לדוגמה:

"browserslist": "baseline 2016 with downstream"

בהגדרה הזו, השאילתה של Browserslist תשתנה בהתאם:

Using targets: {
  "android": "53",
  "chrome": "53",
  "edge": "14",
  "firefox": "49",
  "ios": "10",
  "opera": "40",
  "opera_mobile": "80",
  "safari": "10",
  "samsung": "6.2"
}

6. כלי Linter וכלים אחרים

שאילתות הבסיס שמוטמעות ב-Browserslist נוחות לשימוש בכלים כמו bundlers וחלקים אחרים בשרשרת הכלים, אבל יש גם ערך בכלים אחרים, כמו linters, שאימצו יעדי בסיס כחלק מההגדרה שלהם.

דוגמה טובה לתמיכה של כלי Linter ב-Baseline היא ESLint, שבמסגרת בדיקת ה-CSS שלו מספק כלל use-baseline באמצעות @eslint/css שמאפשר לכם לטרגט את Baseline Newly,‏ Baseline Widely available או Baseline years. יש גם כלל דומה בחבילה של קהילת @html-eslint/eslint-plugin שמאפשר לעשות את אותו הדבר לגבי תכונות HTML בקובץ eslint.config.js:

export default [
  /* Omitted JS linting rules ... */
  // Lint CSS files for Baseline:
  {
    files: ["**/*.css"],
    plugins: {
      css
    },
    language: "css/css",
    rules: {
      "css/no-duplicate-imports": "error",
      // Lint CSS files to make sure they are using
      // only Baseline Widely available features:
      "css/use-baseline": ["warn", {
        available: "widely"
      }]
    },
  },
  // Lint HTML and JSX files for Baseline:
  {
    files: ["**/*.html"],
    ...html.configs["flat/recommended"],
    rules: {
      // Lint HTML files to make sure they are using
      // only Baseline Widely available features:
      "@html-eslint/use-baseline": ["warn", {
        available: "widely"
      }]
    }
  }
];

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

  1. חבילות ה-linting של HTML ו-CSS משתמשות בכלל use-baseline, והוא מוגדר כזמין באופן נרחב באמצעות אפשרות ההגדרה available: "widely".
  2. בשני חבילות ה-linting, רמת היומן להפרות של ה-linter מוגדרת ל-"warn". אפשר להגדיר את הערך "error" כדי להפסיק את התהליך עם קוד שגיאה, וכך למנוע את הבנייה.

יכול להיות שראיתם את הפלט של הכלי לבדיקת קוד כשמריצים את הפקודה npm run build, אבל כדי לראות רק את הפלט של הכלי לבדיקת קוד, אפשר להריץ את הפקודה הבאה:

npm run lint

בפלט שיוצג לכם יופיעו כמה אזהרות לגבי ה-CSS של הפרויקט:

/var/www/baseline-demos/tooling/webpack-browserslist-config-baseline/src/css/normalize.css
  222:3  warning  Property 'outline' is not a widely available baseline feature  css/use-baseline

/var/www/baseline-demos/tooling/webpack-browserslist-config-baseline/src/css/styles.css
  62:3   warning  Property 'outline' is not a widely available baseline feature                                css/use-baseline
  81:23  warning  Value 'subgrid' of property 'grid-template-rows' is not a widely available baseline feature  css/use-baseline

7. סיכום

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

בנוסף, יש גרסה של ההדגמה הזו שפועלת ב-Rollup, ואפשר להשתמש בהדגמה הזו כדי לבצע את רוב השלבים ב-Codelab הזה.

תמיכה ב-Baseline מתחילה להופיע גם בכלי חבילות אחרים. לדוגמה, Vite, שמשתמש ב-Rollup מתחת לפני השטח, מכוון עכשיו כברירת מחדל ל-Baseline Widely available browsers מאז גרסה 7.

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