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

Выбір структуры папак у React: сэм варыянтав структуры і ўсі моменты, калі яны перестаюць працаваць.

Пораўняйце плоскія, типовыя, функцыйна-оріентаваныя, Atomic Design, DDD, Feature-Sliced Design і монорепо-структуры для React, а таксама дакладзіце ведомась пра тыя меркі, на якіх кожна з іх перестае працаваць.

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

Крыніцы: React Folder Structure: 7 Ways to Organize a React App (And Exactly When Each One Breaks)

Кожная развіваючыся база коду на React рано чыта прыходзіць да таго ж пытання: куда падаць гэты файл? Афіцыйнай адказы няма, пры тым каманды витрачаюць цэлыя спрінты на перанасленне между разнымі структурамі, а спакавальнікі продовжваюць запытваць кандыдатаў пра гэта. У гэтым нарадніку параваняюцца семь распашчытных спосабоў арганізацыі дапрацоўкі на React — ад простаг падпакета src/ да манорепа з калькамя дапрацоўак, пры чым усючас викорыстоўваецца адна прыкладная дапрацоўка. Для кожнай структуры вы пазнаеце, што гэта такое, хто насправдзе яе выкорыстоўвае, чаму ёй паслужае, дзе ёсць проблемы, і точную прычыну, чаму ёна перестае работаць, тады вы зможаце выбраць самую простую структуру, якая падходзіць вашай дапрацоўцы.

Ніхто афіцыйны не выберае за вас

У даследнай літаратурэ React калісьці была сторанка пра структуру файлоў. У яй пачыналася з таго, што зазначалася, iż React не мае ніякага адгуку ўжо да таго, як файлы размешчаюцца ў папках, і радзілася всем, хто запускае проект, не витрачаць больш чым пяць хвілін на выбор структуры. Што пазней сторанка была адключыта, калі даследнай літаратурэ перайшла на react.dev, і нічога яе не заменілася. Сэргодні React практычна нічога не кажа пра папкі. Старыя рэкамендаціі застаюцца на архіванай сторанцы FAQ.

Фрэймворкі і інструменты, якія выкарыстоўваюцца разам з React, таксама не маюць чыязвучных рэкамендацый. Next.js описвае сябе як не маючы адгуку ўжо да таго, як організаваны і размешчаны файлы проекту. Шаблон React у Vite стварае калькі ісходных файлоў, а папак там немае. Ніякая автарытетная структура ў экасистеме не кажа, што трэба робіць.

Гэтыя абсэнцыяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяяя

Людзі, які створылі гэтыя методыкі, зазвычай ставяцца да іх значна лёгкая, у працоўнай практыцы, чым тыя, хто іх прымоўчвае. Брад Фрост, які створыў Atomic Design, у 2019 годзе выдаў кнігу „Extending Atomic Design“. У яй он описвае, як людзі звяртаюцца да ўсёго яго, каб „скорэкаваць“ його термінологію, напамінае, што atomic design не ўжо строгая дагматыка, і кажа, што команды, якія хочуць дзевяць стадій, названых на чэстку учаснікаў групы Chicago, могу цэлкам так чыніць. Яе можна прачытаць на Extending Atomic Design. Стваральнік методыкі кажа, што назвы не маюць значэння, тады як где-то процес перагляду коду застаўся на стадіі спора ўжо тое, чы розглядаць компонент як молекулу.

Старыя дасведчэнні React таксама праменаваліся на Atomic Design па імени. У яных згадвалася, што дзеяры раздзеляюць компаненты на папкі згідна з их роллю ў працоўнік, наводзілася Atomic Design як прыклад такога падходу, і рэкамендавалася спрыяць такім методам як корыстным прыкладам, а не як строгім правілам. Урахаваючы, што гэта выказана ў самых дасведчэннях React, гэта лепшая наяўная крітыка строгага падходу да Atomic Design у React.

Screaming Architecture

У гэтым спарчы насправды існуе толькі адна значныя аргументацыя, і яна старэйшая за React. У верасні 2011 года Роберт К. Мартын опублікав Screaming Architecture. Яго запытанне: калі хтось адразу бачыць верхніяй каталогі вашага прыемлена, чы можа ён адразу разбіраць, чы гэта система здравоохранення, бухгалтерскія система чы система утримання запасоў? Яго вывад быў такі, што архітектура павинна рассказваць чытачам пра саму систему, а не пра фреймворкі, якія ў яе викорыстоўваюцца.

Гэта ідея лежыць у основе кожнай структуры, падбіранай на адпаведнае функцыянаванне. src/, які мае папкі components/, hooks/, utils/ і services/, паведамляе, што цэта — аплікацыя на React. src/, які мае папкі checkout/, billing/ і inventory/, паведамляе, чым займаецца бізнес. Кожная структура, описаная ў гэтым кяле, являецца альбо варіяцыяй гэтай ідеі, альбо ўсвядомленым адклэненням ад яе.

Колокацыя

Другі прынцып мае найбольшы значэнь у практычной дзейнасці. Кент С. Доддс называе яго колокацыяй: трэба размешчаць код якомога ближэй да месца, дзе ён неабходны. Ён прызнаёт, што Дан Абрамов запропанав болей тачны выраз, а саме: элементы, якія змінююцца разам, павінны знаходзіцца якомога ближэй адзін да другога. Полныя аргументы ў статте Colocation.

Якща паглядзець на гэта з такой точкі зору, кожны макет у гэтым падраборніку адпавядае на аднае запытанне: якія часткі вашага коду развіваюцца як адна ейка? Якщо вы правільна адпавясце на гэта запытанне, папкі практычна самі сабе ствараюцца. Якщо ж адпавясце неправільна, ніяка методалогія вас не вывяжаць.

Прымечанне да популярнага цитатавання: прадакт «перамешчайце файлы, пакуль не будзе здавацца правільна» шырока асоціюецца з Данам Абрамовым і іноды наводзіцца як офіцыйная дакументацыя React. Гэта не ўскладненая дакументацыя; у яй супакоўваюцца прадакты на пяць хвілін, а цитата Абрамова берэцца з твіта, які, вядома, быў выдалены. Сэнтымент у гэтым прадакце правільны; спрыяйце гэтаму цитаванню як фольклору.

Адна прыкладная аплікацыя, семь варыянтаў

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

  • Функцыі: аутэнтыкацыя (заходжанне і регистрацыя), каталог (спіс та дакладныя відомасці продуктав), кошык, процес платежа і замовленні.
  • Прымітывы UI: Button, Input, Modal, Badge і Spinner.
  • Hooks: useAuth, useCart, useProducts, useCheckout і useDebounce.
  • Модулі API: authApi, productsApi, checkoutApi, ordersApi і спяльны apiClient.
  • Іншае: дапаможны элемент cartStore і функцыя formatPrice.

Чатыры з тых файлаў ўмышлена складныя, бо яны паказваюць, дзе кожная структура начынае вызваліваць проблемы:

  • Modal.jsx атрыбутуецца як атам, молекула чы ўраджэнне залежна ад таго, хто яго класіфікуе, што падкрэсляе таксанамію Atomic Design.
  • useDebounce.js ўсё цяпер загальнага характару, пры тым яго викорыстоўвае толькі пошук у каталозе. Ці гэта глобальны хук, чы каталожны хук?
  • CartTotal.jsx атрыбуецца ўнутрь вікна каравана, а таксама на экране пракупкі, таму незрозумела, хто яго стварыў.
  • formatPrice.js выглядае як простая утиліта, як толькі грошы не ёсць рэальным паняйом у данай галіне, у такім случае яго трэба было бы зробіць об’ектам значэння Money, а размешчанне яго ў папцы з утилітамі — гэта абэчанне.

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

Плоская структура

Што гэта такое

Усе знаходзіцца безпасулькі ў src/, без або майже без папак, у алфавітным порядку, таму што нічога іншаго не наводзіць адпаведнага порядку.

Ніхто не публікав гэта як методыку. Гэта проста тое месца, дзе пачынаецца кожны проект, і дзе застаёцца значныя колькасць з яўных. Дакументацыя React таксама рэкамендавала гэта як пункт выйску: якщо вам здаецца, што вы застрялі, трывайце всі файлы ў адной папцы, а калі яна стане достатнька вялікай, каб патрэбна была ўдзеленне, вы з’ясуеце, якія файлы вы зазвычай рэдзіце разам. Гэта справды хорашыя парады. Структура, выведзена з адазорваных законамасцей змян, краща за тую, якая наводзіцца з самага пачатку.

Калі ўжоўаюць яе

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

Афіцыйны шаблон Vite React па суты є простым. Выкананне команды npm create vite@latest -- --template react-ts стварае файлы main.tsx, App.tsx, App.css, index.css і папку assets/; папакі components/ чы р features/ няма. Паколькі шаблон не выражае жадных паводзаканняў, дыскусіі проста пераходзяць да кожнай команды, якая яго выкорыстоўвае.

Адрозніцы

  • Навігацыя не каштуе нічога. Є толькі адна папка, а прыстрой для выбору файлоў можа знайсці ўсё па імени. Не будучы неабходнымяя рашэнняя ўжываць паводзаканнія ўзгадвання розташоўкі, не існуе таксама ніяких спораў па гэтую тэму.
  • Рефактораванне ўжо безкоштовна. Няма структуры, якую трэба нарабаты, таму няма чаго мігруваць. Вы можете быстра дзейсніць змяны, з’ясавіць, чым насправды є аплікацыя, і арганізаваць ўсё, калі зразумеете.
  • Ён чыста адносіцца да неяснасцэў. У першы тыдзень вы не знаеце меж сваіх функцый, і простая структура не выдавала б галоўныя моменты. Кожная папка, створаная так рана, — це толькі прыпуск, за які пазней можа знадобіцца платіць, каб яго скасаваць.
  • Слабасці

    • Ён раптова перестае падтрымліваць вялікі калібр пры адносна 30 файлах. Адказка не ўскладнюецца паступова: адны дзень список файлоў больш не пасвячаецца ў бокавай панелі, і форма аплікацыі зникае.
    • Абэчны порядак не мае ніякога значэння. authApi.js знаходзіцца ручыма з App.jsx толькі таму, што оба пачынаюцца на літеру A, тады як useAuth.js і LoginForm.jsx, якія вы завжды рэдагуеце разам, апошнія знаходзяцца далека адзін ад другога. Порядак сортавання працуе проты правільнага розташоўвання элементаў.
    • Няма меракоў, якія трэба было б прыменяць. Кожны файл можа імпортуваць любы іншы, ціркулярныя залежнасці прасачуцца непазірана, і калі вы вже хочаце запэўніць меракі, кожна наявная абэрэнцыя стае значным фактарам.
    • Адзёрванне якога-небудзь функцыяналу ператвараецца на сложную задачу. Чым удаліць процедуру прайшчыпкі, тым трэба чытаць файлы, каб з’ясавіць, якіе з іх да ёй належаць, адтолькі што няма папкі, яку можна было б адзёрваць.

    Дзе ўсё ламаецца

    Пры аб’еме прыблізна 30 файлоў, або калі прыўязываецца другі разработчык, другі праграма становіць больш значны. Плоская структура працюе тады, калі адна людзь мае всю інфармацыю ў галаве. Калі ж працуе два чалавеки, у іх є два «карты», якія адразу ж пачынаюць розходзіцца.

    Структура на адной основе

    Што гэта такое

    Файлы групуюцца за ўмовам іх прызначэння: компаненты разам, хукі разам, вызовы API разам, сховішчы разам. У давэльных дасведчальных матэріалах React гэта описвалася як групаванне за типам файлу, і гэта была паказана як адна з двух распашчытых падходоў без выбірання якога-небудзь з іх. Для прыкладнага дапаможнага праграмы гэта значыць Button, Modal, CartItem, CheckoutForm і ўсе іншыя компаненты ў папцы components/, усе хукі ў папцы hooks/, усі модулі API ў папцы api/, а таксама cartStore ў папцы store/.

    Паколькі большасць туторыяў яго выучвае, гэта таксама структура, якую вы часта зустрэнете ў рэальных проектах.

    Хто яго выкарыстоўвае

    Практычна ўсе туторыялы па React, большасць проектаў у буткампах і значны частака прыладоў, якія выраслі за межы плоскага лейауту без чатаргавання. это найпростейшы крок: як толькі папка src/ запрацоўваецца, папка components/ стае ежыстковай першай рэакцыяю.

    Адрознікі

    • Яго не трэба адгрунтавваць. Нікому ніколі не было трэба поясняць, што мае належаць у hooks/, таму новыя разработчыкі можаць дапрацаввацца вучора, выкарыстоўваючы вокабуляр, які ўжо знаюць.
    • Класыфікацыя ўсё проста. Компонент кладзіцца у components/, хук — у hooks/, а сам файл паведамляе, які ён. Пораўняйце з Atomic Design, дзе розумныя людзі можаць спарчвацца над адним компонентам гадзіну.
    • Ён аблікова падходзіць для малых проектаў. Пры менш чым 50 файлах ён працуе добра, а перайшоў на іншы падход будзе коштаць больш, чым прыносіць.

    Слабасці

    • У яго аанонсувается фрэймворк, а не сам продукт, што якраз і ўскладнюе розумэнне. Тэплівыя папкі з назвамі components/, hooks/, api/ і utils/ паведамляюць новачку, што вы викорыстоўваеце React, але не даюць жадных вясканняў пра тое, чым займаецца дапрацоўка. І інтэрнет-магазін, і календар распісаў у лікарні з восьвятковага рэверсу выглядаюць аднакова.
  • Кожныя змены распространяюцца па всій структуре. Дадзенне аднаго поля ў кошык значыць неабходнасць праверкі файла CartItem.jsx, які знаходзится ў падпапцы components/, файла useCart.js у падпапцы hooks/, файла cartApi.js у падпапцы api/ і файла cartStore.js у падпапцы store/. Такім чынам, за адну логічную змену трэба працаваць у чатырох падпапках і переключацца на чатыры разныя позіцыі прасування. Правіла проекта не дазволяюць размешчаць файлы, якія, як правило, зменяюцца ў аднай коміт-запісі, побліжа ўсіх іншых.
  • Падпапка components/ ператвараецца на новую плоскую папку. У прыкладным дапрацоўке ў яй знаходзится або 18 файлаў без внутрашняй групавання. Проблема плоскай структуры рашаецца для модуляў hooks і API, але знова выявляецца ў папцы, якая містіць большую частку коду.
  • Адзінакоўка функцыі значыць неабходнасць пошуку ў кальколькох папках замест аднай. Чысткі выкалывання процэсу платежа заставляе трэбавацца чатырох каталогаў і спадзявацца, што нічаго не было праўлена.
  • Гранічныя абмежэння яшчэ не існуюць. Нічто не заважае ProductCard імпортуваць useCheckout; папкі маюць выключна дэзорганізуючы эфект.
  • Дзе выступаюць проблемы

    Калі колькасць файлаў доходзіць да 100, або калі папка components/ містіць абоўша 20 елементаў, з’являецца адзінакоўка: разработчыкі начынаюць дадаваць прэфіксы да назв файлаў, такія як CartItem, CartDrawer і CartTotal, каб падрабіць групаванне, якое не здабываецца за дапамогою папак. Гэтыя прэфіксы ў сушчыні являюцься запросам кодавой базы пра стварэнне папак для функцый.

    Структура на адзінакоўку функцый

    Што гэта такое

    Файлы групавацца па функцыях, якія яны выкананяюць. Кожна функцыя мае своія складовыя, хукі, вызывы API і стан у аднам месцы; спяльныя прымітывы знаходзяцца ў спяльнай зоне, а функцыі складаюцца на рэвэльнай ступені без аднароўкі ў адныя другія.

    Даследнія дакументы React называлі такую групаванне па функцыях або маршрутах і прастаўалі практычны спосаб размежавання. Паколькі значэнне «функцыя» не ўсюды адно, вы самі выбіраеце ступень дзейловасці; калі вы не можетэ з’явіцься са спісам фолдераў вышэйшага рангу, вашы корыстувальнікі можаць описаць галоўныя часты ўтворэння і выкорыстаць свой ментальны модель як план. Гэта, можна сказаць, найпрактычнейшы адказ у всім гэтым тэме: вашы корыстувальнікі вялікі час ведаюць, дзе знаходзяцца межы вашых функцый.

    Парадоксальна рэч у тым, што гэта ў сутнасі «Screaming Architecture», перакладзенае на React, і сёньдзе гэта ўсё болей популярны выбар. У прыкладнай аплікацыі features/cart/ мае компаненты каштана, useCart — API каштана, а cartStore; features/checkout/ мае CheckoutForm, useCheckout і checkoutApi; і так далей, прычаму Button, Modal і іншые прымітывы знаходзяцца ў спяльнай папке components/.

    Калі ўжо яго выкарыстоўваюць

    Самая вядомая реалізацыя на прыкладзе — Bulletproof React ад Алана Аліковіча, яка мела або 35,5 тысяч зірак у GitHub і ў момент напісання статты яшчэ актыва была падтрымвана. Це найбольш распространёная структура React, і документ структуры проекта Bulletproof React варта прачытаць безпосередзя, а не паследваць пераказы з іншых источнаў.

    Рэкамендаваная структура src/ складаецца з роўна адзэннадцатых папак вышэйшага рангу, якія пераказаны нижэй разам з іх функцыямі. Заўважыце, што толькі адна з іх, features, арганізавана па тэматыкам; рэшта — це спяльныя шары, якія викорыстоўваюцься функцыямі, плюс шар app, які складае ўсё цэла.

    src
    +-- app          # application layer (routes, app.tsx, provider.tsx, router.tsx)
    +-- assets       # static files such as images, fonts, etc.
    +-- components   # shared components used across the entire application
    +-- config       # global configurations, exported env variables etc.
    +-- features     # feature based modules
    +-- hooks        # shared hooks used across the entire application
    +-- lib          # reusable libraries preconfigured for the application
    +-- stores       # global state stores
    +-- testing      # test utilities and mocks
    +-- types        # shared types used across the application
    +-- utils        # shared utility functions
    

    У кожнай функцыяй можа быць да семі сегментоў: api, assets, components, hooks, stores, types і utils. У дасведчэннях чытка пазначаецца, што функцыяй патрэбны толькі тые сегменты, якія ёй насправдзе выкарыстоўваюцца.

    Два правілы виконваюць большую частку роботы:

    • Няма імпортаў між функцыямі. Bulletproof React не рэкамендуе, каб адна функцыя імпортавала іншую, і працоўвае з рэкамендацыяй складаць функцыі на рэвэле аплікацыі, таким чынам кожная застаецца незалежной, а код становіцца лёгкім для разумення.
    • Однонаправлены поток. Код павінен пераходзіць толькі ў адным напрамку — з спадзяльнага коду да функцый, а потым да самай аплікацыі (shared -> features -> app).

    Обе правілы можна застосаваць за дапамою правіла ESLint import/no-restricted-paths. Гэты крок застосавання частаючы паскачуецца многімі командамі, і самэўсёлкі гэта ёст каляна, чаму з часам іх межы становяцца менш чыстымі.

    Файлы barrel: ранейша версія Bulletproof React рэкамендавала викорыстоўваць файлы barrel — index.js, які занова экспортуе публічныя элементы функцыянальнасці. Цяпер жа рэкамендуецца імпортуваць файлы безпосередна, адтуды што файлы barrel могу паўлікваць процес tree shaking у Vite і спрычыніць проблемы з выдаткамі. Якщо вы выучылі гэты падход з старэйшага керавання, рэкамендацыі змяніліся. Паколькі файлы barrel былі способам, якім большасць команд выражалае публічны API функцыянальнасці, ўсуненне іх значыць, што межы тепер вырашваюцца абоўсумова ў налаштаваннях лінта.

    Адрозныя моменты

    • Колакацыя прадстаўленая за замовчаннем. Адна зміна ў карцы паўтараецца ў адной папкі, таму што файлы, якія змінююцца разам, знаходзяцца ў адной папкі.
  • Выдаленне функцыі — це проста команда rm -rf. Выдаліце папку features/checkout/, выправіце элементы імпорту, пра якія скаржыцца кампайляр, і ўсё готава. Гэта мае большое значэнне, чым можа здавацца: код, які важка выдаліць, зазвычай ніколі не выдаляецца.
  • Домэн відразу видны з корневай папкі. Новы інжынер, які чытае папкі auth/, catalog/, cart/, checkout/ і orders/, розумее структуру продукту ўжо перш чым ачынае хоць які файл.
  • Межы можна прымусова застосавіць у вачынку помилак лінт-прабавакаў у системе CI заместо коментараў пасля перагледу.
  • Такая структура добра масштабуецца, нават паўз 1 000 файлоў, адтолькі кожная новая функцыя стварае новую папку, якая не зачыніцца ў спадарожніцтва з існуючымі.
  • Слабасці

    • „Фіча“ не мае фіксаванага адзначэння, таму будуць суперчанні ўжо па яго. Код CartTotal.jsx адрасаваецца як у роздзеле з кошыкам, так і пад час выкарыстоўвання функцыі адплата. Жадна з вароў ня ёсць правильная; проста трэба прымець рашэнне, якое, верагодна, будзе перазьвярнута.
    • Код, які выкарыстоўваецца спольна, кожны раз трэба адначасова ацэніваць. Код useDebounce сёння выкарыстоўваецца толькі пад час пошуку ў каталозе. Якщо зробіць яго глобальным, папка з спольнымі хукамі заполніцца элементамі, якія выкарыстоўваюцца толькі раз. Краща залишыць яго ў папце features/catalog/hooks/, а калі для вырахунку платы яго будзе трэба, трэба яго скопіюваць, імпортуваць у іншыя фічы (чаго не разрашаецца) або падняць яго у вышэйшы ранг.
    • Частковае раздзеленне на фічы занадта рано пашкодзіць ситуацыю ўсё больш, чым занадта ранняя абстракцыя. Размешчэнне 40-файловага прыемляра ў пяці папках фіч з’яўляе толькі формальнасці, а не структуру.
  • Канфігурацыя лінта не масштабуецца сама по сабе. Правіла праграмы Bulletproof React для разных функцыйяў выклікаюць патрэбу ў окремай зоне для кожной функцыі, якая сама сабе надае адступнення. Дзесяць функцыйяў значыць дзесяць ручна напісаных зон, а якщо забыць пра одну, тая функцыя застаецца без захавання.
  • Дзе ён не працуе

    Зазвычай ён працуе, і самэ гэта яшчэ адной прычынай, чаму ён ўсталяны за замовчанням. Ён стварае проблемы у двух ситуаціях. Першая — калі адна функцыя становіцца вельмі большай: папка checkout/ з 80 файламі ёсць проста структурой на адны ранг нижэй, заснованай на типах. Другая — калі з’яўляецца рэальная модель домэна, якая не паспаўляе з функцыйямі інтэрфейсу. Гэтыя два факторы прыводзяць да стварэння наступных трох структураў.

    Atomic Design

    Што ён такое

    Atomic Design — это методалгія Брэда Фроста, представленая ў блог-пастаце з чэрвеня 2013 года і розглянутая болей дакладна ў кнізе 2016 года. Яна включае пяць рангаў. Пераказваючы його вялікання:

    • Атамы — гэта базовыя элементы, з якіх складаецца кожны інтерфейс.
    • Малекулы — гэта дасцяга простых груп элементаў UI, якіе працуюць разам як адна ейка.
    • Організмы — гэта болей складныя компоненты, створаныя з малекул, атамоў і нават іншых організмаў.
    • Шаблоны — гэта структуры на рэвэлі сторанкі, якія размешчаюць компоненты ў паветранстве і апісваюць структуру вялікага кантэнта.
    • Сторанкі — гэта конкретныя прыклады шаблонаў, заполненыя рэальным, адпраўданым кантэнтом.

    Даклад, які практычна всі ігнаруюць, — гэта сама апісанне Фроста пра мету яго падходу. Ён представляе Atomic Design як ментальную модель, а не лінейны процес: спосаб перакладзець інтерфейс як цэлісна структура і ў той жытак як сукупнасць частак. Гэта ніколі не была структура папак; спяльнота пазней прыўязала папкі да яе.

    Хто яго выкарыстоўвае

    Хутчэй рэальнасць тут не адпавядае репутацыі. Існуе мало падтверджальных дапамог, якія бы паказалі, што ведучыя системы дизайна на базе React выкарыстоўваюць буквальную таксанамію папак atoms/, molecules/, organisms/. Напрыклад, Shopify Polaris і GitHub Primer не выкарыстоўваюць такое называнне, па-вялікаму несупрацоўваючы з рэзультатамі пошуку, якія можаць гэта падтрымваць. Яскравы прыклад, які можна падтвердзіць, — это Pattern Lab, сабеўны інструмент Frost, створаны для дэманстраціі гэтага падходу.

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

    Адрозніцы

    • Ён дае дизайнерам і інжынерам спакойны язык. Гэта справжняя перадача, і папкі тут не выказваюць ніявагі. Якщо дизайнер апілюецца да певнага элемента, інжынер адразу разумее яго майбутнія межы, што ў значным ступені корыстна для команд, якія працуют над системамі дизайна.
    • Ён спрыяе структураванню. Іерархія прабуджае бажанне ствараць маленькія елементы і ўжо пасля яных их складаць, што є хорашай практыкай у React незалежна ад таго, дзе знаходзяцца файлы.
    • Ён адкрывае ваш асортымент прымітіў. Папка atoms/ чытна паказвае, калі у вас є тры варыянты кнопкі, якія насправдзе павінны быць адной.

    Слабасці

    • Класыфікацыя ў дзеянні є сложным завданням, і сам создатэль гэта прызнае. Modal.jsx аб’еднвае фон, контейнер, заголовак і элемент для закрыцьця. Чы ўсё гэта група атомаў, тады молекула, чы ж складны самастоятельны элемент, тады арганізм? Фрост у канцэ настаўіў прыблізны правіл: якщо разбіўшы компонент можна атрымаць базовыя элементы, такія як зображэння, заголовкі, параграфы і кнопкі, то гэта молекула; якщо ж атрымліваюцца меншыя компоненты, такія як карточкі, спісы для аднароджэння чы об’екты медыа, то гэта арганізм. Такія хюрістыкі існуюць толькі таму, што межа ў гэтым аспекте є неясной, і кожная неясная межа становіць прычыну паўтараючыхся дыскусый, якія не прыносяць жаднай цэні для корыстувальніка.
  • Ён класіфікуе толькі UI-элементы, таму не можа структураваць аплікацыю. Гэта ўзгубны недаклад. Atomic Design мае практычныя рэкамендацыі ўжо ў чыненні Button і CheckoutForm, але ўсёўсюды не мае нічога пра useCheckout, checkoutApi, cartStore чы formatPrice. Палова файлаў не падпадае під гэтую таксанамію, таму команды вынужданыя викорыстоўваць атомы, молекулы і організмы для ўсьго, а таксама типавую структуру для рэшты элементаў, што прыносіць два комплексы проблем.
  • Ён адкрыта суперачыць прынцыпу кольокацыі. Усё, што стосуецца процэса платежа, назаўседы розпадзяецца між папкамі organisms/, templates/, pages/, hooks/ і api/.
  • Компаненты павяршаюць, таму файлы перашыруюцца. Молекула адрастае нэшта, становіцца організамом, пераходзіць у іншую папку і разбивае всі імпорты. Таксанамія залежыць ад складнасці, а складнасць зменшваецца.
  • Сама дакументацыя React паветарала пра тое, каб не спрыяваць ёй як строгам правілу, а радыя як кориснам прыкладу.
  • Дзе гэта не працуе

    Як толькі гэта паказваецца за межамі системы дизайна. Распаковка прымітываў па складнасці ў packages/ui/ або shared/ui/ ёсць разумным рашэнням. Але калі гэта застосавляецца да всей аплікацыі, гэта адразу ж зламваецца, адтуды што большая частка будзь-яй аплікацыі складаецца з элементаў, якія не ўзьмісцююцца ў склад компанентаў UI.

    Сама позіцыя Frostа падтрымлеўна гэтаму тлумачэнню: ён называе гэта псіхічным моделюванням, а не догмай, і прасіць команды перэназываць стадіі. Команды, якія прыменяюць строгія правіла ўзгалду з атомамі і молекуламі в React-проектах, ўжываюць больш жорсткія падходы, чым сама людзь, якая створыла гэты метод.

    Структура, адмованая ад домэны

    Што гэта такое

    Domain-Driven Design выйшаў у кнізе Эріка Еванса 2003 года, напісанай болей чым за дзесяць гадоў да стварэння React, і ён являе сабою падход да моделювання складных бізнес-домэн у коде. Два з яго ідэяў пераносяцца на фронтэнд. Бяжычны контэкст — це частка програмнага забезпечэння, у якой певныя тэрміны, вызначэння і правіла застосоўваюцца адносова стабільна. Прынцып універсальнага языка гласі, што код павінен вжываць той самы слоўнік, што і бізнес.

    У прыменэнні да React-проекта кожная домэна становіць верхній папак, якая внутршняя чынюцца шарамі:

    • domain/ абсарбуе экзэнты і об’екты-значэнні: чыстыя бізнес-правілы.
    • application/ абсарбуе кейсы выкарыстання.
    • infrastructure/ абсарбуе кліенты API і сховышча.
    • presentation/ абсарбуе компаненты React.

    Залежнасці наводзяцца толькі ўнутрь, таму домэн нічога не ведае пра React чы ў HTTP.

    Пазірце, што адбываецца з неканэйчнымі файламі. formatPrice больш не ёсць дапаможнім функцыям; ён ператвараецца на об’ект-значэнне Money, які знаходзіцца ў catalog/domain/. useAuth скарацваецца да простага обгортку на роўні прэзентацыі над кейсам выкарыстання loginUser. React цаленаправлена адкладаецца на края.

    Хто яго выкарыстоўвае

    Самым надзеяным практычным даведнікам ёсць кантэнт Алекса Беспоясава “Clean Architecture on Frontend”, які мае полную рэалізацыю на React і TypeScript у репазітарые bespoyasov/frontend-clean-architecture. Яго адказ пра стратыфікацыю такі: домэн — это тая частка, якая застаецца адной і той жа незалежна ад таго, чы робіце пераход з React на Angular чы мяніце конкрэтны кейс выкарыстання.

    Таксама варта знати, што Манфред Стейер, можа, найвядомыш чалавек, які падтрымвае прыемы DDD на фронтэндзе, пераважна працуе з Angular. Модель Angular на адваротах класоў, оріентаваная на службы, з інтэнсіўным вводам залежнасцей, яе лепша падходзіць для DDD чым функцыі і хукі у React. Перш чым апраўдваць які-небудзь моцны керавання прыемамі DDD на фронтэндзе, пераканайцеся, для каго саме фрэймворку ён быў напісаны.

    Гэты стыль выкорыстоўваецца ў сферах фінтэху, страхавання, охоры здароў’я, логістыкі і корпоратывнага ПО типу B2B, дзе бізнес-правілы є складнымі і існавалі задоўга яшчэ до появы інтэрфейсу.

    Адрозныя моменты

    • Бізнес-логіка перазіходзіць за межы фрэймворку. Энтытет Cart з правіламі addItem — это просты TypeScript; замена React не паўтараеся на роўні домэн-шару. Для продукту, які плануецца викорыстоўваць дзесяткі гадоў, гэта є важлівым актываў.
    • Правілы можна тэставаць без React. Не трэба нічога атрыбутаваць, няма хуків і бібліятэк для тэставання — толькі функцыі і асерцыі, якіе выконваюцца за каліксекунды. Пры складных правілах гэта сама по сабе можа быць праблемай для ўтверджэння такой структуры.
    • Код відпавае бізнес-кансэрвацыям. Калі эксперт у данай сфере кажа, што замовленне не можа быць адправленае пакуль не будзе пераканана ўказаная адреса, гэта правілы мае толькі адну локацыю — файл пад назвай Order.ts.
  • Аб’якаваныя контэксты падходзяць для большых арганізацый, ўжо таму што кожны контэкст можа належаць да аднай команды з чыткым інтерфейсам да іншых.
  • Слабасці

    • Колькасць неабяжных элементаў вельмі велика, і гэта ёсць галоўны расход. Кожная ентычнасць зазвычай включае модель домэну, DTO і прыемнік межы між ямі: тры файлы і шар перакладу для таго, калі прыкладнэць на адной заснованай на функціях логіцы выдае адпаведны адпаведнюючыся API-адказ.
  • Большасць дапраў на React не маюць справжнего домэна. Хоць гэта ўзгляд, а не падтверджаны факт, гэта ўсё ж ключовая мысль гэтага раздзелу. Тыпавая дапраўа на React атрыбутуе данні з API, якое належыць іншай камандзе або службе, і ўсё яе справжняе складнасць крыўціцца ў стане сервера, кэшаванні, оптымістычных апдэтах і супернагонках. DDD не рашае ніякога з гэтых прыемоў; бібліятэка для керування станам сервера, такая як React Query, лепей рашае фактычную проблему, чым шар домэна. Якщо вашы ентытаты — это типаваныя адпаведзі API без інварыянтных правілаў, такая архітэктура коштае грошы і нічога не захоўвае.
  • Фронтэнд на самай працо не можа аб’яднацца з сваёй фрэймворк-сістэмай. Обяцанне — незалежнасць ад фрэймворка, але фронтэнд завжоды прыўязаны да модэлю атрыбутавання, механізмаў маршрутацыі, патэранаў калектывнага керавання, API прыгледачоў і інструментаў для стварэння коду. Чыстая архітектура пераносіць гэтыя обмежэння на ўзлётныя моменты, а не усувае іх. Гэта справжняя перадчыннасць, проста меншая, чым праглашаюць.
  • Контэксты UI є нечыяры. У бэкэндзе власнасць дадзенняў даёт чыстыя межы. Фронтэнд паказвае тое, што трэба экрану, і адна стораніца часта павярнутая трохі контэкстам, таму межы становяцца суб’ектывнымі і зменнымі.
  • Інтеграцыя трэбуе часу. Разработчык на React, які ніколі не сталкаваўся з DDD, можа патрабаваць недзеў, каб стаць продуктывым, і завжды хтось будзе спытацца, чаму існуе мапер.
  • Дзе ён не працуе

    Калі домэн існуе толькі на паперы. DDD створаны, каб дапамогчы справіцца з рэальной складнасцю бізнесу. Якщо вашы інварыянты ўсамітнены, такія як грошы, контракты, регулююцьяяя працэўныя процесы або багаташаговые машыны станаў, кераваныя правіламі, інвестыцыя вяртаеся. Калі задача заключаецца у прадстаўленні спісу продуктав з канцэнтра, вы купілі вельмі большую колькасць формальнасцяў, каб абгорнуць fetch.

    Корыстны тэст: чы можаце вы пераказаць тры бізнес-правілы, якія будуць цікавейшыя за пераконтроўванне обов’язковых поль? Якщо не можаце, тады у вас ёсць толькі UI, а не домэн.

    Дизайн з функцыямі, роздзеленымі на часткі

    Што гэта такое

    Дизайн з функцыямі, роздзеленымі на часткі (FSD) — ўсё, што тут ёсць у форме формальнай спэцыфікацыі, з версіямі выданняў, дакументацыяй і офіцыйным інструментам для пераконтроўвання архітектуры пад назвай steiger. Іншыя методы ўособліваюцься толькі як звычаі; FSD зафіксаваны пісьмова.

    У яго ёсць тры глэбіні іерархіі:

    • Слойяў — это фіксаваныя верхнія папкі: app, pages, widgets, features, entities і shared.
    • Складанкі — это групы ў межах слойя, раздзеленыя па бізнес-значэнні, тыя самыя, якія код мае для продукту чыстаў прылады.
    • Сегменты — это групы ў межах складанкі, раздзеленыя па тэхнічным назначэнні: ui, api, model, lib і config.

    Правілам, якое ўтримвае ўсё разам, яе є тое, што модуль у складанцы можа імпортуваць іншыя складанкі толькі тады, калі яны знаходзяцца ў слойях, якія знаходзяцца строго нижэй за ўласны. Імпорты завжды направлены вярху, а два складанкі, якія дзеляць слой, ніколі не можу імпортуваць адна другую. Братскія элементы маюць нульовую взаемную прыяжнёсць, што контролюецца інструментам для перагляду коду, а не добрымі намерамі.

    Есць два важлівыя пасправкі да тых тэзаў, якія циркулююць ў іншых джэрелах, якія варта знаць:

    • Слой processes ўжо не выкарыстоўваецца. У дасяглібнай інструкцыі зазначаецца, што чынныя стандарты рэкамендуюць утримацца ад яго і пераказаць ўсё, што ён містіць, у слоях features і app. Інструкцыі, якія ўсё ўжо перыядуць сема слоў, укладаючы ў іх processes, описваюць старэйшую версію.
    • Слой pages не быў зняты з выкарыстоўвання; ён быў падняты у прыоритет. У версіі 2.1, выданай у лістападзе 2024 года, як загалоўка выказана фраза "Старонкі — першыя!" Тепер рэкамендуецца размешчаць якомога больш коду ўнутрь старонак: вялікія блокі інтэрфейсу, формы та логіка обработкі дадзеных, якія не викорыстоўваюцца іншымі старонкамі, павінны застацца ў самай той старонцы.

    У версіі FSD пры викорыстоўванні базовага дапаможнага праграмы CheckoutForm.tsx знаходзіцца ў падкаталозе pages/checkout/ui/, а не ў окремай частцы функцыйнасці. Падход v2.0 за прынцыпам вымагаў разбівання яго на ентыты і функцыйны элементы, тады калі v2.1 залишае яго ў межах старонкі, пакуль іншая старонка насправды не запатрабавае часткі з яго.

    Мотывацыя для такой змены ёсць самай цікавай часткаю. Разбівання на ентыты, прыменяванае ў v2.0, стварала слабую кохезію: для аналізу аднаго траекторыя выконання задачі патрэбна была праходка чераз многія каталогі, а знаходжэнне непрацюючага коду было складным. Адпаведальнія за развіцце праграмы фактычна з’яўіліся, што пачатковая версія вымагала занадта многіх архітэктурных рашэнняў пры напісанні коду. Такім чынам, найсерьознейшая крытыка FSD была выказана і рашыта самімі яго автарамі. Заслугі за выкананне парадаксу належаць ім, але команды, якія вжывалі v2.0, заплатілі за гэты урок.

    Хто яго вжывае

    Ситуацыя з адопцыёй гэтага тэхналагіяў трэбуе адкрытага аналізу. На момент напісання на галоўнай стороне FSD ёсць раздзіл для компаній, якія выкарыстоўваюць FSD, дзе не наводзіцца жадных конкрэтных прыкладаў, а замест таго відвідухоў прасягаюць паведаміць пра свою компанію.

    На офіцыяльной стороне з прыкладамі пераказана апошней 21 проект, большасцю дэмы і прыладкі для хобі, такія як клон RealWorld, гра Sudoku, фальшывы інтернет-магазін і невялікая гра для браузера. Проекты, якія выглядаюць як прыладкі для практычнага выкарыстоўвання, ёсць некалькі: Roke.to, Moke Smoke, Moonlogs і адданне для Chrome.

    Па стану на момент напісання, показнікі адопцыі ўмерзлівыя, але рэальныя: апошней 297 репазітарыў на GitHub выкарыстоўваюць тэму feature-sliced-design, репазітарый з дасягненнямі мае апошней 2,3 тысячы зірак, а інструмент для перагляду коду — апошней 388. Спільнатэка сфокусавана ў рускагаворачым свеце разработчыкаў, што робіць адпрацоўкі гэтага тэхналагіяў на англійскай мове выглядзячымі менш распространенымі, чым яны на самай працэ.

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

    Прыямнікі

    • Гэта паканчыця дыскусій пра месца размешчэння, калі ўжо єсць вялікі спефікацыя. Куда падае гэты файл? Спефікацыя дае адказ. У вялікай камандзе гэта заўсёды эконаміць час, і самэ гэтае ўмоўлівае на выбор FSD проты падходу, базаванага на фічарах, дзе вакуум вялікай колькасці разоў пераадрасаваецца.
    • Грані перакантролююцься машынамі. steiger і настройкі ESLint адпаведна выкарыстоўваюць правіла імпорту, і архітектура, якая контролюецца, развиваецца набагато спакойней, чым тая, якая не контролюецца.
    • Гэты падход паслужыць для вялікіх каманд з мінімальным коордынацыям. Фіксаваныя шары і відсутнасць імпорту межаў дазволяюць камандам працаваць паралельна без суперскуплення.
  • Як толькі правільна супарацыя энтытаў і фічаў становіцца зрозумелай, гэта даскладзе чытлаўцу. product — гэта тое, што існуе; add-to-cart — гэта тое, што робіць корыстнік. Це разныя виды коду, а большасць лейаутаў іх змешвае.
  • Слабасці

    • Крывая навучэння ўздымаецца стрэлкам, і сама стораніца з мотывацыяй FSD прызнае гэтую загальную проблему, зазначаючы, што існуючыя падходы маюць высокі порог входу, які ускладнюе найм. FSD не ўжо адстае: шары, секторы і фрагменты — гэта тры таксанаміі, якія трэба выучыць, прычым ужо пасля чаго можна размістіць адзін файл.
    • Пераход на версію v2.1 сигналізуе пра змены. Прыглавныя елементы разбівкі зменіліся, і кожны, хто працуе за спефікацыямі, должен следаваць за ўсіма змінамі.
    • Сама дакументацыя называе гэты падход занадто сложным для маленькіх проектаў, зазначаючы, што ён непатрэбны для короткакалендарных проектаў або калі швальць важнейшы за якасць коду.
    • Дапамога доказоў адмацыявання ёсць скромная. Гэта прыемна для персональных проектаў, але ўскладнюе прымусовую рэалізацыю, калі заінтэресаваная сторона спытае, хто ўсё ж такі керуе ім у рэальных умовах.
    • Міграцыя старых кодавых базаў ёсць дорогай. Адкорэгаванне існуючага коду ёсць масштабным проектам, які дае малая візуальна аддача.

    Дзе ён не працуе

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

    Модульная структура і монорепозітарыі

    Што гэта такое

    У працоўніку не йдзе, як у іншых, пра аранжаванне папакі src/, таму ён розглядаецца апошнім. Цэў — структура репазітарыя: калькі прыкладнікаў і спакетаў, якія дзелююцца між сабою, знаходзяцца ў аднам репазітарыі, пры чым іх координуе виконвальны механізм.

    У дасягледах Turborepo описваецца стандартная форма: спачатку размешчаюць прыкладнікі і службы ў папцы apps/, а всё іншае, такое як бібліятэкі та інструменты, — у папцы packages/. Адзін раз прачытайце кансультатыв Turborepo па тэме структурування репазітарыя.

    Кожны прыкладнік у папцы apps/ заўсёды трэбуе ў сабе аднай з шасці іншых внутрашняях структураў. Манорепазітарый не залежыць ад спосабу аранжавання адзінаго прыкладніка, і плутанне эўх двух ёсць найпашыльнейшым непрацоўкам у гэтый тэме.

    У момент напісання главнымі інструментамі былі turbo (2.10.x, прыблізна 73 мільйоны ўсёх завантажэнняў на месцы), nx (23.x, прыблізна 38 мільйонаў) і lerna (9.x, прыблізна 7,5 мільйонаў). Перад тым, як паслужыцца імі, пераканайцеся ў актуальных цифрах. У працоўнасуперакладзе з распространёнага мнення, Lerna не ўстарэў. У 2022 году Nx перыябрав на сябе ўправлінне яго розвиткам, калі існаваў рызык таго, што ён перастане падтрымваліцца. Ён продовжае выдаваць новыя версіі, а тепер перадае задачы запуску і кэшавання Nx, фармальна концентруючыся на версіяванні і публікацыі.

    Хто яго выкорыстоўвае

    У дыскусіях пра манорепоў часта згадваюць Google, Meta і Microsoft, што є вводзячым у глухае. это манорепоў на рэвэліцыі компаній, а не манорепоў для React, і гэта нічога не сказвае пра вашу аплікацыю на React.

    Цыфры застаюць цікавымі. У рэпазітарыі Google, за данымі, было прыблізна адны мільярд файлаў і 86 ТБ (Potvin і Levenberg, Communications of the ACM, ліпень 2016 г.). Meta пазначае, што ў яе рэпазітарыі, керованам Sapling, є дзесяткі мільйонаў файлаў, змян і галоўак. Па словам Браяна Гарі з мая 2017 г., рэпазітарый Windows у Microsoft мятаў прыблізна 3,5 мільйонаў файлаў загальнай вазой 300 ГБ, над якімі працавалі адпраўна 4 000 інжынераў.

    Кожная з эйных компаній была вынушана стварыць сабе спецыяльныі інструментарыя, каб справіцца з гэтым: Google створыў Piper і Bazel, Meta разрабатала Sapling і EdenFS, а Microsoft напісала GVFS. Це можна спрыяжыць з сигналам пра высокія витраты, а не з падтрымкай такога падходу. Якщо манорэпазітарыю для нормальнай роботы патрэбна спецыяльная команда інфраструктуры, гэта ў чымсь свідчыць пра проблемы манорэпазітарыяў.

    Адпаведныя, пераканальныя прыклады з React адрозневае:

    • Рэпазітарый Vercel з проектам next.js ўособліва являе сабою манорэпа для React, у якім выдзелены верхнія рэпазітарыя apps/ і packages/, а таксама прызначаны паверкспэсысы pnpm; у яму знаходзіцца 19 пакетаў, сярод яых next, create-next-app і eslint-config-next.
    • Shopify зберагае своія прыкладнення на React Native ў адной манорэпе, якая павіннаяся на Shop, Inbox, Point of Sale, Shopify Mobile і Local Delivery. Їхній інжынерны калектыў у верасне 2021 года поясніў, што адна манорэпа зменшыць витраты на тыямо, адколі трэба прабаваць і оптымізаваць толькі адны процес, у працоўнасці з багатым коллекшанам окремых пакетаў і рэпазітарыяў.

    Гэта ёсць рэальныя прычыны для викорыстоўвання манорэпы, і трэба памятаць, што гэта стосуецца процеса тыямо, а не організацыі коду.

    Адрознікі

    • Змены ў розных пакетах атамарныя. Змены ў packages/ui/Button і ўсіх трох прыёмных дапрацоўках выканаюцца ў аднам коміте, адной просьбе пра падключэнне, адной пераглядзе і аднай запускі CI. У разе окремых рэпазітарыёў гэта прыводзіць да падняцья версіі, публікацыі і трох апдэйтаў залежнасцяў. Саме таму і існуюць манорэпазітарыёў.
    • Аднародная робота асаблівая. packages/ui мае свой сабскрыпты package.json і чыста адзначаную публічную API, пры тым межа пакета — гэта найжорсткішы спосаб працы з пакетамі ў JavaScript.
    • Існуе адна версія ўсьго: жадная дапрацоўка не застрягае на React 18, калі іншая працюе на версіі 19, є адны файл забарыкадавання і адна ентычная справачная база.
    • Вялікія рефакторы стаюць можлівымі. Можна перайменаваць API ў всіх прыёмных дапрацоўках у аднам коміте, пры чым кампайляр пераканаецца ў рэзультатах.

    Слабасці

    • Інструменты ўсёлякага роду являюцься справжнім і постаўным тэксам: прасторы роботы, графі завад, аддаленая кэшаванне і матрыцы CI. Самыя дасведчэнні Turborepo таксама адзначаюць проблему масштабавання, адколі кожны прастор роботы мае свои задачы на тэставанне, перагляд коду і складанне, і адна монорепа можа запрацаваць з тыячамі такіх задач. Turborepo створаны для рашэння проблем, якія ствараюць монорепы.
    • Процес CI стае повольней і дорожэ, прычаму ён не стае быстрей. Без належна настаўленага адказвання на змяны і кэшавання, кожны pull request запускае ўсе задачі.
    • Інтеграцыя новых спецыялістаў ёсць сложней. Перш чым здзеўсці першы commit, новы працавальнік должен выучыць, як функцыонуюць прасторы роботы, як работае граф завад і як практыкуецца кэшаванне.
  • Спяшаныя пакеты ствараюць зв’язкі, які маскуюцца пад можлівае пераўтворэнне. Калі пакет packages/ui становіць сабою об’ект для трох прыемнікаў, кожныя змены рызыкуюць спрычыніць проблемы ў усіх трох дапрацоўках. Команды часта рэагуюць пададзеннем дапаможных параметраў і варіянтав, пакуль спяшаны компонент не стане мовай налаштавання, якую ніхто не розумее.
  • Дзе цэль не дасягаецца

    Калі існуе толькі адна дапрацоўка. Монорепозітарый, у яком каталог apps/ містыць адну-едзиную дапрацоўку, плаціць высокія косты апаратнага забезпечэння без жадных выгод: няма коду, які можна было б раздзеліць, і няма можлівасці атомарных змэн у розных дапрацоўках.

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

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

    React Server Components не наказуюць пра формат папак

    Багатыя няўзбліжныя стацыяны творчы, што компаненты React Server Components зменяюць спосаб структуравання папак, зазвычай рэкамендуючы адзінокія каталогі components/server/ і components/client/. Нічога ў афіцыйной дакументацыі не падтрымляе гэта.

    Дыректыва use client пазначае межу ў графіку модуляў, а не ў дрэва папак. Адпаведны нарадчык пра рэндарыванне Next.js апісвае use client як заяву пра межу між графікамі модуляў сервера і кліента, і пояснюе, што як толькі файл мае гэтую дыректыву, яго імпорты і компаненты, якія ён безпасцерожна рэндаруе, всі потрапляюць у пакет кліента.

    Гэты другі момант ёсць ключовым. Межа распространяецца через імпорты, а не папкі. Файл у каталозе client/ не ўважаецца компонентам кліента чераз свою локалізацію, а файл у каталозе server/ не отрымае жаднага захавання заводзка гэтым назвам. Тое, што вялічынае рэштунак, — это дыректыва плюс ланцуг імпортаў.

    Якщо вы хочаце забезпечыць супярэчнасць, то інструментамі ёсцю пакеты npm server-only і client-only, якія спрычыняюць паўстанне процесу будавання, калі код перакрочыць неправильную межу. Папкі гэтага не даюць.

    Афіцыйныя рэкамендацыі на самай працоўцы спрыяюць працупаку: перасунуць 'use client' ніжэй у іерархію, да листоўых компонентаў, каб заставіць пакет кліента маленькім. Раздзелэнне на верхнім роўні на папкі сервера і кліента спрыяе працупаку працупаку.

    Некалькі стандартаў App Router дзейсна вплываюць на арганізацыю, і яны рэальныя:

    • Групы маршрутаў, пісаныя як (folder), арганізуюць маршруты без змены URL.
    • Прыватныя папкі, пісаныя як _folder, зовсамна не ўключаюцца у систему маршрутаў.
    • Колакейшн є безпечныя за замовчанням, тым што маршрут стае доступным для загальнага відвідування толькі пасля дадавання файла page.js або route.js. Компаненты, тэсты і інструменты можаць знаходзіцца безпасулькі ў сегментах маршрута, не стаючы самымі маршрутамі, таму прыватныя папкі для гэтага не трэбуюцься.

    Next.js чыста зазначае, што не мае прагненняў ў спосабе арганізацыі і розмешчэння файлаў проекту. Яго дасягальнік праказвае тры стратэгіі арганізацыі без ўпорядкування іх па прыоритэтах.

    Як выбраць

    Ёсць складзены варыянт рашэння, з найважлівейшыми аргументамі:

    • Менейш чым апоўну 30 файлаў, або вы яшчэ доследжваеце проблему: застаўцеся з простай структурой. Структура, адаследжаная на падставе рэальных законамаў змян, лепшая за тую, якая спадабліваецца з першага дня, як і радзілі дакументы React.
    • Менейш чым апоўну 50 файлаў, маленькія команды і короткая трымкі: типовая структура падходзіць. Яна не ў модзе, але гэта не мае значэння; перайшоха ў іншую структуру будзе карыснае больш, чым можна заўсёды заадно зберагчы.
    • Якшто праект рэальны і мае дугі трымкі: выберыце структуру, адаследжаную па функцыях. Гэта должна быць стандартам. Яна задовольняе прынцып Screaming Architecture, спрыяе калекцыі функцый разам, робіць выдаленне функцый простым і падтрымлівае правіла, наведзеныя пры викорыстоўванні лінт-інструментаў. Пачніце з адэнаццаў Bulletproof React, рана дадзіце зоны import/no-restricted-paths і адмовіцеся ад файлаў у формате barrel.
  • Большая кампанія, продукт з давньай історыёю, а таксама постаянныя спарчкі пра тое, што ляжыць у базу функцыйнасці: пагляньце на FSD. Вы купуеце спефікацыю, якая вже прыняла рашэнні, і инструмент для ўпэўнення ў ўжыцці гэтых рашэнняў, пры чым цена складаецца з мінімальных доказоў апрыемлівасці та вялікаг колькасці концэптаў.
  • Прыгожа складныя бізнес-правілы, якія перастаюць быць актуальнымі пасля змянай інтерфейсу: дадзіце шар домэна, але не цэлы комплект DDD. Пераместіце правілы ў звычныя ентыты на TypeScript, якія ніколі не імпортуюць React, а ўсё інша залишыце на базе функцыйнасці. Так можна атрымаць большую частку цяніны за значна меньшыя зусиллі.
  • Система дизайна з рэальнымі корыстнікамі: выкарыстоўвайце Atomic Design толькі як частку гэтага пакета, як слоўнік. Не включайце яго ў загальную структуру прыкладнення.
  • Калькі легітныя прыемкі, які выкарыстоўваюць легітны код: наладзіце манорепа з падкатэгорыямі apps/ і packages/, які керуецца Turborepo або Nx, і дазвольце кожнай прыемкі самой выбраць свою внутраню структуру з гэтага спісу.
  • Є адна правіла, якая мае прыоритет над усімі іншымі: гэтыя падходы можна сумаваць. Рэальныя кодбазы ўжо выкарыстоўваюць их саўмешанне, і ў даследных дакументах React таксама гаворыцца пра гэта, зазначаючы, што ў большых проектах у практыцы часта выкарыстоўваецца сумешанне розных падходаў, таму выбір „правильнага“ з іх з самага пачатку не ўсё так важны.

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

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

    Людзі, які знаходзяцца найбліжэй да гэтых стандартоў, прыменяюць іх ляйтасова і постаўляюць ўсё новыя змены публічна. Фрост называе Atomic Design ментальным модэлем, а не дагматам. У дасведчэннях React час прыняцтва рашэння быў обмежаны пяцьма мінутамі, а потым сторонка была выдалена. Next.js і Vite вадзіраюцца ад выражэння паводлів. FSD змяніў свою асновную елементарную единіцу разбівання ў версіі v2.1, а Bulletproof React перакрыў сваю ранейшую рэкамендацыю. Яны змянілі падход, таму што слухалі рэальныя адзывы, а не захопляліся своімі паводламі.

    Гэта залишае два стойкія правіла, якія існуюць ранейш за ўсе лэйауты, прыменяваныя тут:

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

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