TGViewer
Валя читает ишью Валя читает ишью @valya_reads_issue · 3.01K subscribers
Post #329 7.17K
Safari class fields implementation is buggy: part two, Tt edition

Я уже рассказывал о том, как сафари не очень хорошо (мягко говоря) дружит с замыканиями в class fields. И вот, спустя полгода, мы снова здесь. Long time no see как говорится!

В прошлый четверг я закончил миграцю с Jest на Vitest в последнем нашем проекте (про наш опыт можно почитать тут), всё протестил и выкатил в прод. На следующей день пришла жалоба от пользователя «форма поиска исчезает в сафари 15 — ничего не работает». При этом я форму эту не трогал даже близко. Весело!

Для начала пошли в BrowserStack чтобы посмотреть что ж там в 15 сафари происходит (какая же гениальная система обновлений у сафари, боже, я никогда это не пойму). В 15 сафари мы ничего не могли воспроизвести около часа, хотя у тестировщика разок получилось. Решили ради интереса попробовать сафари 14, который мы не поддерживаем — и сразу же воспроизвелось, причём стабильно. Увидели «ReferenceError: Tt is not defined». В этот раз проблемное место нашли сразу же, т.к. такая переменная была одна на весь бандл. Ну в общем всё тоже самое: class field, замыкание, вспомнили что в 15 сафари проблема иногда воспроизводилась, а иногда не особо.

Но как так вышло, что мы чиним ту же проблему, что и полгода назад? А всё просто — проблема та же, но в другом проекте! Понятно, что это чинится использованием babel/plugin-proposal-class-properties, но почему всё сломалось?

Если поменялся результат билда, то очевидно, что обновилась какая-то транизитивная зависимость (зависимость зависимости зависимости зависимости, ну вы знаете). В yarn.lock смотреть было бесполезно, т.к. дифф очень большой.

Решил сравнить мастер с веткой через yarn info.
yarn info --recursive --name-only выводит плоский список зависимостей с их версиями:
├─ @adobe/css-tools@npm:4.3.1
├─ @ampproject/remapping@npm:2.2.1
├─ @aviasales/analytics@npm:4.0.7

и т.д.

В дифе помимо кучи других пакетов, я увидел caniuse-lite и @babel/compat-data, а именно их использует @babel/preset-env, чтобы решить нужно трансформировать ту или иную фичу.

Начиная с 7.22.6 в @babel/compat-data указано, что class properties поддерживаются в iOS 14.5, а до этого было указано что в iOS 15, т.е. с Safari 15 сдаунгрейдили поддержку до Safari 14.1. Напомню, без багов эта фича работает начиная с Safari/iOS 16.

Что ж, тут вроде всё понятно. А что с caniuse-lite? Его использует browserslist, чтобы получить браузеры, которые мы хотим поддерживать. В конфиге у нас было указано defaults, last 2 years, not ie > 0, not ie_mob > 0, chrome >= 94. Сравнил вывод yarn dlx browserslist и увидел, что из поддерживаемых браузеров исчез сафари 14, т.к. ему исполнилось больше двух лет.

Получается, что к проблеме мог привести апдейт babel/compat-data и caniuse-lite в любых комбинациях: по отдельности и вместе.

А кто их обновил? Ну, в общем-то я, когда устанавливал vitest и пару зависимостей к нему. Мы используем yarn dedupe, чтобы в рамках SemVer использовалась только одна библиотека. При установке и babel/compat-data, и caniuse-lite зарезолвились на последнюю версию и всё сломалось! Этой проблемы можно было бы избежать, если yarn dedupe умел бы в другие стратегии, но пока что только latest.

Ну и напоследок: что сделали, чтобы такого больше не случалось?
1. Явно включили babel/plugin-proposal-class-properties.
2. Посмотрели, что пользователи 14 сафари приносят нам 1% деняк и явно указали safari >= 14 в конфиге браузерслиста.
3. Через resolutions явно установили browserslist и caniuse-lite в единственных экземплярах, чтоб прозрачно контролировать процесс обновления.

А что там с ишью? А ишью в бабеле так и висит без изменений…
  • 👍 32
  • 😱 14
  • ❤ 1
More from @valya_reads_issue
  1. Aug 26, 2026Поддержка zip архивов в Node.js Внезапно, в Node.js 26.8.0 появился нативная поддержка для…
  2. Jun 12, 2026Diff: You should be able to just render any diff А пока гитхаб не вывозит как с точки зрен…
  3. Jun 12, 2026Diff: The uphill climb of making diff lines performant Пару лет назад я уже пинал GitHub з…
  4. May 6, 2026Vite выходит из Vitest В Vitest появилась крайне интересная дискуссия — а что если раздели…
  5. Mar 31, 2026Port of React Compiler to Rust Пока что WIP в виде альтернативного плагина для Babel и cra…
  6. Mar 11, 2026Evolving the Node.js Release Schedule Node.js давно загнала себя в странное состояние — чё…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →