Node-Webkit без вебкита

Якось ми обговорювали десктопні програми nw.js. Все добре, але необхідність поширювати весь движок браузера (який з плином часу і додаванням нових фіч менше не стає і зараз важить стислий 30МБ) — пригнічує.
А що якщо зробити модуль для node.js, вміє показувати UI в системному браузері?
Під катом розповім про спробу — як воно, варто зусиль, можна використовувати, і що в результаті вийшло.

Dicslaimer
В основному проект був зроблений швидше як proof-of-concept: погратися, подивитися, перевірити, як воно. Зробив на ньому 3-4 замовлення в стилі «хочу маленьке додаток з вбудованим webview» або «хочу обгортку для сайту у вікні десктоп-додатки». Може бути, комусь мій досвід виявиться корисний, тому виклав в паблік. Код на гітхабі. Детально описувати нюанси коду не буду, ціль — не описати код, а швидше подумати над придатністю результату.

Як це працює
Додаток статично збирається з node.js зі своєю точкою входу. При запуску в ноду додається нативний модуль з логікою відображення вікон, і управління передається _thirdPartyMain.js (в ноді є така можливість). Звідти завантажується користувальницький main.js, де підключається модуль ui. Модуль стартує http-сервер, відкриває вікно з заданим конфіг і направляє webview на адресу вбудованого сервера, який віддає користувальницький контент. Вікно генерує події (переміщення, згортання, ...) і вміє виконувати методи (наприклад, закритися).

WebView
Під вінди вставляється ActiveX-ний Браузера (це той же MSIE, але без тубларов, адресних рядків ітд). За замовчуванням він показує багато непотрібних діалогів (які відключаються дивним чином), але в цілому працює як хочеться. IE, оновлюється неважливо, а підтримати XP треба було, тому для старих версій Windows передбачена можливість скачати вебкит (chrome embedded framework). При необхідності, якщо користувач не проти, додаток завантажує бібліотеки, розпаковує їх і працює вже з вебкитом.
Під маком все більш прозоро, WebKit WebView порівняно з IE в інтеграції набагато простіше і понянтее; під лінуксом є webkit-gtk.

Упаковка додатків
Потрібно було, щоб додатка пакувалися в один EXE. Найкращим форматом виявився ZIP: він читається з кінця, дозволяючи дописувати в виконуваний файл що завгодно, і розпаковувати його; за цим принципом і працюють SFX. Для використання з node.js можна повісити хук на звернення до fs і перенаправляти запити до файлів, які є в архіві, до віртуальної файлової системи замість читання з диска.

Взаємодія з браузером
IE і WebKit пропонують способи взаємодії як з C++ в JS, так і навпаки. В IE javascript-овий об'єкт, у тому числі і функція, являє собою об'єкт IDispatch. Якщо перевірити typeof такого об'єкта, javascript-движок віддасть unknown, це так звані host objects (використання таких результатів оператора typeof в стандарті ES6 вже не рекомендується, але раніше про нестандартні типи нічого не було сказано). Щось викликати з C++ можна, звернувшись до об'єкта window.external, за умови, що хост реалізував цей метод.
У вебките аналогічно, можна додати властивість window як об'єкт з методми, доступними для виклику.

Взаємодія з node.js
В ноді процес створення плагінів прекрасно документований. Аналогічно створюються і вбудовані аддони, але реєструються іншим макросом. Після створення класу аддона, він успадковуються від EventEmitter-а і вміє генерувати події, отримавши посилання на метод emit.
Node.js навмисно живе в окремому тред, щоб тривалі операції не блокували UI, тому для відправки повідомлення у ноду і синхронізації використовується бібліотека UV.

Що вийшло добре
Розмір програми
Він становить 2-3 МБ (незапакованного 7). В принципі можна зробити складання та меншого розміру, якщо треба тільки відкрити сторінку в додатку, без node.js (вобщем-то заради розміру все і робилося).

Час запуску
Оскільки у програмі не використовуються додаткові фреймворки, запускається вона швидко в середньому 1 секунду (про час першого запуску див. нижче); додавши профілювання, можна переконатися, що основний час витрачається на ініціалізацію браузера.

Проблеми
Перший запуск
Windows оптимізує запуск додатків і компонентів, які ви використовуєте найчастіше. Якщо IE користуються рідко, час першого запуску програми становить десь 3..10 секунд, в залежності від операційки і комп'ютера.

Версії браузерів
Дуже часто IE використовують як інструмент для скачування браузера не оновлюють взагалі ніколи (хоча з останніми версіями Windows ситуація поліпшується). IE не можна оновити примусово (показати діалог поновіть IE з програми рівносильно самогубству: оновлення IE складний, тривалий, часто вимагає перезавантаження — не можна так знущатися над користувачем, він просто знайде інший додаток).
Версії браузерів прив'язані до операційці: для Windows XP IE10, для OS X Lion немає Safari 8.

Упаковка
Додаток запаковано UPX — деякі антивіруси можуть лаятися на нього. Можна не пакувати додаток і отримати розмір 6-7МБ. Знову багато. Менше, ніж 60, але все одно не 2 МБ.

Контексти javascript
Об'єкти node.js не можна використовувати в браузері і навпаки, взаємодія відбувається або як в класичному клієнт-серверному додатку (xhr), або способом, наданих програмою (postMessage у вікні або ноде) — тобто як в web worker, передати можна тільки прості дані. Можна було зробити context bridge, але це по-перше складно і бажно, по-друге недалекоглядно, бо ES6 вже майже тут, а що робити, наприклад, з об'єктом-проксі в IE10 — невідомо.


Є збірка під win/mac/linux, яку в принципі можна використовувати, кастомизировать ітд. Я і використовую її для створення кастомізованих «програм-браузерів», коли це буває раптом комусь треба. Вона відносно стабільна, але до розуму і релізної якості я її не ставив, тому що…

Висновки
Програми викачуються рідко, інтернет зараз досить швидкий (і в разі встановлення програм, EDGE дійсно можна знехтувати, тому що програма — це не сайт, його не будуть устаналивать в дорозі), вирішуються проблеми у використанні системного браузера присутні. У більшості випадків зараз гра не варта свічок і використовувати вебкит здається більш правильним. Якщо мета — створити маленьке додаток в основному під нові операційки — а може, й так.

Посилання

Джерело: Хабрахабр

0 коментарів

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