Buy tickets for the next conference JavaScript fwdays’24 conference!

Dude, where’s my boilerplate? [ukr]

Talk from the partner Wix.

Talk presentation

After night of partying Oleksii can’t find boilerplate in his project. Was it stolen? Or maybe it’s just someone’s sick joke? Let’s deep dive into this mystery!

Oleksii Makodzeba
Wix
  • Doing stuff in Dev Tools (FE Infra) at Wix.com
  • 10+ years of experience in bad solutions
  • Sometimes I get confused with a security guard
  • I dream of hugging a gorilla

Talk transcription

Доброго дня. Блін, вас дуже багато, і я вже супер нервую. Це мій перший раз. Ну що ж, почнемо. Як ви бачите, назва моєї презентації – "чувачі". Зразу скажу на питання, чому саме "чувачі", де жіночий гендер? Жіноча, коротше, замість "дюд" використовують слово "дюдеса", і воно настільки погане на мій погляд, тому я вирішив не перекладати, тому сорі, буде лише "дюд". Де мій бойлерплейт? Але спочатку давайте трохи про мене. Мене звати Дмитро. 12 років у професійній розробці, з яких 7 плюс років я працюю в WIX, і 2 плюс роки я працюю в команді DevEx.

Що таке DevEx, ми зараз трошки поговоримо, але ще є головна фраза, яку можна використовувати для опису моєї роботи в професійній розробці. Я хочу звільнити якомога більше розробників. Чому? Бо я хочу створити такі інструменти, які можна було б використовувати будь-ким, навіть мавпами, навіть горилами. Ми могли б звільнити розробників, найняти горил, і я б з ними постійно тусувався. Ось сама ультимативна ціль. Ось, про що ми будемо казати, і я вам буду розповідати сьогодні.

У нас є DevEx, бойлерплейт, і, звісно, це мем кому за 30. Мабуть, вже про кальсонних гномів. Я не впевнений, що ви все знаєте, але вирішив його вставити. Чудово. Отже, що таке DevEx? Чесно кажучи, хотів сюди вставити лінку з Вікіпедії, але там щось не знайшов. Погуглив, знайшов якісь статті, але вони були дуже великі, тому вирішив самостійно описати це. Один рядок вийшов таким для мене: "Це набір інструментів і практик, які дозволяють розробникам розуміти, робити роботу розумно, а не важко". Тобто розробник може фокусуватись на бізнес-задачах, а платять нам за бізнес.

Також розумна людина сказала, що можна дати фразу: "Ти перестаєш думати, як будувати, а починаєш думати, що будувати". Ну, я не дуже розумію цю фразу, але вирішив додати її. Іншими словами, припиняєш роздумувати про те, як правильно впровадити певні рішення, і починаєш розглядати, що саме потрібно робити. Підсумок: Незважаючи на всі труднощі, моя команда в DevEx продовжує створювати інструменти, щоб зробити роботу розробників легшею. І я хочу ділитися з вами проектом, який ми розробляємо і який називається "бойлерплейт".

Інструментів збірки дуже багато. Деякі з них дуже низькорівневі. Тобто їх треба конфігурувати. Отже, ми просто скопіюємо конфіг з блокпостів або з док. Лише я впевнений, що немає людини, яка знає — ну, мабуть, є, але я таких не знаю — яка може мені розповісти повністю про все, що можна налаштувати в Webpack конфіг, сидячи, наприклад, за один раз. Тут приклад якихось конфігів, зліва це Webpack конфіг, який я знайшов в блокпості. Справа у нас Rollup. З моєї практики, можу сказати, що тут відбувається, але не дуже чітко. Що з цим можна зробити? Як кажуть, це все для затравки. Тут ми просто можемо це виділити кудись. Як це зроблено у нас? Грубо кажучи, ви просто знаходите, якщо у вас є компанія, і у вас є білдтули, і багато компаній, команд, ви знаходите людей, яким не все одно на це, домовляєтесь, берете цей конфіг, підкидаєте в якийсь проєктик, робите паблішити в NPM, публічний чи приватний, як вам хочеться. Робите депенденцію на нього в ваших проектах. І ось так використовуєте. Супер просто, на мій погляд.

Тому не дуже цікаво. Ось. Ну, плюси і мінуси теж дуже прості. Легко використовувати, легко розширювати, мінуси легко розширювати і забувати про контриб'ютінг. Бо всі розуміють, що ми взяли, потім вийшов оновлений конфіг, через пів року вийшов новий вебпак або якийсь плагін. Треба це виправити. Ви в своєму проєкті виправили. І так далі. О, треба контриб'ютити. Зроблю це завтра, якщо ніколи. Ось. Далі. Runtime. Насправді майже те саме. Ми, як би, в фронтенді робимо схожі речі. Для схожих речей є схожі бібліотеки. Ось, типу, багато якихось бібліотек, які я знайшов, навіть колись використовував. Там те саме. Типу, основна проблема з ним, що якщо у вас велика компанія і ви робите всі щось дуже схоже, скоріш за все вам не потрібні дві бібліотеки, які роблять одне й саме.

Наприклад, React I18 Next і React Intelligent. Або, наприклад, MomentJS versus date-fns. Вони мають свої плюси і мінуси, але, взагалі, вони різні. Але, типу, якщо ви робите майже одне та саме, з великою кількістю деталей, вам не потрібні різні бібліотеки. Більшість часу вам не потрібні різні конфігурації цих бібліотек. Так, навіть tailor-made конфіг не завжди необхіден. Це, типу, ілюзія. Ілюзія того, що ми самі налаштовуємо і контролюємо наші інструменти. Зазвичай, це правда лише перші кілька неділь, доки ми пам'ятаємо, що ми налаштували, потім, з моєї практики, я не завжди пам'ятаю, чому я обрав, наприклад, такий конфіг. Тому... Це означає, що ми також копіюємо його. Тобто, що з цим можна зробити? Те ж саме, що і на попередньому слайді. Це, до речі, просто приклади конфігів. Зліва Axios, справа i18 Next.

До речі, мабуть, я взяв це з WIX-ового репозиторію. Ось. Що з цим робити? Як я говорив. Те ж саме. Можна піти трохи далі і використати так звану Feature Abstraction. Чесно кажучи, я вигадав цю фразу, бо я не знав, як це назвати. Ось. Ну, мені здавалося, що це не погана назва. Що це означає? Концепт такий. Коли ми робимо якусь задачу, вона приходить від бізнесу. І зазвичай 99% бізнесу не каже нам: "Я хочу, щоб ви використовували цю бібліотеку". Навпаки, він говорить, наприклад, якщо йдеться про інтернаціоналізацію, то бізнес скаже: "Я хочу, щоб там класно змінювалася мова". Вибір бібліотеки — це вже наша задача. І якщо у вас дуже багато різних частин коду, пов'язаних саме з цим, ви можете трохи обрамити їх абстракціями.

І замість того, щоб ділити це з іншими, наприклад, конфіг для i18next, ділити щось більш абстрактне, наприклад, трансляції. Або, якщо у вас, скажімо, складна система моніторингу помилок, замість того, щоб ділити щось пов'язане з Sentry чи іншими бібліотеками з великою кількістю конфігурацій, ви це обгортаєте в якусь таку фічу з назвою, наприклад, error-монітор. Ось. І тут є ще одне питання: якщо ми накопичили цей пул таких common фічей в межах однієї компанії, то що робити з цим? Чи краще незалежно включати їх в окремі пакети? Чи можливо створити один великий пакет з усіма фічами, і він автоматично включатиме їх усі? Ну, досить швидко. Перше, це процеси. Теж тривіально, на мій погляд, ці речі.

Якщо ми говоримо про fichi-per-package, тобто незалежно все, то у нас легко використовується, і ми фокусуємося на бізнес-розвитку. Основна проблема, на мій погляд, полягає в тому, що люди часто забувають про концепцію того, що створюючи фічу на основі абстракції, ми створюємо нову domain-specific language (DSL). Це означає, що ми створюємо певні знання, яке існує лише в межах нашої компанії. Якщо в WIX, наприклад, є фіча під назвою "error-моніторинг", і нова людина приходить і каже: "Дивіться, error-моніторинг, я йду в Google, а там немає error-моніторингу". Вона може сказати: "Як так? Адже error-моніторинг це наше, і ми повинні про це пам'ятати".

Це не означає, що нічого з цим не можна зробити, але це просто актуальні доки, процеси онбордингу, щоб людина знала про всі ці речі. Але важливо пам'ятати, що це існує. Далі, якщо ми, скажімо, ми це все обгортаємо в один пакет. Великий, з одним бандлом, який вам все віддає. Ті самі плюси, і, зрозуміло, є додатковий плюс, що дуже легко впроваджувати нові фічі, оскільки людина просто оновлює версію, отримує нові фічі. Тривіально, як я вже казав. Це не наступний крок, це, власне, фокус. Тут було, як ми це робили в WIX. Але я пропоную вам запитати нас на нашому стенді, оскільки я бачив, що наші колеги стояли і нічого не робили.

Отже, я пропоную питати, як ми робимо цю річ із фічами. Бо в нас досить велика і, можна сказати, складна система для всього цього, ось так от, обгортання цих common фіч. І, на мій погляд, це цікава штука. Але, але. Тут починається, на мій погляд, найцікавіше. В будь-який момент вас може відвідати новий CTO чи архітектор і сказати, що ми інтегруємося з якоюсь платформою. Що це означає? Зазвичай, це, наприклад, handshake і конфігурація в рантаймі. Можливо, вам доведеться змінити форму вашого основного бандлу. Наприклад, основної точки входу. Або навіть ви можете запропонувати, що тепер, замість одного бандлу, який ви створювали для ваших додатки, тепер слід створювати кілька.

За певною ідеєю чи архітектурним рішенням. Тут я пропоную вам розглянути приклад на реальній основі, що якраз хочу вам показати. Отже, що ми інтегруємо. Уявіть собі, що у вас є компанія з 50 команд, кожна з яких розробляє свой власну додаток. І всі ці додатки десь спільно взаємодіють. Система досить проста. Ви надаєте один бандл, який потім використовується. Ваша річ рендериться десь на React і використовується на всіх додатках. Приходить новий CTO чи архітектор і говорить: "Це все добре, але мені не подобається. Давайте зараз подивимося на цей слайд. Кожний ваш додаток буде складатися з незалежних віджетів, тобто незалежних частин. І кожен віджет буде складатися з двох частин. По-перше, це React-компонент, простий, без дата-фетчінгу, без складної логіки. Цей компонент буде рендеритися, скажімо, в основному вікні, і він буде мати контролер. Це, так би мовити, якийсь код, який буде відповідати за те, щоб тягнути дату. Дань якісь, так би мовити, трансформації з нею. І ця штука буде впроваджена, якраз, у Worker.

Отже, архітектор, а точніше, CTO, представляє це вам. Ви такі класні. У вас 50 людей. Що це означає? Що, ймовірно, буде 50 різних рішень. Вони будуть усі різні. Але чи є в цьому сенс? Зовсім немає сенсу. Усі ці 50 рішень не мають ніякого сенсу. Бо, фактично, потрібно лише одне, яке всі можуть використовувати. Так як вас, як розробників, які фокусуються на бізнес-логіці. Ну, чому вам потрібно робити все це? Ну, насправді. Тому що це новий архітектура. Це так. Але навіщо? І що ми будемо з цим робити? Що ми будемо робити, щоб вибрати одне рішення із цих 50? Почнемо з такої річи, як фраза, ідея, конвенція замість конфігурації. Дуже класний абзац з Вікіпедії. Скопіював, вставив, мені подобається.

В принципі, я так бачу для себе. У вас є певна роль, певна конвенція. І вона встановлює рамки, які допомагають іншим інструментам зрозуміти, що ви робите з проектом і як його використовувати. Фактично, це один із основних фреймворків. Тож ми будемо використовувати цей підхід. Я пропоную, як один з учасників з 50 команд. Отже, у нас є ці віджети, і кожен з них складається з React частини і цієї частини Worker. Давайте домовимося, що весь код буде у нас. Тобто, буде папка Components, зафіксована. І в ній можуть бути лише папки, які відносяться до наших віджетів. Тобто, якщо ми плануємо мати 5 віджетів, тут буде 5 папок. Вони будуть називатися так, як ми хочемо, щоб їх називали у внутрішніх системах – наші типи віджетів. Отже, і в кожній з цих типових папок має бути як мінімум 2 файли. Перший файл – це React TSX, другий файл – Worker TS. Ось приклад. Так би мовити, я хочу, щоб в кожному з них був один дефолтний експорт. А в React TSX дефолтний експорт – це, фактично, буде просто цей наш кореневий компонент. А в Worker – це буде ось ця коренева функція, яку, фактично, наша платформа буде запускати.

І дозвольте також вставити якусь аплікацію JSON, файли з метаданими на майбутнє. Ось. Що можна з цим робити далі? Далі у нас є такі... Люди, виглядає трошки неорганізовано через мій код. Що можна з цим зробити? Можна написати дуже простий інструмент. Ось у нас є коренева функція. У нас є конвенції, як я вже говорив. Правила. Ми маємо, так би мовити, весь код у папці src. І нам важлива папка Components. Тому ми виділили папку Components у src як, так би мовити, константу. Зчитуємо все, що є. Усі папки, що у нас є там. Розуміємо, добре, стільки цих папок, отже, стільки у нас компонентів. Круто. Беремо, так би мовити, цей список. І для кожного розуміємо, що в кожному з них є такий код. В кожному з них є react-tsx-file, worker-tsx-file. Пишемо таку функцію. І що вона робить? Вона, так би мовити, повертає нам ось цей наш загальний webpack-config, який ми створили. Але для кожного з цих, так би мовити, файлів. Тобто, результат цієї штуки цієї функції буде просто набір webpack-configs для наших бандлів. Але, якщо ми захочемо додати якийсь новий віджет, то нам тут нічого змінювати не потрібно. Ми просто додаємо папку і все. І все працює. Ну, ось так.

На мій погляд, так би мовити, вау. Так би мовити, нічого не потрібно робити. Ви, так би мовити, один раз написали таку штуку. Всі інші фактично просто змінили структуру проекту. І все. І все працює. І ви інтегрувалися з платформою за 50 гривень. Ну, круто. А що далі? Далі реальність. Реальний-чек під назвою "Через рік ми найняли нового CTO". І новий CTO приходить і каже, "Мене 40 плюс років роботи. Я ще писав на Бейсіку, тому я знаю, що дефолтні експорти – це..." Вибачте за вираз, це цитата. "Це фігня. Тому я вимагаю, як CTO, щоб у нас було отак. Я хочу отак". 50 команд. Всі здивовані. І всі питають його, чому? І знову ж таки, вибачте за вираз, це цитата. І він відповідає, а вас це нестосується. Робіть. Ось. Sorry. Це цитата. Ось. І що з цим робити? Тобто, що це означає? Чи потрібно 50 командам іти і змінювати структуру всіх наших файлів worker.ts і react.ts, щоб змінити там дефолтні експорти на ось такі named export, які я запропонував.

Ну, давайте так. У нас є код, який написаний. У нас є код, який хочеться, щоб написали. Давайте він сам себе напише. Тобто, ось так. Сам себе напише, нехай. Код генерації. Що це означає? Ну, отже, у нас вже є якась build-tool, ну, так би мовити, яку ми запускаємо, щоб, так би мовити, збудувати щось, і в неї вся інформація є, то ми можемо якось її використовувати. Ну, насправді, так. То ми робимо? Ось бачите ось цей код? Це, в принципі, те саме, що і хотів наш CTO. Тобто, що ми робимо? Нехай у нас є... Ми створимо temp-папку, отже, в build-time створимо temp-папку. Ось, так би мовити, десь є, назвемо її temp. І давайте для кожного нашого віджета, для кожного нашого, ось цього, так би мовити, рутового файлу React TSX і Worker TSX, ми створимо нові файли. Але у них буде ось така структура. Там буде імпорт з... Справжніх... З реальних файлів. Ось. З правильним шляхом. Бо у нас ця вся інформація є. Там буде ось така структура. Ось це просто будуть файли якісь. Так би мовити, контент такий. Ну, можливо, там чи треба було написати мені. Так ні, ймовірно, воно просто має запрацювати ось так. Тобто, що ми зробили? Ми в temp-і... В build-time створили якісь нові файли. І тепер ми кажемо... А webpack.config, подивись. Ти тепер подивись не на ці справжні файли, які ми тобі казали, а подивись на ці. І що це означає? Вебпак такий, окей. Він подивиться на це. Буде дивитись на цей файл з таким контентом. І все. І рутовий вигляд вашого бандлу буде ось такий. Тобто, ми ж знову ж таки.Одна людина зробила ось ці зміни. І тепер людям в 50-тих проектах не потрібно робити нічого. Тобто, їм не потрібно робити нічого. Ну, так би мовити, щоб виконати вимоги нового CTO.

Ну, в принципі, це як би біблійська історія виходить. Мені дуже подобається. Що, як би, далі? Ну, як ви зрозуміли, у нас... Ви ж бачили, що ми там використали наш сетіон. І наш сетіон, шерет, конфіг, вебпака. Ми можемо, як би, ще це все так прикольно зробити з код-генерацією. І пам'ятаєте, в нас ж там були всі фічер, абстракція, фічі, ось все це.І зазвичай воно ж як виглядає? Ну, так би мовити, в нас є рутовий компонент, в нас є, як би, провайдери в світі React. Ми там обгорнули це в нашому app.tsx, наприклад. Взяли всі провайдери з фічей. Зробили ось так. Ну, так би мовити, і все. Круто. Але, насправді, чи потрібно це розробникам? Ну, можливо, а можна і, в принципі, так не робити. Можна зробити ось так. Тобто, в нашому результативному бандлі. Ну, так би мовити, ви зрозуміли, що потрібно, щоб наші фічі експортували провайдер і якусь просто функцію, яка обгортає компонент з цим провайдером. І тепер ми можемо зробити? Ми можемо в нашому бандлі сказати, окей, що коли ти робиш це, імпортуй ще два наших обгортачі і обгорніть ними React-компонент.

І тепер замість такого, людина може написати ось таке. І все. І її, в принципі, не турбує. Виходить нова фіча якась. Знову ж таки, прийшли в нашу білдтулу, додали якийсь імпорт, якщо хочемо. Все. Ну, типу, прямо кайф. Що можна ще зробити? Ну, насправді, все, що завгодно. В білдтаймі зробити, модифікувати ts-конфіг, наприклад, якщо потрібно. Буває потрібно, до речі. Internal якийсь файл з метаданими. Тобто, приходить новий CTO. А я тепер хочу метадані, якісь JSON. Теж будуємо в білдтаймі, легко. Типи для TypeScript. Якщо це цікаво, чому цей пункт взагалі є, теж підходьте, питайте у хлопців. Щось зі Storybook. Ну, насправді, все, що завгодно. До речі, хотів сказати. Бачите, немає анімацій, окрім гіфок. Ну, я так скажу. У мене була просто ситуація з аніматором в Туреччині. Більше нічого не можу сказати без адвоката. Тому без анімацій, як ви бачите. Що далі? Зараз є питання, що ми всі бачимо AI. Блін, типу, AI забере наші робочі місця. То що треба зробити, щоб AI не забрав наші робочі місця? Це мій, до речі, особистий досвід. Треба зробити щось таке, що, по-перше, буде працювати. Але ніхто не буде розуміти, як воно працює. Але воно дуже потрібне. Тобто, зробіть, ну, це якби особиста думка. Ви можете зробити плагін, ну, типу, якусь альтернативу, яка буде дивитися на AST-структуру коду людей і щось змінювати.

Якщо вам ці слова, ці речення про що не кажуть, це плюс, на мій погляд, значить, ви, як кажуть, не розумієте і не знаєте всі ці потенційні проблеми, які можуть виникнути. Але, ну, я так робив. Насправді, я дуже радий, що ця річ не в продакшені. Ось. І... Ну, так. Все ще можна сказати. Тепер. Швиденько подумаємо, чи це гарний, в принципі, сценарій. Ну, які у нас плюси? Zero bootstrapping. Тобто, якщо нам з'являється нова команда, 51-ша, все ще її потрібно зробити, це просто організувати структуру за нашими правилами і все. Ну, просто, типу, прямо рай на землі. Ось. Просто фокусуємось на бізнес-логіках. У нас одразу є всі фічі.

Ми одразу можемо використовувати всі наші, типу, класні хуки для того, щоб їх зберегти. Просто кайф. Але є проблеми. Типу, з feature abstraction ми додаємо domain-specific language. Тут виходить взагалі, типу, ну, рівень domain-specific language просто, типу, зростає. Дуже багато інфи потрібно зазначити, бо ми ж, типу, вся та штука, яку я вам показав, вона трошки кустарна. Але коли, якщо ви йдете цим шляхом, будете додавати нових-нових фішок, ви додаєте абстракції, значить, ви додаєте новий DSL. І це про все треба писати. Тобто,, це виходить як такий framework. Ну, насправді це і є framework, виходить. Ось.

І це все треба описувати, вести документацію і так далі. Я, наприклад, ненавиджу це. Ну, для мене це найгірша частина. Я можу зробити фічу, наприклад, за день, а потім неділю писати документацію. І це навіть не жарт. Отже, якщо треба просто зробити цей поворот на 360 градусів, то треба якось щось думати. Ось. Ну, і найгірше це те, що треба це все утримувати. Ось. Ну, але в принципі, і найкраще. Бо, як кажуть, два плюс роки в WIX, спробуйте мене звільнити з WIX. Ось. Ну, в принципі, чи це якби фантазія? Ну, насправді це не фантазія. Все, що я вам зараз розповів, це такий швидкий wrap-up того, чим я займався три останні роки. А WIX, в принципі, вже досить давно займаються.

Ну, насправді. Проблема лише в тому, що з гарним чи поганим WIX все рівно треба працювати. Ось. Це не прикольно. Але. Насправді, що до цього слайда? Це слайд про те, що навіть в Україні, бо є ідея, що у нас, типу, багато аутсорсу. Ми щось робимо. На фронтенді чи бекенди кажуть, ну, формочки зробіть. Там, сюди сідайте. Ні. Можна робити складні речі. Можна робити цікаві речі. Можна робити не лише формочки. Можна робити щось, що економить дуже багато часу. Значить, дуже багато грошей. Ось. Ми всі це робимо. І це не пусті слова. Тому давайте швиденько просто пройдемось трошки. WIX важливий. Ну, важливо. Бо у нас усіх ресурси, як би, обмежені. А ми хочемо робити все швидко і продуктивно.

Boilerplate. Ну, можливо, я не розкриваю до кінця, чому його потрібно розуміти, що Boilerplate потрібно зменшувати. Сприймайте це як аксіому. Boilerplate — це не дуже прикольно. Якщо ви йдете цим шляхом, то потрібно розуміти, що у вас відкривається багато простору. Для якихось максимально сміливих ідей. Але то з вас вимагає набагато більше. Прям набагато більше. І треба це дуже сильно, прям дуже гарно усвідомлювати. Ну, і основна річ, що WIX наймає. Прям дуже багато. Навіть, можливо, в мою команду. Але це, типу, не точно. Але можливо. Тому, в принципі, дякую. Може, є які-небудь питання?

Sign in
Or by mail
Sign in
Or by mail
Register with email
Register with email
Forgot password?