Галоўная / Артыкулы

Рэакцыя без мета-фреймворка: захаваныя выкладкі пайтонскага бэкенду

Чаму React плюс Vite на не-JavaScript-бэкендзе адхоўляе дыскусію пра Next.js, якія функцыі фрэймворкаў вам даводзіцца перабудаваць, і як кераваць сувязямі межы ўсіма элементамі.

Выдавец: REACTAPP.TOP7 хв чытання1689 слоў

Крыніцы: Everyone’s Leaving Next.js. I Never Showed Up.

Большасць дыялогаў пра фрэймворкі React предпакуе наяўнасць толькі двух варыянтаў: застацца на Next.js або перайсці да таго, што ў даны час працавае як йго наступнік — будзь то Astro, Remix чы TanStack Start. Значны частака рэальных прыкладоў застосоў на React не выбірае ні аднага з гэтых падходаў. Яны ствараюць кліентскую частку з адной сторанай за дапамогою Vite і вяршаюць зв’язак з бэкендам, напісаным на Python, Ruby чы PHP, які вже керуе базай дадзеных, бізнес-правіламі і API. У этай статыце часова рассматрываецца гэты трэці варыянт: якія працы ўжо не стосуюцься мета-фрэймворкаў, якія абавязакі тыха пераходзяць у ваш сэнсабльны код і як падтрымваць створаны такім чынам фрэймворк у працездатны стан.

Конкрэтны прыклад трэцьяго варыянта

Уявіце сабэстояння здароў’я населення, яка стежыць за адзначэннем пашчотных вяскаў у ўжоўм. Фронтэнд апрацоўваецца на React і TypeScript, пры чым як бібліятэка компанентаў выкорыстоўваецца Ant Design. Серверная частка — Frappe, фрэймворк на Python, які ўтрамбоввае ERPNext. Frappe визначае модэлі дадзеных як „doctypes“, керуе базай дадзеных і выклікае методы на Python зі спісу дазволеных як канцэнтры API. У працоўным режыме няма экзэкютавальнага сераўера Node.js, няма маршрутацыйнага прыстрою для аплікацый і няма серверных компанентаў, якія б выбіралі, калькі часткі інтэрфейса могу з’яўляцца да базы дадзеных. React атрымлівае экран; Frappe робіць усё іншае.

Для команды, якая знаходзіцца ў такой пазицыі, большасць найгучнейшых аргументаў проты Next.js є нерэлевантнымі. Закрэпленне на Vercel не мае значэння, калі там нічога не размешчаецца. Павольная замена модуляў пад маршрутацыйным прыстроем аплікацый не ёсць проблемай, калі Vite запускае сервер разработкі і перазавантажвае контэнт настолькі шыбка, што ніхто пра гэта не думае.

Тая ж сама архітектура выкорыстоўваецца кожны раз, калі React прыўязуецца да Django, Rails, Laravel чыя-небудзь іншая платформа, якая вже мае свою сэрверную структуру. Аднак застаюцца і іншыя прытваранні ўжо да мета-фрэймворкаў. Яны проста праглядаюцца з іншага крыту.

Вы все раве ствараеце фрэймворк, по аднай практычной функциі за раз

Адмова ад мета-фрэймворка не пазбавляе вас проблем, якія ён рашае. Яны пераходзяць у ваш код, дзе вам самым трэба іх рашыць, зазвычай пасляпелым чынам і без чыткага названня таго, што вы ствараеце. Тры прыклады з дапамогай аплікацыі fortification паказваюць такі патэрн.

Формы, керованыя схемай, заместо стандартаў фрэймворка

Команда створыла компонент DynamicForm, які выкарбоввае формы безпосередна з адзінакоў JSON, якія надае бэкенд. Ён чытае схему, визначае, якія поля існуюць і які у іх тип, пазначае обавязковыя поля, керуе полямі, чыя видазрэннасць або значэнне залежыць ад іншага поля, і выкарбоввае цэлую форму. Для дадзення новага адзінакоў больш не трэба рукамі пісаць форму.

Это ўзята з прыняцоўкі, а не з настройкі — галоўная обяцанне кожнага мета-фрэймворка, які быў реалізаваны самастоятельна. Гэта таксама не спрацавала з першай спробы: компонент прыняў тры полныя перапісвы, прычым стаў стабільным. Фрэймворк бы практычна сам абработаў усія гэтыя ітерацыі за вас, среди тысяч корыстнікаў.

Загрузка з паградуваннем без шара дадзеных

У звяздцы паказана мэтода, якая дазволяе завантажваць рядкі пакетамі па меры прасування корыстніка. Без getServerSideProps, адпаведнага прыемка дадзеных або іншай функцыі, задаўная ў рамках фрэймворку, рашэнне было створана з разных элементаў: IntersectionObserver, які стежыць за элементам пад канцом спіса, ручна фіксаваныя пазначкі положэння курсора на старонцы, а таксама стан завантажэння, пры якому патрэбна была самастайна разрабоць логіку. Чы хаця бы спінер павінен з’явіцца пад канцом, чы новыя рядкі проста должны з’являцца поступова? Калі няма рэкамендацый фрэймворку, адзін разрабох няўзабаве прымець гэтае рашэнне пад час звычайнага рабочага дня.

У настроюванні React-plus-Vite бібліятэка, такая як TanStack Query, можа запрацаваць для адміністрыравання большай часткі гэтаго (бесканальныя запыткі, курсары, пазнакі завантажэння), і ўцёмкаеяцца яе адразу пераканацца, прычым не пісаць логіку самому. Асновная ідея застаецца тая ж: хтось трэба выбраць і абавязацца за шар дадзеных.

Шар адаптатора для неоднаковых дадзеных бэкэнда

У выпадаючых спісах для прыблізна дзесятка типоў дадзеных трэба было паказваць меткі, зрозумелыя чалавеку, але кожны тип дадзеных называў свое поле меткі інакш. Дзеяныя выкарыстоўвалі label, іншыя — title, а ў аднам старым типе дадзеных — display_name. Невялікая функцыя mapOptions нормалізуе ўсе іх у аднаковы формат, так што кожны компонент выпадаючага спіса можа ігнараваць гэтую неоднаковасць.

Ніхто не назваў бы гэта архітектурай, пры тым што саме такая нормалізацыя зазвычай прыменяецца за дапамогою стандартных правілаў фрэймворка. Кожная команда зрэшты піша тые самыя елементы, якія мог бы запроста стварыць мета-фрэймворк. Єдыны выбар — це чы робіць гэта, прыймаючы практікі фрэймворка, чы витрачаючы сабе час на розрабоцу.

Калі самастворыты фрэймворк стае проблемай

Праўыя выклікі з’являюцца пазней. Чырэз калькі гадоў компонент DynamicForm быў пазначаны SonarQube як маючы чрэзмерную когнітыўную складнасць. Гэта не была баг у бібліятэке чы несумеснасць версій. Це было звычайнае расшырэнне компонента: адны файл таямна стаў як шар маршрутацыі, так і шар формы, і шар верыфікацыі ў програме.

Рефактарызацыя паказала, насколькі заплутаным стаў код. Выявленне логікі пераканання ў правамернасці ў самастоятню функцыю адкрыло чатыры незв’язаныя шляхі коду, якія залежалі ад побачных эфектаў, спрывучыхся ўнутры компонента. Гэта той «падатак», які рэдка бачыце на рахунку, калі прыменяеце мета-фрэймворк. Вы пішаце інфраструктуру, і ў той жытак стаеце яе едынай документацыяй. Не існуе популярных трэкераў проблем, дзе хтось іншы страждаў ад тых сабе падобных проблем і выпускаў способы ўсунення.

Спосаб усунення проблемы быў адпаведны звычайнам методу дэкомпанавання:

  • Пераказаць рашэнне пытанняў, залежных ад полей, у спецыяльны кастомны хук.
  • Размістыць логіку пераканання ў правамернасці ў аддзельны модуль, які нічога не ведае пра тое, як атрыбуты формы выкарстаныя.
  • Заставіць сам компонент адпавядаць толькі за выкарстаные.

Пасля раздзелення рэштунак сложнасці знизіўся, і компанент стаў лёгкім да чытання. Абщая наука заключаецца ў тым, што раздзелэнне абавясцей, якое мета-фрэймворк прыменяе за правіламі, у самастоятельнай структуры павінна прыменяцца за працэсам, ў кожны раз. Жаданы лінтар не паведамляе вас пра тое, што вы неправільна перабудовваеце слой дадзэнняя фрэймворка. Корыстныя прывычкі тут – періядычныя звіты пра сложнасць, адзінаковыя перагляды коду, у якіх ставіцца пытанне «чы не ператвараецца гэты компанент на інфраструктуру?», а таксама короткая внутраняя дакументацыя для будзь-якага інструменту, ад якога залежыць больш за калькі экранаў.

Багі, якія існуюць у з’еднанні двух экасистем

Фрэймворк, такі як Next.js, керуе як серверам, так і кліентам, таму межа межы ўсё гэта праектуецца як адна система. Калі React работае з Python-бэкендам, гэтую межу трэба визначаць самому, і гэта стварае адзінаковы клас багоў.

Адзін прыклад: канфлікт MySQL Error 1292, які трэба было аднаважваць праз большую частку дня. Штрафныя паведамленні супаказваюць невалідны або некоректна па формату значэнне даты чыста часу. Форма на React адправляла даты ў аднам формате, а ORM Frappe чакаў іншага. Ні фронтэнд, ні бэкэнд самі па сабе не былі няправыя; проблема выйшла з перакладу между двумя экосістэмамі, якія ніколі не былі створаны разам, а з’еднаны традыцыямі, створанымі месяцямі раней і часткова забутымі.

Іншы прыклад: нечакана робота верыфікатора сілы пароля ўнутры хука after_insert бэкэнда, які запускаўся па формату даных, якія адправляла форма і які ніхто не тэставаў. Жадны чарт змян фреймворка не охопляе такую взаімаўпрацу, таму што жадны мета-фреймворк не ведае пра існаванне Frappe. Дэбаггін значыць чытаць як ваш код, так і кантэнт выхадных кодаў бэкэнд-фреймворка, пакуль два бокі прыгодкі не з’явяцца адносна едны.

Калькі прыемнія захоплення проты багоў у швах:

  • Серыялізавайце даты і часовыя моменты толькі ў аднам месцы на кліяне, у формате, заданым бэкендам, а не для кожнай формы.
  • Спрыяйце запиту як да кантракту: задайце його на TypeScript і, як толькі можна, пераканаўце його на обох бокох.
  • Запісвайце тэсты інтеграцыі, якія надаюць рэальныя даны запиту бэкенду, уключаючы нестандартныя форматы, таму што хукі на стороне сервера рэагуюць на даны, якіх можна не чакаць.
  • Запісвайце необработаны пакет даных у разе абэрэнцій пераканаўкі на бэкендзе, каб несувяместнасць была відразу видна.

Якщо вашы задній канал таксама напісаны на JavaScript, спяльная схема верыфікацыі зменшае вельмі частку такіх трудносцей; пагляньце на спяльнае викорыстоўванне адной схемы Zod між фронтэндам на React і заднім каналам на Node. Калі задній канал напісаны на Python, код нельга спяляваць, але контракт все ж можна раздаваць.

Правильная падготовка да рашэння

Дыскусія пра „каторы мета-фрэймворк“ вырахоўвае, што задній канал можна перагаварыць. Для багато команд гэта не так. Якщо існуючыя прыкладніцы на Django, Rails, Laravel або Frappe вже керуюць серверам, то React плюс Vite — гэта не компроміс; гэта натуральная архітектура. Асалодны вопыт стае тым, якую частку задач фрэймворка вы гатовы самі ствараць і падтрымваць на адной вялікай базе, якая вже існуе.

У замену вы можете выбраць бэкэнд, який падходзіць да вашага домэна. Для системы, пабудованай на doctype і Python hooks, такая свабода ўзначальна. Але за яе трэба платіць, перадумваючыся пра всі наследкі такага выбору.

Ключовыя выводы

  • Аргументы пра залежнасць ад Vercel і неабходнасць міграцыі через app router справядлівыя, але яны не стосуюцца кліентаў на React, якія працуюць з бэкэндам, не базаваным на JavaScript.
  • Без мета-фрэймворку вы все раве ствараеце шаблоны форм, механізмы завантажэння і нормалізацыі дадзеных; вы проста робіце гэта самі і застаецеся ўсёвылучнаяўцамі гэтых элементаў.
  • Інфраструктура, створаная самімі, часта ператвараецца на заплутаныя компоненты; ўсвядомлена прабавайце даглядаць за раздзеленнем функцый і задокументавайце спільныя інструменты.
  • Межа між кліентам і серверам — ваша адпаведнасць: цэнтрызуйце процес серыялізацыі, задайце формат пакета дадзеных і тэставайце ўсё на рэальным бэкэндзе.
  • Ніяны з гэтых парадактов не ўсё простыя. Яны меняюць падходы да фрэймворкаў на час на выкананне інжынерных задач, а правы выбор залежыць ад таго, якому бэкенду вы насправды прысвячылі ся.