Open Source
RFC процесс и breaking changes
React 16.8 добавил Hooks - самое большое изменение в истории React. Но никто не был вынужден переписывать код. Как такое возможно? Это искусство делать breaking changes правильно.
- React Hooks RFC обсуждался 2 месяца с 1800+ комментариями - только после этого началась реализация
- TC39 процесс: Optional Chaining (?.) прошёл путь от Stage 0 до Stage 4 за 3 года, сейчас в каждом браузере
- Vue 3 @vue/compat позволил проектам мигрировать постепенно: сначала запустить на Vue 3 с предупреждениями, потом исправлять
- React codemod репозиторий содержит 20+ трансформаций - Facebook мигрировал тысячи компонентов автоматически
RFC процесс: принятие больших решений
**RFC (Request for Comments)** - формальный процесс принятия значимых изменений в проекте. Одиночный PR с 2000 строками кода без обсуждения дизайна - плохой способ менять публичный API. RFC отделяет «что и почему» от «как именно».
RFC работает так: автор пишет документ (обычно Markdown-файл в `rfcs/` директории репозитория) → открывает PR → сообщество обсуждает дизайн → core team принимает или отклоняет → только тогда начинается реализация. Этот процесс используют React, Vue, Rust, Ember, Swift.
**Vue 3 Composition API RFC** (2019) - ещё более бурное обсуждение: 500+ комментариев только в первые дни, петиция против с тысячами подписей. Evan You ответил подробным объяснением, RFC скорректировали. Результат - Composition API стал опциональным, Options API сохранили.
**TC39 proposal stages** - RFC процесс для JavaScript самого языка: Stage 0 (идея) → Stage 1 (предложение с чемпионом) → Stage 2 (черновик спецификации) → Stage 3 (кандидат, реализации в браузерах) → Stage 4 (готово, войдёт в следующий стандарт ECMA). Обычно от 0 до 4 - несколько лет.
**Когда RFC обязателен:** новый публичный API; изменение поведения существующего API; удаление существующего API; значимое изменение архитектуры. Когда не нужен: багфикс, оптимизация без изменения API, обновление документации.
Vue Composition API RFC получил петицию с тысячами подписей против. Evan You в итоге:
Breaking changes: как делать правильно
**Semver** (Semantic Versioning): `MAJOR.MINOR.PATCH`. Patch - баги без изменения API. Minor - новые возможности, обратная совместимость сохранена. Major - breaking change: существующий код может сломаться.
**Deprecation pipeline** - правильный путь к breaking change: **1)** Minor: добавить `@deprecated` и `console.warn` с инструкцией по миграции. **2)** Один-два minor релиза: дать пользователям время. **3)** Major: удалить deprecated API.
**Реальные примеры хорошо управляемых breaking changes:** React 17 - нулевые breaking changes, только подготовка к React 18. React 18 - Concurrent Mode как opt-in через `createRoot`. Node.js - LTS политика, deprecation за несколько major версий вперёд. Angular - чёткий schedule: major каждые 6 месяцев, 18 месяцев поддержки.
**Антипаттерн: major bump без реальных breaking changes.** Некоторые проекты выпускают major версии ради маркетинга. Это обесценивает semver - пользователи перестают доверять версиям. Если breaking changes нет - не делайте major bump.
Библиотека `parse(input, options)` хочет сделать второй аргумент обязательным. Текущая версия 2.5.0. Правильный процесс:
Migration guides и codemods
**Migration guide** - обязательный документ при major релизе. Структура: список всех breaking changes → почему изменили → как мигрировать (before/after примеры) → ссылки на инструменты миграции.
**Codemod** - программа, которая автоматически трансформирует исходный код через AST (Abstract Syntax Tree). Вместо ручного поиска и замены всех вызовов deprecated API - запускаешь скрипт, он трансформирует весь проект за секунды.
**Реальные примеры codemods:** React - `react-codemod` репозиторий с 20+ трансформациями (class → hooks, PropTypes удаление, createClass → class). Vue 3 - `@vue/compat` migration build: запустить старый код на Vue 3 с предупреждениями о deprecated API. Angular - `ng update` встроен в CLI, применяет схематики миграции автоматически.
**Создание codemods - знак уважения к пользователям.** Когда крупная библиотека предоставляет codemod, это говорит: «Мы сделали breaking change, но мы уважаем ваше время». Именно это отличает зрелые OSS-проекты от тех, кто просто «меняет API и пишет migration guide».
Vue выпустил `@vue/compat` - migration build. Это позволяет:
Ключевые идеи
- RFC процесс отделяет дизайн API от реализации - крупные изменения обсуждаются до написания кода
- TC39 stages - образцовый RFC процесс: от идеи до стандарта через 4 стадии с чёткими критериями
- Deprecation pipeline: console.warn в minor → удаление в major - пользователи получают time to migrate
- Codemod через jscodeshift трансформирует код через AST - миграция тысяч файлов за секунды
- Хороший major релиз = RFC + deprecation warnings + migration guide + codemod
Связанные темы
RFC и versioning неотделимы от управления несколькими пакетами.
- Monorepo для OSS — В monorepo breaking change в одном пакете требует координации версий через Changesets
- Semantic Versioning — Semver - основа для понимания когда делать patch/minor/major bump
Вопросы для размышления
- Ваша библиотека `formatDate(date, format)` хочет изменить порядок аргументов на `formatDate(format, date)` для консистентности с другими функциями. Опишите полный процесс: RFC нужен? Какой deprecation pipeline? Что должен делать codemod?
- TC39 предложение находится на Stage 2 - черновик спецификации готов. Можно ли использовать его в продакшн коде через Babel? Какие риски?