Как использовать Baseline в вашем проекте

1. Введение

Baseline — это инициатива, которая обеспечивает более чёткое представление о том, какие веб-функции совместимы и безопасны для использования уже сегодня. Благодаря достижениям в области инструментов Baseline вы теперь можете использовать Baseline непосредственно в своих проектах в виде запроса Browserslist , чтобы ваша цепочка инструментов могла изменять вывод кода в зависимости от выбранного вами целевого значения Baseline .

В этой лабораторной работе вы узнаете, как использовать Baseline в проекте-примере и как настроить его для выбора определённого целевого значения Baseline. Вы также увидите, как выходные данные цепочки инструментов проекта меняются в зависимости от выбранного вами целевого значения Baseline.

2. Настройте демо-версию на локальном компьютере.

Сначала перейдите в предпочитаемое вами терминальное приложение, клонируйте демонстрационный репозиторий, а затем войдите в каталог проекта:

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

На этом этапе демоверсия уже будет иметь интегрированный Baseline, но вам нужно будет проверить коммит, который позволит вам начать все с нуля:

git checkout 94f12e34

После клонирования репозитория демо-версию можно развернуть. Этот проект использует nvm для управления версиями Node. Если у вас установлена достаточно свежая версия Node глобально, вам, вероятно, не нужно выполнять этот шаг. Но если вы используете nvm , выполните следующие команды:

nvm install
nvm use

Отсюда установите пакеты проекта:

npm install

Если вы хотите увидеть демо, выполните следующую команду:

npm start

Затем перейдите по адресу http://localhost:8080 . Демонстрационная версия представляет собой список карточек, который можно отфильтровать с помощью поля формы в верхней части страницы. Само приложение использует набор функций, достигших базового порога.

Завершив демонстрацию, перейдите в терминал и нажмите Ctrl+C, чтобы остановить демонстрацию в любой момент.

3. Как интегрировать Baseline в проект

В этой демонстрации конфигурация Browserslist изначально не задаётся. Browserslist — это компактный синтаксис запросов, сообщающий цепочкам инструментов, какие минимальные версии браузеров должны поддерживаться. Например, запрос за last 3 years укажет широкий диапазон целевых значений. В этой демонстрации мы используем пакет npm с именем browserslist-config-baseline для задания запроса Browserslist, соответствующего базовым целевым значениям, которые вы можете использовать в своей цепочке инструментов.

Для начала установите browserslist-config-baseline следующим образом:

npm install browserslist-config-baseline --save-dev

После установки этот пакет позволяет вам указать в проекте запрос extends Browserslist, который преобразуется в список базовых браузеров. Эти базовые цели могут быть одними из следующих:

  • Движущиеся цели , которые обновляются со временем по мере выпуска новых браузеров:
    • Базовый уровень Недавно доступен , который выравнивает совместимые функции, реализованные в основном наборе браузеров в любой момент времени с настоящего момента до 30 месяцев назад.
    • Базовый широкодоступный вариант , включающий совместимые функции, которые были реализованы в основном наборе браузеров 30 или более месяцев назад.
  • Фиксированные цели , представляющие версии браузеров на фиксированный момент времени. Они выражены в годах с 2016 по текущий год.

Для начала мы используем browserslist-config-baseline для выбора перемещаемой базовой версии Widely available для проекта. Для этого откройте package.json и добавьте следующее:

"browserslist": "extends browserslist-config-baseline"

4. Наблюдайте за изменениями в выходных данных кода, выбирая различные базовые цели.

Вы только что выбрали Baseline Widely available в качестве целевой платформы для демонстрационного проекта. Далее вам нужно будет собрать проект:

npm run build

Выводится много дополнительной информации, поскольку в babel.config.js проекта параметр debug @babel/preset-env установлен как true Во-первых, обратите внимание на размер CSS и JavaScript в статистике сборщика:

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 составляет 208 КБ , а CSS — 3,64 КБ . Поскольку в этом проекте используется core-js для полифиллов JavaScript и autoprefixer для применения префиксов, специфичных для вендоров, к свойствам CSS, которые пока не полностью совместимы. Как core-js , так и autoprefixer подвержены влиянию browserslist-config-baseline .

Ещё один момент, на который стоит обратить внимание в выводе, — это то, как ваш запрос 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": "extends browserslist-config-baseline/2016"

При этом в качестве целевой версии будет выбрана версия Baseline 2016, которая будет преобразована в запрос Browserslist. Вы можете заметить различия в выводе цепочки инструментов после повторного запуска сборки:

npm run build

Во-первых, обратите внимание на изменение размера файла JavaScript и CSS проекта в статистике упаковщика:

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 увеличился почти на 30 КБ. CSS-код проекта увеличился лишь немного благодаря тому, что autoprefixer добавил больше вендорных префиксов в соответствии с базовым целевым показателем 2016 года. Также обратите внимание на изменение в запросе Browserslist:

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

По сравнению с базовой версией Widely available эти версии браузеров намного более ранние — настолько ранние, что в данном случае целевая версия Edge является более ранней, чем Chromium.

Полифиллы, внедряемые 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" }

Вывод здесь заключается в том, что ваш базовый целевой уровень может существенно повлиять на то, как ваше приложение преобразуется инструментами вашего проекта. Приложение в этом примере очень простое и не содержит большого количества передовых функций разработки ни в React, ни в самом приложении. Для значительно более сложных приложений можно ожидать совершенно иных результатов — возможно, даже более серьёзных в плане добавления полифиллов, преобразований и других источников дополнительного кода для соответствия выбранному вами базовому целевому уровню.

5. Ориентация на нижестоящие браузеры с помощью browserslist-config-baseline

Для обзора, основной набор браузеров, на который ориентирован Baseline, включает следующие браузеры:

  • Хром
  • Chrome на Android
  • Firefox
  • Firefox на Android
  • Край
  • Safari на macOS
  • Safari на iOS

Однако вы можете ориентироваться на так называемые «нижестоящие браузеры». Это браузеры, движки которых основаны на браузере из основного набора — чаще всего Chromium. К ним относятся такие браузеры, как Opera, Samsung Internet и другие. Вы можете настроить browserslist-config-baseline для работы с ними в файле package.json следующим образом:

"browserslist": "extends browserslist-config-baseline/with-downstream"

Это нацеливает браузеры, работающие в рамках нисходящей цепочки, в соответствии с базовым целевым значением 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": "extends browserslist-config-baseline/with-downstream/2016"

При такой конфигурации ваш запрос Browserslist изменится соответствующим образом:

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

6. Линтеры и другие инструменты

browserslist-config-baseline — удобный инструмент для сборщиков пакетов и других частей вашей цепочки инструментов, но ценность представляют и другие инструменты, например, линтеры, которые приняли целевые показатели 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. Оба пакета линтинга HTML и CSS используют правило use-baseline , и для него установлено значение Widely available с помощью параметра конфигурации available: "widely" .
  2. Для обоих пакетов линтинга уровень ведения журнала для нарушений линтера установлен на "warn" . Его можно изменить на "error" , чтобы выводился код ошибки и сборка не выполнялась.

Возможно, вы уже видели вывод linter при запуске npm run build , но чтобы увидеть вывод 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

7. Подведение итогов

Как видите, использование browserslist-config-baseline в вашем проекте требует некоторого понимания базовых инструментов сборки и Browserslist, но внедрение этого модуля в ваши проекты должно быть возможным после небольших усилий. Главное преимущество заключается в том, что вам больше не нужно думать о поддерживаемых браузерах с точки зрения номеров версий, а достаточно иметь целевой базовый модуль, который сделает всю сложную работу за вас.

Кроме того, существует версия этой демо-версии, которая работает на Rollup , и большую часть данной лабораторной работы можно выполнить также с помощью этой демо-версии.

Поддержка Baseline также начинает появляться в других инструментах для сборки пакетов. Например, Vite, использующий Rollup, теперь, начиная с версии 7, по умолчанию ориентирован на широко распространённые браузеры Baseline .

Однако какой бы способ вы ни выбрали, внедрив browserslist-config-baseline в цепочку инструментов вашего проекта и выбрав подходящую для вас базовую цель , вы сможете нацеливаться на браузеры более простым и надежным способом.