نحوه استفاده از Baseline در پروژه

۱. مقدمه

Baseline ابتکاری است که پیام‌های واضح‌تری در مورد اینکه کدام ویژگی‌های وب امروزه قابل تعامل و استفاده ایمن هستند، ارائه می‌دهد. به لطف پیشرفت‌ها در ابزار Baseline، اکنون می‌توانید از Baseline مستقیماً در پروژه‌های خود به عنوان یک پرس‌وجوی Browserslist استفاده کنید تا زنجیره ابزار شما بتواند خروجی کد را بر اساس هدف Baseline که انتخاب می‌کنید تغییر دهد.

در این آزمایشگاه کد، شما یاد خواهید گرفت که چگونه از Baseline در یک پروژه نمونه استفاده کنید و چگونه آن را برای انتخاب یک هدف Baseline خاص پیکربندی کنید. همچنین مشاهده خواهید کرد که چگونه خروجی ابزار پروژه بسته به هدف Baseline که انتخاب کرده‌اید، تغییر می‌کند.

۲. نسخه آزمایشی را روی دستگاه محلی خود تنظیم کنید

ابتدا به برنامه ترمینال مورد نظر خود بروید، مخزن نسخه آزمایشی را کلون کنید و سپس وارد دایرکتوری پروژه شوید:

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 بروید. خودِ نسخه آزمایشی، فهرستی از کارت‌ها است که با استفاده از یک فیلد فرم در بالای صفحه قابل فیلتر کردن است. خود برنامه از ترکیبی از ویژگی‌هایی استفاده می‌کند که به آستانه پایه رسیده‌اند.

وقتی کار با نسخه آزمایشی تمام شد، به ترمینال خود بروید و Ctrl+C را فشار دهید تا اجرای نسخه آزمایشی در هر زمانی متوقف شود.

۳. نحوه ادغام Baseline در پروژه

این دمو در ابتدا پیکربندی Browserslist را مشخص نمی‌کند. Browserslist یک سینتکس پرس‌وجوی فشرده است که به زنجیره ابزارها می‌گوید حداقل نسخه‌های مرورگر باید پشتیبانی شوند. برای مثال، استفاده از یک پرس‌وجوی last 3 years طیف گسترده‌ای از اهداف را مشخص می‌کند. در این دمو، یک پرس‌وجوی Browserslist را مشخص می‌کنیم که با اهداف Baseline که می‌توانید در زنجیره ابزار خود استفاده کنید، همسو باشد. اهداف Baseline می‌توانند یکی از موارد زیر باشند:

  • اهداف متحرک ، که با انتشار مرورگرهای جدید به مرور زمان به‌روزرسانی می‌شوند:
    • نسخه پایه (Baseline) که به تازگی در دسترس قرار گرفته است ، ویژگی‌های سازگار پیاده‌سازی شده در مجموعه مرورگر اصلی را از زمان حال تا 30 ماه پیش، همسو می‌کند.
    • نسخه پایه به طور گسترده در دسترس است ، که شامل ویژگی‌های سازگار است که از 30 ماه پیش یا بیشتر در مجموعه مرورگرهای اصلی پیاده‌سازی شده‌اند.
  • اهداف ثابت ، که نشان دهنده نسخه‌های مرورگر در یک نقطه زمانی ثابت هستند. این اهداف به صورت سال از ۲۰۱۶ تا سال جاری بیان می‌شوند.

برای شروع، هدف متحرک Baseline Widely available را برای پروژه انتخاب می‌کنیم. برای انجام این کار، package.json را باز کنید و موارد زیر را اضافه کنید:

"browserslist": "baseline widely available"

۴. مشاهده تغییرات در خروجی کد با انتخاب اهداف مختلف خط پایه

شما همین الان Baseline Widely available را به عنوان هدف برای پروژه آزمایشی انتخاب کردید. در مرحله بعد، باید پروژه را بسازید:

npm run build

خروجی اضافی زیادی وجود دارد زیرا گزینه debug برای @babel/preset-env در babel.config.js پروژه به صورت true مشخص شده است. ابتدا، به اندازه CSS و جاوا اسکریپت در آمار 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]

توجه داشته باشید که حجم بسته جاوا اسکریپت ۲۰۸ کیلوبایت و حجم CSS 3.64 کیلوبایت است. زیرا این پروژه core-js برای polyfillهای جاوا اسکریپت و autoprefixer برای اعمال پیشوندهای مخصوص فروشنده برای ویژگی‌های CSS که هنوز کاملاً سازگار نیستند، استفاده می‌کند. هم core-js و هم autoprefixer تحت تأثیر کوئری انتخاب شده در Baseline Browserslist قرار می‌گیرند.

نکته دیگری که در خروجی باید به آن توجه کنید این است که چگونه کوئری Browserslist شما برای Baseline Widely available به یک کوئری Browserslist تبدیل می‌شود. در پروژه شما، چیزی شبیه به این خواهد بود:

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

به پلی‌فیل‌های تزریق‌شده توسط core-js در خروجی ساخت توجه کنید:

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 ترجمه می‌شود. می‌توانید تفاوت‌ها را در خروجی toolchain پس از اجرای مجدد build مشاهده کنید:

npm run build

ابتدا، به تغییر اندازه فایل جاوا اسکریپت و 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]

متوجه خواهید شد که حجم بسته جاوا اسکریپت تقریباً 30 کیلوبایت افزایش یافته است. CSS پروژه فقط کمی بزرگتر شده است، که به دلیل اضافه کردن پیشوندهای بیشتر فروشندگان توسط autoprefixer بر اساس هدف Baseline 2016 است. همچنین به تغییر در پرس و جوی Browserslist توجه کنید:

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

در مقایسه با هدف اولیه‌ی در دسترس عموم، این نسخه‌های مرورگر خیلی خیلی قدیمی‌تر هستند - آنقدر قدیمی که نسخه‌ای از اج که در این مورد هدف قرار گرفته، نسخه پیش از کرومیوم است.

پلی‌فیل‌های تزریق‌شده توسط core-js نیز تغییر خواهند کرد، که به‌طور قابل‌توجهی بیشتر از زمانی است که Baseline Widely available به عنوان هدف انتخاب شده بود:

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" }

نکته‌ی کلیدی اینجاست که هدف Baseline شما می‌تواند تأثیر قابل توجهی در نحوه‌ی تبدیل برنامه‌تان توسط زنجیره‌ی ابزار پروژه‌تان داشته باشد؛ برنامه‌ی مورد استفاده در این مثال بسیار ابتدایی است و ویژگی‌های پیشرفته‌ی زیادی چه در React و چه در خود برنامه ندارد. برای برنامه‌های بسیار پیچیده‌تر، می‌توانید نتایج بسیار متفاوتی را انتظار داشته باشید - احتمالاً حتی بیشتر در قالب اضافه کردن polyfillها، transformها و سایر منابع کد اضافی برای مطابقت با هدف Baseline که انتخاب می‌کنید.

۵. هدف قرار دادن مرورگرهای پایین‌دست

برای بررسی، مجموعه مرورگرهای اصلی که Baseline آنها را هدف قرار می‌دهد شامل مرورگرهای زیر است:

  • کروم
  • کروم در اندروید
  • فایرفاکس
  • فایرفاکس در اندروید
  • لبه
  • سافاری در macOS
  • سافاری در iOS

با این حال، می‌توانید مرورگرهایی که به عنوان "مرورگرهای پایین‌دست" شناخته می‌شوند را هدف قرار دهید. این مرورگرها، مرورگرهایی هستند که موتورشان از یک مرورگر در مجموعه مرورگرهای اصلی - که اغلب Chromium است - گرفته شده است. این مرورگرها شامل مرورگرهایی مانند Opera، Samsung Internet و سایرین می‌شوند. می‌توانید علاوه بر مرورگرهای موجود در مجموعه مرورگرهای اصلی، این مرورگرها را نیز با اضافه کردن with downstream به هر کوئری معتبر Baseline Browserslist هدف قرار دهید:

"browserslist": "baseline widely available with downstream"

این مرورگرهای پایین‌دستی را مطابق با هدف Baseline Widely available هدف قرار می‌دهد. برای دیدن اینکه چگونه این به یک پرس‌وجوی 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"
}

۶. لینترها و ابزارهای دیگر

کوئری‌های Baseline که در Browserslist تعبیه شده‌اند، برای ابزارهایی مانند bundlerها و سایر بخش‌های زنجیره ابزار شما مناسب هستند، اما ابزارهای دیگری مانند linterها که اهداف Baseline را به عنوان بخشی از پیکربندی خود پذیرفته‌اند نیز ارزشمند هستند.

یک مثال خوب از پشتیبانی لینتر برای 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" روی حالت Widely available تنظیم شده‌اند.
  2. برای هر دو بسته‌ی linting، سطح گزارش تخلفات linter روی "warn" تنظیم شده است. این مقدار را می‌توان روی "error" تنظیم کرد تا با یک کد خطا از بین برود و از وقوع build جلوگیری شود.

ممکن است قبلاً هنگام اجرای npm run build خروجی linter را دیده باشید، اما برای دیدن خروجی linter به تنهایی، می‌توانید دستور زیر را اجرا کنید:

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

۷. جمع‌بندی

استفاده از کوئری‌های Baseline ارائه شده توسط Browserslist در پروژه شما نیاز به درک ابزارهای ساخت اساسی و خود Browserslist دارد، اما عمل قرار دادن آنها در یک پروژه به خودی خود مختصر است. مزیت اصلی استفاده از آن این است که دیگر نیازی نیست به مرورگرهایی که از نظر شماره نسخه پشتیبانی می‌کنید فکر کنید، بلکه یک هدف Baseline وجود دارد که کارهای سنگین را برای شما انجام می‌دهد.

علاوه بر این، نسخه‌ای از این نسخه آزمایشی وجود دارد که روی Rollup اجرا می‌شود و این Codelab را می‌توان تا حد زیادی با استفاده از آن نسخه آزمایشی نیز دنبال کرد.

پشتیبانی از Baseline در سایر ابزارهای بسته‌بندی نیز در حال ظهور است. به عنوان مثال، Vite که در اصل از Rollup استفاده می‌کند، اکنون از نسخه ۷ به طور پیش‌فرض مرورگرهای Baseline Widely available را هدف قرار می‌دهد .

به هر روشی که تصمیم بگیرید، با معرفی کوئری‌های Baseline موجود در Browserslist به پروژه خود - و انتخاب یک هدف Baseline که برای شما مناسب باشد - می‌توانید مرورگرها را به روشی ساده‌تر و مطمئن‌تر هدف قرار دهید.