Migration Roadmap: як зробити міграцію великого проєкту з Nuxt 2 на Nuxt 3
Всім привіт! Мене звати Володимир Василенко, я Front-end Team Lead у компанії Futurra Group. Ми розробляємо низку освітніх продуктів, зокрема, математичний сервіс MathMaster.
Міграція проєкту з одного стеку технологій на інший — це водночас і точка ризику, і вихід на новий етап для проєкту, а отже, і зона подвійної відповідальності для розробника. Тож потрібно виважено підходити до цього процесу та намагатися мінімізувати ризики, якими він супроводжується.
У своїй статті хочу поділитися досвідом міграції наших проєктів на Nuxt 3, що значно спростило розробку нового функціоналу, прискорило роботу наших застосунків та дозволило вийти на новий рівень якості коду.
Як було до
Зважаючи на стрімкий розвиток проєктів та велику кількість A/B-тестів, що в нас відбуваються постійно, Front-end складова досить часто змінювалась та пройшла декілька етапів еволюції: від HTML/CSS + JQuery до Nuxt 3 SSR + Tailwind CSS.
Основний стек технологій на момент ухвалення рішення про рефакторинг та заміну стеку складався з: Nuxt 2 SSG, Laravel Blade, Bootstrap 5, SCSS, з використанням багатьох бібліотек та пакетів по типу vuex, axios, i18n, OAuth, moment, lottie та інших.
У чому була проблема
У міру розвитку наших продуктів та технологій цього стеку поступово ставало недостатньо для розв’язання поточних задач, а також періодично накопичувалася низка проблем, що потребували вирішення.
Після довгої серії А/В-тестів кодова база ставала все більшою та заплутанішою. Збільшився загальний розмір бандлу та почастішали проблеми з оптимізацією. Особливості побудови архітектури подекуди перешкоджали використанню простих рішень, а відсутність типізації призводила до неявних помилок, що тільки збільшували час розробки.
Також слід брати до уваги масштабування проєктів та збільшення штату девелоперів. Добре побудована архітектура, типізація, перевикористання та патернування логік і компонентів в цьому випадку збільшила б продуктивність команди та підвищила б якість продуктів.
Усе вищенаведене змусило мене задуматись про заміну стеку на більш сучасний і гнучкий, рефакторинг наявної кодової бази та перебудову наших проєктів в цілому.
Перехід до Nuxt 3
Першочергово необхідно було зважити всі ризики та ознайомитись з усією необхідною інформацією. Великою перевагою Nuxt/Vue завжди була досить детальна та проста у використанні документація, яка містить всю необхідну розробнику інформацію.
Ознайомившись з нею та прочитавши низку тематичних статей, переваги заміни старої версії на більш сучасну стали для мене ще більш очевидними.
На момент ухваленя рішення Nuxt 3 мав stable-версію та більшість модулів, які ми використовували, вже були сумісні з Vue 3.
Порівняно з попередньою версією, Nuxt 3 отримав:
- впровадження останньої версії Vue 3, яка пропонує розширені функції, як-от Composition API та Composables;.
- Vite — інструмент для створення, збірки та налаштування проєктів. Його основні переваги — швидкість збірки, простота та миттєва гаряча заміна модулів;
- новий node-сервер Nitro, що має багато корисних функцій;
- Pinia — нову бібліотеку управління станом для екосистеми Vue;
- покращену маршрутизацію, автоімпорт та багато чого іншого.
Найсучасніший механізм Nitro Engine у Nuxt 3 покращує практично кожен аспект фреймворку розробки Vue. Оптимізуючи продуктивність, Nitro Engine забезпечує блискавичне завантаження застосунків під час розробки та швидке оновлення під час внесення змін.
Також Nitro додав фреймворку full-stack нових можливостей. Створивши лише каталог server
, розробник уже може створювати свою серверну логіку в самому Nuxt 3. Загалом Nuxt 3 тепер ближчий до простого та інтуїтивно зрозумілого full-stack фреймворку.
Через те, що проєкт досить об’ємний та постійно переживає велику кількість А/В-тестів, досить гострою була і проблема гнучкості. Зважаючи на статичну генерацію (SSG) та специфічну серверну архітектуру для зв’язки з Laravel Blade, було досить некомфортно масштабувати проєкт.
Це обмежувало реалізацію певного функціоналу та подекуди призводило до непередбачених труднощів, як-от, наприклад, до проблеми рендерингу та ваги об’ємних за вмістом сторінок залежно від А/В-тест змінної, заплутаної системи роутингу та імпортів, проблеми використання синтаксису Laravel Blade та отримання даних до рендерингу сторінки, втрати даних з LS та Cookies за певних умов тощо.
Composition API та Composables
Революційний Composition API пропонує гнучку структуру коду з можливістю багаторазового використання, що робить роботу розробника менш суворою порівняно з Options API, адже фреймворк стає більш схожим на React.
Основна перевага Composition API полягає в тому, що він дає змогу чистого та ефективного повторного використання логіки у формі композиційних функцій. Він усуває всі недоліки міксинів, основного механізму повторного використання логіки для Options API. Більш гнучка організація коду в Composition API дозволяє краще групувати код на логічні блоки.
Також однією з найважливіших переваг Composition API є його високий рівень абстракції, який полегшує життя розробників, особливо тих, хто не має глибокого досвіду з Vue або Nuxt. Тепер вони можуть використовувати свої знання звичайного JavaScript, не витрачаючи багато зусиль на вивчення синтаксису Vue.
Composables — це, по суті, функції, які інкапсулюють загальну логіку та можуть використовуватися кількома компонентами. Вони забезпечують модульний і гнучкий підхід до створення програм Vue та полегшують підтримку складних проєктів.
Недоліки SSG: чому цей підхід застарів
Маючи SSG (Static Site Generation), нам було досить незручно проводити велику кількість A/B-тестів.
Взагалі статичне генерування вебсайтів довгий час було доволі популярним рішенням. Проте згодом на поверхню стали виходити його суттєві недоліки, які важко ігнорувати, особливо, коли йдеться про великі проєкти:
- Обмежена динамічність. SSG чудово справляється з статичними сайтами, але коли потрібно обробляти часті оновлення або велику кількість динамічного контенту, виникають проблеми. Тому підтримувати актуальність такого контенту не завжди ефективно.
- Перевантаження. Зберігання та генерація великої кількості статичних файлів може призвести до збільшення обсягу проєкту та ускладнити його управління.
- Складність обробки запитів на стороні клієнта. Оскільки SSG генерує статичний контент, обробка запитів користувача стає складною задачею. В реальному часі оновлювати великі обсяги даних може бути неефективно.
Перехід до SSR та його переваги над SSG
SSR (Server-Side Rendering) та SSG (Static Site Generation) — це два різних підходи до генерації контенту для вебсайтів.
Розглянемо переваги SSR над SSG:
- Динамічність контенту. SSR дозволяє генерувати контент динамічно на сервері при кожному запиті. Це корисно для сайтів, де контент часто оновлюється, або для вебзастосунків, де потрібна взаємодія з сервером на стороні клієнта.
- Прямий доступ до бази даних під час генерації сторінки на сервері. Це важливо для вебзастосунків, які потребують актуальних даних під час завантаження сторінки.
- Real-time оновлення. Завдяки SSR можна надавати користувачам актуальні дані в режимі реального часу без необхідності чекати на перегенерацію всього сайту.
- Динамічні параметри шляху (Dynamic Path Parameters). SSR дозволяє використовувати динамічні параметри шляху, що дозволяє створювати сторінки з унікальними URL-адресами для різних сутностей.
- Контроль генерації контенту і обробки запитів знаходиться на сервері.
Відхід від SSG та вибір на користь серверного рендерингу (SSR) з використанням всіх його переваг зробило Front-end частину нашого проєкту більш гнучкою та надійною.
TypeScript
Однією з причин рефакторингу була необхідність в коді, що буде більш надійним та який буде легше підтримувати. Додавання TypeScript до нашого проєкту — крок, який суттєво полегшив життя розробників.
Використання TypeScript має низку беззаперечних переваг:
- Статична типізація. TypeScript дозволяє визначати типи, що дозволяє попереджати виникнення помилок під час розробки.
- Прискорена робота. Завдяки підказкам та автодоповненню коду, TypeScript прискорює його написання та виправлення.
- Легкий рефакторинг.
- Активна спільнота. TypeScript має велику та активну комʼюніті розробників, що означає доступ до різноманітних інструментів та ресурсів.
- Сумісність з JavaScript. TypeScript взаємодіє з наявним JavaScript-кодом, дозволяючи поступово впроваджувати його в проєкт.
Словом TypeScript — це інструмент, що робить розробку більш зручною й надійною та, як результат, підвищує якість коду.
Перехід від Bootstrap до Tailwind CSS: технічні аспекти
Bootstrap хоча і став стандартом для фронтенд-розробки, але він не завжди є оптимальним вибором з технічної точки зору. Тож наведу низку технічних аспектів, що можуть впливати на рішення перейти на Tailwind:
- Вага та продуктивність. Bootstrap, будучи повноцінним фреймворком, має великий розмір, що може вплинути на час завантаження сторінки. Tailwind же пропонує модульний підхід та можливість генерації легкого CSS, що сприяє меншому розміру збірки та продуктивності.
- Архітектура класів та масштабованість. Bootstrap надає велику кількість класів для стилізації, що може призводити до пасивного та важкого коду, особливо у великих проєктах. Tailwind пропонує концепцію Utility-First з акцентом на використанні конкретних класів для стилізації, що полегшує масштабування та обслуговування коду.
- Кастомізація та гнучкість. На противагу обмеженим можливостям кастомізації у Bootstrap, Tailwind дозволяє розробникам зберігати більше контролю над дизайном.
- Мінімізація використання JavaScript. Bootstrap включає значну кількість JavaScript-коду, який може бути непотрібним для певних проєктів. Tailwind дозволяє розробникам вибирати та використовувати стільки JS, скільки їм потрібно.
Nuxt3 має досить велику сумісність з даним фреймворком. Налаштування Tailwind є доволі простими, а гнучкість кастомізації дозволяє максимально швидко перебудувати проєкт під необхідні налаштування.
Після переходу на Tailwind знову відчуваєш радість життя та отримуєш задоволення від звичайної верстки😄
Pinia
Наступним рішенням було замінити Vuex на Pinia як основний інструмент управління станом. API Pinia простіший та інтуїтивніший, все стає зрозуміло з перших сторінок документації.
Переваги цього інструменту:
- Реактивність та швидкодія. Pinia використовує принципи Vue 3.0 та його реактивності. У порівнянні з Vuex, Pinia дозволяє більш ефективно використовувати систему реактивності Vue.
- Організація коду. Pinia впроваджує концепцію модульної організації стору, де кожен модуль може мати свій власний стан, мутації та екшени. Це спрощує структуру коду та дозволяє краще масштабувати застосунки.
- Завантаження коду. Pinia надає можливість лінивого завантаження модулів стору, що означає, що код для конкретного модуля завантажується лише тоді, коли він справді потрібний. Це сприяє оптимізації завантаження стору.
- Типізація та TypeScript. Pinia призначений для роботи із TypeScript «з коробки», надаючи переваги статичної типізації для розробників. Тоді як Vuex також може працювати з TypeScript, Pinia забезпечує більш глибоку інтеграцію та зручний синтаксис.
- Persist state. Pinia надає вбудовану підтримку persist state, що дозволяє зберегти стан застосунку навіть після перезавантаження сторінки. Це дуже корисно для тривалих сеансів роботи.
Додаткові зміни
Окрім запровадження наведених вище змін, було виконано значний обсяг рефакторингу та налагодження розгортання.
Ми також реалізували архітектуру розгортання для різних середовищ (DEV, TEST, MODL, PROD) з відповідними конфігураціями. Додали автоматизовані тести для забезпечення якості коду, а також health check для виявлення стану системи та її компонентів.
І внаслідок цього...
Ми оновили проєкт до Nuxt 3, де впроваджено серверний рендеринг (SSR). Оновлення стеку технологій, зокрема перехід на Vue 3/Nuxt 3, TypeScript, Pinia та інші, призвело до значного покращення функціональності та стабільності. Використання Vite/Nitro дозволило зменшити час розробки та деплою. Заміна CSS-фреймворка на Tailwind сприяла прискоренню верстки та полегшенню роботи розробників.
Результатом цих змін став зменшений розмір збірки та покращені показники швидкодії сайту. Упровадження тестового середовища та автотестів сприяло зменшенню кількості багів та підвищило стабільність продакшену.
Проєкт загалом став простішим у масштабуванні, надійнішим та легшим у підтримці. Час, що ми витратили на рефакторинг, вибір та імплементацію нових технологій точно був того вартий, адже результат на всі 100 відсотків відповідає потребам як команди розробників, так і бізнесу.
8 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів