На прошлой неделе на Vue.js London я кратко рассказал о том, что будет в следующей основной версии Vue. В этом посте представлен подробный обзор плана.

Почему новая мажорная версия?

Vue 2.0 был выпущен ровно два года назад (как летит время!). В течение этого периода ядро ​​оставалось обратно совместимым с пятью второстепенными выпусками. Мы накопили ряд идей, которые могли бы привести к улучшениям, но их отложили, потому что они приведут к критическим изменениям. В то же время экосистема JavaScript и сам язык стремительно развиваются. Существуют значительно улучшенные инструменты, которые могут улучшить наш рабочий процесс, и множество новых языковых функций, которые могут открыть более простые, полные и эффективные решения проблем, которые Vue пытается решить. Что еще более захватывающе, так это то, что мы видим, что поддержка ES2015 становится базовой для всех основных вечнозеленых браузеров. Vue 3.0 стремится использовать эти новые языковые функции, чтобы сделать ядро ​​Vue меньше, быстрее и мощнее.

Vue 3.0 в настоящее время находится на стадии прототипирования, и мы уже реализовали среду выполнения, близкую к функциональному паритету с 2.x. Многие из перечисленных ниже элементов либо уже реализованы, либо подтверждены как выполнимые. Те, которые еще не реализованы или все еще находятся в стадии разработки, отмечены *.

Детали

Изменения API высокого уровня

TL; DR: все, кроме API функции рендеринга и синтаксиса scoped-slots, либо останется прежним, либо может быть сделано совместимым с 2.x через сборку совместимости.

Поскольку это новая специальность, в ней произойдут серьезные изменения. Однако мы серьезно относимся к обратной совместимости, поэтому мы хотим сообщить об этих изменениях как можно скорее. Вот планируемые в настоящее время изменения общедоступного API:

  • Синтаксис шаблона останется прежним на 99%. Могут быть небольшие изменения в синтаксисе слотов с ограниченной областью видимости, но кроме этого мы не планируем изменять что-либо еще для шаблонов.
  • ̶3̶.̶0̶ ̶w̶i̶l̶l̶ ̶s̶u̶p̶p̶o̶r̶t̶ ̶c̶l̶a̶s̶s̶-̶b̶a̶s̶e̶d̶ ̶c̶o̶m̶p̶o̶n̶e̶n̶t̶s̶ ̶n̶a̶t̶i̶y̶e̶l. Обновление: черновик Class API удален. Мы опубликовали новое предложение API на основе функций, которое обеспечивает лучшую логическую композицию, лучшую поддержку TypeScript и совместимость с API 2.x.
  • Миксины по-прежнему будут поддерживаться. *
  • API верхнего уровня, вероятно, будут подвергнуты капитальному ремонту, чтобы избежать глобального изменения среды выполнения Vue при установке плагинов. Вместо этого плагины будут применены и привязаны к дереву компонентов. Это упростит тестирование компонентов, которые полагаются на определенные плагины, а также даст возможность монтировать несколько приложений Vue на одной странице с разными плагинами, но с использованием одной и той же среды выполнения Vue. * (Обновление: связанный RFC )
  • Функциональные компоненты, наконец, могут быть простыми функциями - однако теперь асинхронные компоненты должны быть явно созданы с помощью вспомогательной функции. (Обновление: соответствующий RFC)
  • Часть, которая получит больше всего изменений, - это формат Virtual DOM, используемый в функциях рендеринга. В настоящее время мы собираем отзывы от основных авторов библиотек и поделимся более подробной информацией, поскольку мы более уверены в изменениях, но до тех пор, пока вы не сильно полагаетесь на написанные вручную (не JSX) функции рендеринга в своем приложении, обновление должен быть достаточно простым процессом.

Архитектура исходного кода

TL; DR: лучше разделенные внутренние модули, TypeScript и кодовая база, в которую легче внести свой вклад.

Мы переписываем 3.0 с нуля для более чистой и удобной в обслуживании архитектуры, в частности, пытаясь упростить работу над ней. Мы разбиваем некоторые внутренние функции на отдельные пакеты, чтобы изолировать объем сложности. Например, модуль наблюдателя станет отдельным пакетом с собственным общедоступным API и тестами. Обратите внимание, что это не влияет на API уровня фреймворка - вам не придется вручную импортировать отдельные биты из нескольких пакетов, чтобы использовать Vue. Вместо этого последний пакет Vue собирается с использованием этих внутренних пакетов.

Кодовая база теперь также написана на TypeScript. Хотя это сделает владение TypeScript предпосылкой для внесения вклада в новую кодовую базу, мы полагаем, что информация о типе и поддержка IDE на самом деле упростят для нового участника внесение значимого вклада.

Разделение наблюдателя и планировщика на отдельные пакеты также позволяет нам легко экспериментировать с альтернативными реализациями этих частей. Например, мы можем реализовать совместимую с IE11 реализацию наблюдателя с тем же API или альтернативный планировщик, который использует requestIdleCallback, чтобы уступить браузеру во время длительных обновлений. *

Механизм наблюдения

TL; DR: более полное, точное, эффективное и отлаживаемое отслеживание реактивности и API для создания наблюдаемых.

3.0 будет поставляться с реализацией наблюдателя на основе прокси, которая обеспечивает отслеживание реактивности с полным языковым охватом. Это устраняет ряд ограничений текущей реализации Vue 2 на основе Object.defineProperty:

  • Обнаружение добавления / удаления свойства
  • Обнаружение мутации индекса массива / мутации .length
  • Поддержка Map, Set, WeakMap и WeakSet

В новом наблюдателе также есть следующие возможности:

  • Открытый API для создания наблюдаемых. Это легкое и простое решение для управления состоянием между компонентами для малых и средних сценариев.
  • По умолчанию ленивое наблюдение. В 2.x любые реактивные данные, независимо от их размера, будут отслеживаться при запуске. Это может вызвать заметные накладные расходы при запуске приложения, если ваш набор данных огромен. В 3.x необходимо будет наблюдать только данные, используемые для визуализации изначально видимой части вашего приложения, не говоря уже о том, что само наблюдение также намного быстрее.
  • Более точное уведомление об изменении. Пример: в 2.x принудительное добавление нового свойства с использованием Vue.set приведет к повторной оценке любого наблюдателя, который зависит от объекта. В 3.x будут уведомлены только наблюдатели, которые полагаются на это конкретное свойство.
  • Неизменяемые наблюдаемые: мы можем создавать «неизменяемые» версии значения, которые предотвращают изменения даже во вложенных свойствах, за исключением случаев, когда система временно разблокирует их изнутри. Этот механизм можно использовать для замораживания переданных свойств или деревьев состояний Vuex вне мутаций.
  • Улучшенные возможности отладки: мы можем точно отслеживать, когда и почему повторный рендеринг компонента отслеживается или запускается с помощью новых хуков renderTracked и renderTriggered:

Другие улучшения во время выполнения

TL; DR: меньшие, более быстрые, древовидные функции, фрагменты и порталы, пользовательский API рендеринга.

  • Меньше: новая кодовая база разработана с нуля, чтобы быть удобной в использовании. Такие функции, как встроенные компоненты (<transition>, <keep-alive>) и помощники времени выполнения директив (v-model), теперь импортируются по запросу и с возможностью изменения дерева. Постоянный базовый размер для новой среды выполнения составляет ‹10 КБ в сжатом виде. Кроме того, возможность древовидного преобразования функций также позволяет нам предлагать больше встроенных функций в будущем без штрафных санкций за полезную нагрузку для пользователей, которые не не использовать их.
  • Быстрее: по предварительным тестам мы наблюдаем повышение производительности до 100% по всем направлениям, включая монтирование и исправление необработанного виртуального DOM (мы узнали немало трюков из Inferno, самой быстрой реализации виртуального DOM), инициализацию экземпляра компонента. и данные наблюдения. 3.0 сокращает половину времени, затрачиваемого на JavaScript, когда ваше приложение загружается.
  • Фрагменты и порталы: несмотря на уменьшение размера, 3.0 поставляется со встроенной поддержкой фрагментов (компонент, возвращающий несколько корневых узлов) и порталов (рендеринг поддерева в другой части DOM, а не внутри компонента).
  • Улучшенный механизм слотов: все слоты, созданные компилятором, теперь являются функциями и вызываются во время вызова рендеринга дочернего компонента. Это гарантирует, что зависимости в слотах собираются как зависимости для дочернего элемента, а не для родительского. Это означает, что: 1. при изменении содержимого слота выполняется повторная визуализация только дочернего элемента; 2. когда родительский элемент выполняет повторную визуализацию, дочерний элемент не обязан, если содержимое его слота не изменилось. Это изменение предлагает еще более точное обнаружение изменений на уровне дерева компонентов, так что еще меньше бесполезных повторных отрисовок!
  • Custom Renderer API: будет доступен первоклассный API для создания настраиваемых средств визуализации, который больше не требует разветвления кодовой базы Vue с настраиваемыми модификациями. Это значительно упростит для проектов с рендерингом в нативной версии, таких как Weex и NativeScript Vue, оставаться в курсе последних изменений. Это также упростило бы создание пользовательских средств визуализации для различных других целей.

Улучшения компилятора *

TL; DR: дружественный к дереву вывод, больше оптимизаций AOT, синтаксический анализатор с лучшей информацией об ошибках и поддержка исходной карты.

  • При нацеливании на сборщики пакетов с возможностью встряхивания деревьев шаблоны, которые используют дополнительные функции, будут генерировать код, который импортирует эти функции с использованием синтаксиса модулей ES. Таким образом, неиспользуемые дополнительные функции удаляются из окончательного пакета.
  • Благодаря улучшениям в новой реализации Virtual DOM, мы также можем выполнять более эффективную оптимизацию времени компиляции, такую ​​как подъем статического дерева, подъем статических свойств, подсказки компилятора для времени выполнения, чтобы пропустить нормализацию детей, быстрые пути создания VNode и т. Д.
  • Мы планируем переписать парсер, чтобы предоставлять информацию о местоположении при ошибках компиляции шаблона. Это также должно привести к поддержке исходной карты шаблонов, а новый синтаксический анализатор может служить основой для интеграции сторонних инструментов, таких как eslint-plugin-vue и языковые службы IDE.

Поддержка IE11 *

TL; DR: он будет поддерживаться, но в отдельной сборке с теми же ограничениями реактивности, что и Vue 2.x.

Новая кодовая база в настоящее время предназначена только для вечнозеленых браузеров и предполагает базовую встроенную поддержку ES2015. Но, увы, мы знаем, что многим нашим пользователям все еще необходимо поддерживать IE11 в обозримом будущем. Большинство используемых функций ES2015 могут быть перенесены / заполнены для IE11, за исключением прокси. Мы планируем реализовать альтернативный наблюдатель с тем же API, но с использованием старого доброго ES5 Object.defineProperty API. Отдельная сборка Vue 3.x будет распространяться с использованием этой реализации наблюдателя. Однако эта сборка будет подвержена тем же предупреждениям об обнаружении изменений, что и Vue 2.x, и, следовательно, не будет полностью совместима с «современной» сборкой 3.x. Мы понимаем, что это создает некоторые неудобства для авторов библиотек, поскольку им необходимо знать о совместимости двух разных сборок, но мы обязательно предоставим четкие рекомендации по этому поводу, когда дойдем до этого этапа.

Как мы туда попадем

Во-первых, хотя мы объявляем об этом сегодня, у нас еще нет окончательного графика. Что мы действительно знаем на данный момент, так это шаги, которые мы предпримем, чтобы этого добиться:

1. Внутренняя обратная связь для прототипа среды выполнения

Это тот этап, на котором мы сейчас находимся. В настоящее время у нас уже есть рабочий прототип среды выполнения, который включает новый наблюдатель, виртуальную модель DOM и реализацию компонента. Мы пригласили группу авторов влиятельных проектов сообщества для предоставления обратной связи по внутренним изменениям и хотели бы убедиться, что они довольны изменениями, прежде чем двигаться дальше. Мы хотим гарантировать, что важные библиотеки в экосистеме будут готовы одновременно с выпуском 3.0, чтобы пользователи, полагающиеся на эти проекты, могли легко выполнить обновление.

2. Отзывы общественности через RFC

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

  • Объем изменения;
  • Причины изменения: что мы получаем и какие компромиссы мы делаем;
  • Путь обновления: может ли он быть полностью обратно совместим, через съемный уровень совместимости или через codemods?

Мы будем ожидать откликов общественности от более широкого сообщества, чтобы помочь нам консолидировать эти идеи.

3. Добавьте совместимые функции в версии 2.x и 2.x-next.

Мы не забываем о 2.x! Фактически, мы планируем использовать 2.x, чтобы постепенно приучать пользователей к новым изменениям. Мы будем постепенно вводить подтвержденные изменения API в 2.x через адаптеры подписки, а 2.x-next позволит пользователям опробовать новый обозреватель на основе прокси.

Последний второстепенный выпуск в 2.x станет LTS и продолжит получать исправления ошибок и безопасности в течение 18 месяцев после выпуска 3.0.

4. Альфа-фаза

Затем мы закончим компилятор и серверную часть рендеринга 3.0 и начнем выпускать альфа-версии. В основном они будут использоваться для тестирования стабильности в небольших новых приложениях.

5. Бета-фаза

На этапе бета-тестирования нашей основной целью является обновление вспомогательных библиотек и инструментов, таких как Vue Router, Vuex, Vue CLI, Vue DevTools, и обеспечение бесперебойной работы с новым ядром. Мы также будем работать с крупными авторами библиотек из сообщества, чтобы помочь им подготовиться к версии 3.0.

6. Фаза RC

Как только мы сочтем API и кодовую базу стабильными, мы перейдем к фазе RC с замораживанием API. На этом этапе мы также будем работать над «совместимой сборкой»: сборкой 3.0, которая включает уровни совместимости для 2.x API. Эта сборка также будет поставляться с флагом, который вы можете включить, чтобы выдавать предупреждения об устаревании для использования API 2.x в вашем приложении. Совместимую сборку можно использовать в качестве руководства для обновления вашего приложения до версии 3.0.

7. Сборка IE11

Последней задачей перед финальным выпуском будет сборка совместимости с IE11, как упоминалось выше.

8. Окончательный выпуск

Честно говоря, мы пока не знаем, когда это произойдет, но, скорее всего, в 2019 году. Опять же, мы больше заботимся о том, чтобы выпустить что-то надежное и стабильное, а не в конкретные сроки. Предстоит еще много работы, но мы очень ждем, что будет дальше!