Remote (dev)tools своїми руками – інтерв'ю з Романом Дворновым (Авіто)



Роман Дворнов twitter – керівник фронтенд-розробки в Авіто, автор basis.js, мейнтейнер CSSO, CSSTree, Component Inspector і не тільки. Роман працює над новим проектом, що покликаний спростити розробку інструментів віддаленого моніторингу та налагодження web-додатків.

Давайте дізнаємося, які проблеми допоможе вирішити проект Романа, і до чого він прийшов.

– Розкажи, що таке rempl і навіщо він взагалі потрібен?

– rempl – рішення, яке дозволяє отримати контрольований віддалений доступ до runtime програми. Рішення композитне і складається декількох різнопланових компонент.
Ми починаємо з того, що створюємо провайдера (спостерігача), сутність, яка моніторить додаток (або сторінку, процеси в браузері і т. д.) і публікує деякі дані. Далі ми створюємо інтерфейс (споживач), який ці дані візуалізує або робить з ними щось ще. При цьому інтерфейс – це деякий UI, який може бути запущений в довільному WebView і до нього «магічним» чином потрапляють дані від провайдера. Провайдер і споживач також можуть обмінюватися командами.

Коли ми говоримо про довільному WebView, то маємо на увазі іншу вкладку, вкладку іншого браузера, браузерні Developer Tools, плагіни в редакторах і IDE, як на тій же машині, що і провайдер, так і на будь-який інший.

Rempl дозволяє досить просто створити свій інструмент, тобто провайдера, і деякий інтерфейс, який забезпечує весь транспорт (ми створюємо провайдера і споживача, а вони самі з'єднуються і починають спілкуватися між собою), а також надає ряд хостів зразок веб-інтерфейсу, який можна відкрити у будь-якому сучасному браузері, плагіни для браузерних Developer Tools (поки тільки Chrome, але буде і Firefox), різних редакторів (поки Atom і VS Code) та інше. Також в планах є SDK, яке спростить типові операції, такі як робота з потоками даних і роботу з DOM, наприклад, підсвітити певний елемент на сторінці.
Щоб отримати уявлення про те, як це працює, можна подивитися відео – в цьому відео показано інструменти для basis.js, на яких обкатувався підхід. Власне, при роботі над цими інструментами стало зрозуміло, що підхід досить універсальний. А саме більша його частина, яка стосується транспорту і хостів, не залежить від специфіки фреймворку або програми. Можна вважати, що реалізація інструментів basis.js стала прототипом для rempl – універсального рішення для створення подібних інструментів. Коли все запрацювало з інструментами basis.js я подав заявку на HolyJS і почав пиляти rempl :)

Провайдер і споживач
– Що з себе представляє провайдер? Ця сутність тільки надає API для взаємодії з інструментом, а самі дані повинен збирати інструмент?

– Провайдер (provider) і споживач (customer) — це ролі. Зараз є певна проблема з термінологією, але те, що виходить близько до паттерну publish-subscribe і проблеми producer-consumer.

Провайдер – це та частина, що генерує і публікує дані, а споживач їх використовує. Rempl дозволяє отримати API для публікації на одній стороні (стороні провайдера) і приймати дані на інший (споживач). Те, як ці дані збирати і в якому вигляді публікувати, розробник вирішує сам при створенні провайдера. Точно так само як і що робити з цими даними на стороні споживача. В методах і технологіях обмежень немає, в цьому випадку rempl лише полегшує передачу даних від однієї сторони іншій.

– За протоколом відбувається спілкування провайдера і споживача? Для такої взаємодії потрібен посередник (сервер)? Це буде працювати в IE?

– Все залежить від того, де хоститься провайдер і споживач. Якщо провайдер хоститься в браузері або node.js процесі, а споживач в іншій вкладці браузера (або в іншому браузері), то комунікація відбувається через socket.io. В цьому випадку, так, використовується проміжна ланка у вигляді сервера. Сервер не тільки є сполучною ланкою, але і надає веб-інтерфейс зі списком всіх підключених провайдерів, можливістю вибору цікавить і організує запуск користувальницького інтерфейсу вибраного провайдера в пісочниці (sandbox). Останнє, по суті, є хостом для споживача.

Так як для комунікації використовується socket.io, то буде використовуватися або WebSocket, або long polling як фолбек. Тобто в IE, теоретично, в плані транспорту все повинно працювати.
Але socket.io використовується не завжди. Наприклад, з браузерних Developer Tools через веб сокети не поспілкуєшся. У цьому випадку комунікація забезпечується через DOM-події. Більше того, для того, щоб щось передати у вашу закладку, потрібно з'єднати між собою 4 вузли: провайдер <--> content script <--> background page <--> plugin (схема є на початку статті). Це нетривіальне завдання, але з rempl вам не потрібно про це думати.

– Коли ти говориш про збір даних провайдером, ти маєш на увазі моніторинг клієнтської частини програми?

– Моніторинг це лише один з можливих напрямків, як це можна використовувати. Так, початкова ідея була саме в області клієнтської частини додатків і сайтів. Але в ході обговорень з колегами варіантів використання rempl, вже в ході підготовки доповіді, несподівано прийшло розуміння, що провайдер може жити не тільки в браузері, але і в node-процесі. Таким чином, вся та ж інфраструктура стала доступна і для node-додатків. Так можна отримувати інформацію про внутрішні процеси в зручному і наочному інтерфейсі.

Наприклад, є такий проект як дешборд для Webpack, який малює в консолі інформацію про те, що відбувається в більш наочній формі, ніж звичайний висновок Webpack'а. Колега зробив клон цього плагіна, головна відмінність якого в тому, що інформація виводиться з використанням веб-технологій і може виконуватися в довільному WebView. Це дає набагато більше можливостей для візуалізації і більш багатого UX. Наприклад, можна прикрутити вже готові рішення з аналізу бандлу, такі як source-map-explorer та інші. При цьому для аналізу бандла необов'язково, щоб він був на диску, адже провайдер має доступ до рантайму Webpack, і тут великий простір для фантазії.

Інструментів розробки і раніше не вистачає
– тобто, нам варто очікувати появу нових інструментів, які будуть краще старих?

– Час покаже, але я дуже на це сподіваюся :) Одна з основних цілей, крім того, щоб надати готове рішення, це знизити поріг входу для розробників у виготовленні власних інструментів. Я вважаю, що інструментів багато не буває, і від того, що ви використовуєте в розробці, дуже сильно залежить ваша продуктивність. Незважаючи на, здавалося б, велику кількість інструментів розробки, їх як і раніше не вистачає. Це пов'язано з тим, що інструменти часто роблять інші розробники, вирішуючи свої завдання. Але у кожного свої потреби, завдання, можливо, унікальний стек технологій або власний фреймворк. У цьому випадку рішенням проблеми буде розробка своїх інструментів. Але доведеться зробити багато, особливо, якщо є мета запускати інструмент поза сторінки, в якій працює додаток. Це вимагає багато часу і нервів.

Більш того, це не можна назвати корисною роботою – це свого роду оверхед, який віддаляє вас від розробки безпосередньо самого інструменту. Так от, rempl дозволяє уникнути зайвої роботи і зосередитися безпосередньо на інструменті, що куди простіше і цікавіше.

Є ще один важливий момент. Різні хости для інтерфейсу інструменту можуть дати додаткові можливості. Особливо хостинг інструменту в редакторі – адже це двері в світ нових можливостей для веб-розробки. Зараз є безліч інструментів, які допомагають писати код і аналізують його. Є інструменти, які свідчать про те, що відбувається всередині додатка (в його runtime). І ці дві категорії інструментів живуть окремо. Але що, якщо ми об'єднаємо ці два світи? Так, маючи завантажений інтерфейс інструменту в редакторі/IDE, має віддалений доступ до runtime – можна отримати нові можливості. Просто уявіть, у нас є інформація про код і runtime в одному місці! І з цим з певністю можна щось зробити. Приміром, редагуючи JavaScript, CSS або шаблони, можна підсвічувати на сторінці те, що зачіпає редагований файл. Або в шаблонах підказувати, які доступні биндинги. Або показувати, на що Webpack ресолвит require, з можливістю перейти на потрібний файл. Або у що траспилируется поточний файл і т. д.

Насправді, я сам ще не знаю всі можливі кейси, але можу сказати напевно, можливостей дуже багато, і нові ідеї з'являються постійно. Дуже цікаво, що придумають інші :)
Кордон між кодом і runtime в редакторах я побачив досить давно, і зрозумів, що її можна подолати. Але для того, щоб це якось утилізувати в своїх інструментах, довелося зробити чимало. До rempl так чи інакше я йшов більше п'яти років, створюючи проміжні рішення. Багато рефакторинги і роботи в напрямку «зробити по розуму» приводили в глухий кут і не мали хеппі енду – закінчувалося терпіння і час. Радий, що зараз вимальовується закінчене рішення, хоча ще багато над чим потрібно попрацювати.

Це як приклад того, що рішення рутинних інженерних завдань віддаляє від корисної роботи. Зараз я тільки підходжу до того, щоб реалізувати багато своїх ідей. Шлях був тернистим, і я точно не буду радити комусь його повторювати. Вважаю своєю маленькою перемогою, що багатьом і не доведеться, достатньо буде взяти rempl і зробити те, що вони давно хотіли для свого проекту або стека.

Розробка такого інструменту – це каторга
– А як rempl вплине на вже існуючі інструменти?

– На це питання складно відповісти, так як складно прогнозувати реакцію розробників інструментів. Чи захочуть вони перевести свої інструменти на загальну платформу або продовжать пиляти своє. Одне можу сказати, інструменти basis.js точно мігрують на rempl і почнуть використовувати нові можливості, що повинно позитивно позначитися на їх функціональності. Component Inspector теж буде переведений на rempl. І думаю, що в нашій компанії, незабаром з'являться нові інструменти на основі rempl, які вирішують нагальні проблеми.

Говорячи про існуючі інструментах, хотілося б розповісти про кілька проблем. І хоча проблеми різні, як не дивно, одна випливає з іншої.

По-перше, проблема транспорту і хостів тільки здається простий. У ній дуже багато підводних каменів і, повторюся, це не сама проста і тим більше цікава задача. Якщо подивитися на розробників інструментів (зазвичай це інструменти до фреймворкам у вигляді плагінів для браузерних Developer Tools), то всі вони ходять по одному і тому ж мінному полю. Тобто кожен розробник заново, з нуля, реалізує все необхідне, а саме транспорти, хости і т. д. При цьому втрачаючи час, вирішуючи ті ж проблеми, що й інші. З rempl розробникам інструментів можна буде видалити своє рішення для різних платформ (хостів) і дбати тільки про основний їх функціональності інструменту. Наприклад, у react-devtools можливо буде видалити папку shells – можна повивчати, наскільки там непростий код.

По-друге, складність розробки і розвитку інструменту. Наприклад, інструменти для фреймворків часто обмежуються плагіном для браузерних Developer Tools. Розробка такого інструменту – це каторга. Адже щоб побачити зміни, потрібно перезібрати плагін, перевантажити його в налаштуваннях браузера (в Chrome це Extensions), перезавантажте сторінку, де використовується плагін, закрити браузерні Developer Tools, їх заново відкрити і вибрати вкладку вашого плагіна. І це потрібно робити кожен раз, коли ви вносите зміни. Ми самі через це проходили, дуже швидко набридає і починає бісити. Куди простіше запускати той же інтерфейс, що і в плагіні, в окремій вкладці браузера так і розробляти. А коли все буде готово, то просто запустити цей інтерфейс Developer Tools.

Все стає набагато простіше: для того, щоб побачити зміни, досить перезавантажте сторінку, а якщо стек, на якому створюється інтерфейс, підтримує live update або live reload, то і цього зазвичай не потрібно. Але щоб це організувати, вам потрібно реалізувати ще один вид транспорту і запуск інтерфейсу в відмінному від Developer Tools оточенні. І тут хто як виходить з ситуації, але, у будь-якому разі, процес не можна назвати приємним і захоплюючим. Тому такого роду інструменти розвиваються повільно, а то й зовсім їх розвиток завмирає. Rempl дозволяє запускати ваш інструмент (його інтерфейс) в тому хості, який найбільш підходить для розв'язуваної вами завдання, і вам не потрібно робити щось особливе для цього.

По-третє, версіонування. Коли ви робите інструмент, наприклад, для фреймворку, який розвивається, то потрібно бути готовим до того, що у фреймворку щось може змінитися, і, інструмент перестане працювати. Власне, так і трапляється, фреймворк змінюється – інструмент змінюється слідом. Але інструмент не може працювати тільки з останньою версією фреймворку: не всі мігрують швидко, а деякі проекти взагалі можуть бути на підтримку і оновлення бібліотек може бути дуже дорогим і нераціональним заходом.

Залишатися зовсім без інструментів в таких випадках теж погано. Тому інструменти «навчаються працювати з різними версіями фреймворку, що з часом перетворює їх код у кашу і сильно ускладнює додавання нової функціональності. Ми це теж проходили з інструментами basis.js і це велика біль, особливо для літніх фреймворків. Rempl вирішує цю проблему своєю моделлю поширення інтерфейсу. А саме: хост (наприклад, плагін для браузерних Developer Tools) це всього лише пісочниця, в якій може бути виконаний довільний скрипт. Хост нічого не знає про інтерфейсі. Коли зі сторінки вибирається деякий провайдер (інструмент), з яким доведеться працювати, то хост посилає до провайдера запит «а дай мені твій інтерфейс», а у відповідь провайдер віддає скрипт (пакет, в якому є все необхідне для побудови інтерфейсу). Хост виконує цей скрипт в пісочниці і ви бачите інтерфейс інструменту. Таким чином, для кожної версії фреймворку ви підключаєте свою версію провайдера (інструменту) на сторінці. В результаті, в залежності від версії фреймворку в Developer Tools, ви побачите ту чи іншу версію інструменту, версії можуть відрізнятися функціональністю і зав'язані на конкретну версію фреймворка. Підтримка інструменту в такому випадку здорово спрощується і вам не потрібно різних браузерних плагінів для того, щоб працювати з різними версіями фреймворка.

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

– Я сильно здивований, що в цій сфері немає нічого готового.

– Темою займаються деякі, так як вона не проста. Кастомное рішення хоч і непросто зробити, але куди простіше універсального. Ну і треба поваритися в темі значний час, щоб це остаточно дістало і побачити способи вирішення проблеми ;)

– Спасибі, що приділив мені час. Підкажи, коли і де можна буде побачити результат?

– Все що відноситься до проекту доступно на GitHub організації rempl. Правда, зараз там «робочий безлад» і поки не все готово, але до виступу на HolyJS все повинно стати набагато краще. У будь-якому випадку, можна поставити лайк і підписатися на оновлення вже сьогодні ;)

В ході самого виступу на HolyJS, 11 грудня, я постараюся розповісти все більш структуровано, з прикладами коду, схемами і live demo. Це буде перший публічний виступ про проект. Але, думаю, далеко не останнє – попереду ще багато чудових відкриттів, про яких можна буде почути на майбутніх конференціях.



Всім, хто зацікавився даною темою, ми пропонуємо відвідати доповідь Романа на JavaScript-конференції HolyJS. Також ви зможете почути ще 19 доповідей про проблеми, рішеннях і майбутньому JavaScript світу: говорити будемо про фронтэнд, бекенд і навіть десктоп.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.