Як скомпілювати код у браузері за допомогою WebAssembly

Як скомпілювати код у браузері за допомогою WebAssembly
7 хв. читання
11 листопада 2020

Браузери стали потужними. Спочатку вони використовувалися для обміну науковими роботами в CERN, а тепер в браузері можна запускати Google Earth, грати в Unity 3D- ігри  та навіть проєктувати будівлі в AutoCAD.

Чи може браузер, з такою потужністю,  скомпілювати та запустити ваш код? 

Чому б ні? Я ніяк не міг проігнорувати такий захоплюючий виклик. Після чотирьох місяців натискання клавіш та перегляду документації я нарешті створив свою відповідь: Go Wasm.

Зображення для публікації
Перейти Wasm https://go-wasm.johnstarich.com

Go Wasm - це середовище розробки на Go, в якому є все необхідне для написання та запуску коду повністю у браузері, використовуючи потужність WebAssembly (Wasm). Проєкт має відкритий вихідний код. Go Wasm складається з трьох основних компонентів WebAssembly: «операційної системи», редактора та оболонки.

У цій статті я покажу вам, що таке Go Wasm, як це працює і що попереду.

Пишіть за допомогою Go Wasm

Go Wasm дає можливість як писати, так і запускати програми Go, використовуючи фактичний компілятор Go. Іншими словами: напишіть код go build, а потім запустіть програму. Це значно відрізняється від знайомих сайтів, таких як Go Playground, оскільки код насправді працює у браузері - навіть після відключення від Інтернету.

Зображення для публікації
Go Wasm також працює в автономному режимі

На демонстраційному сайті Go Wasm завантажується ОС, розміщує інсталяцію Go у віртуальній файловій системі, запускає редактор коду та показує загальні інструменти, такі як термінали та елементи керування компілятором. Я склав докупи три ключові програми, щоб це все працювало, і я розгляну кожну з них у наступному розділі. Спочатку короткий огляд IDE.

У редакторі ви можете писати код Go на декількох вкладках, імпортувати зовнішні бібліотеки, переформатувати код та запускати програму.

Для запуску користувацьких команд Go CLI або інших програм просто відкрийте термінал. Щоб передати вхідні дані програмі або зберегти її вихідні дані, скористайтеся перенаправленням файлу, ось так ./playground > output.txt або під'єднайте виходи до входів за допомогою | каналів.

Файл перенаправляє та підключає виходи до входів із трубами в оболонці Go Wasm

Ви також можете створювати та встановлювати власні програми Wasm в будь-якому місці віртуальної файлової системи. На наведеному вище скріншоті  програма count-lines була скомпільована та збережена в /bin. Звідси її можна запустити, як і будь-яку іншу вбудовану команду.

Як це працює

Go Wasm складається з трьох основних програм: «операційної системи», редактора та однієї або декількох оболонок. Всі ці три стискаються разом із браузером, де операційна система є перекладачем для доступу до віртуальних файлів та процесів.

Зображення для публікації

На високому рівні операційна система (ОС) перехоплює системні виклики між програмами Go та браузером, щоб надати доступ до віртуальної файлової системи та процесів. Оскільки браузер нічого не знає про файли або процеси, ця ОС є важливим будівельним матеріалом для запуску програм Go. Це насправді не справжня ОС, але вона надає важливі абстракції, які зазвичай недоступні у браузерах.

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

Програми редактора та оболонки розташовані на вершині ОС, так само як і скомпільована  програма з редактора. Редактор має вкладки файлів, елементи керування та термінали для написання та запуску коду Go. Оболонка запускається на кожній вкладці терміналу, щоб ви могли запускати власні go команди або власні програми, як у справжньому терміналі.

"Операційна система"

Операційні системи запускають програми на різному обладнанні. Вони надають програмам фасад для доступу до ресурсів, але зазвичай не дозволяють прямого доступу. Якщо програма відкриває файл і записує деякі дані, тоді ОС повертає дескриптор файлу і записує дані на апаратний диск. Такі важливі дії часто називають системними викликами.

Подібним чином, операційна система Go Wasm дозволяє запускати програми Go, перехоплюючи системні виклики та маніпулюючи віртуальними ресурсами замість реальних. Оскільки програми Go, орієнтовані на Wasm, покладаються на глобальні функції JavaScript для здійснення системних викликів, компонент ОС замінює їх на власний код. Браузери насправді не надають доступ до файлів та процесів, тому ці функції заміни створюють віртуальні версії, а потім передають їх назад у Go.

Зображення для публікації
Діаграма послідовності відкриття файлу

Процеси в браузері представляють цікаву проблему. Для досвідченого веб-розробника очевидно, що не існує такого поняття, як "процес JavaScript", і точно немає можливості запускати дві програми одночасно. Для боротьби з цим обмеженням я використовував перемикання контексту, щоб переходити між процесами, так ніби вони працювали на одному ядрі процесора. Перемикання контексту дозволяє ОС замінювати таблиці файлів, що відповідають процесу, і змінні середовища, коли новий процес отримує пріоритет виконання. 

Віртуальна файлова система

Короткий огляд віртуальної файлової системи, оскільки особливо важко було отримати правильне рішення. Сучасна файлова система (FS) містить в собі безліч функцій. Дозволи доступу до файлів, власні конвеєри та блокування файлів повинні працювати бездоганно, інакше go build не зможе працювати без помилок.

Щоб заощадити трохи часу, я уникнув написання власної файлової системи в пам’яті з нуля і взяв Afero. Afero дав хорошу відправну точку і визначив потужну абстракцію файлової системи. З використанням цієї FS я створив кілька користувальницьких файлових систем: монтовану FS, потокову gzip FS та експериментальну IndexedDB FS. На жаль, навіть маючи такий міцний фундамент, помилок було багато.

Виявляється, Go CLI не дуже добре працює коли операційна система на якій він запускається не справжня.

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

Редактор

Редактор виконує більш звичну роль. Він налаштовує веб-сторінку з вкладками редактора коду, елементами керування, консоль збірки та вкладки терміналу.

Редактор коду та оболонка, об'єднані всередині IDE

Програма редактора працює над ОС, запускаючи нові процеси, як будь-яка звичайна програма Go. На вкладках редактора запускається CodeMirror який синхронізую підключені файли з файловою системою.

Термінали запускають процеси оболонки, а потім підключають вхід і вихід до xterm.js для більш звичного досвіду роботи з терміналом.

Оболонка

Оболонки всередині кожної вкладки терміналу - це інтерактивний спосіб запуску go команд або будь-якої іншої програми Wasm у файловій системі. Там було кілька консольних команд, написаних на Go, але жодну з тих які я пробував не вдалося скомпілювати на Wasm і вони не запустилися з коробки. На щастя, запуск оболонки був цікавим і повчальним процесом. Мені довелося дізнатися все про коди виходу терміналу для підтримки редагування вводу в командному рядку, а потім пофантазувати з перенаправленнями файлів процесу та змінними середовища.

І це все! Я люблю поєднувати нові бібліотеки в Go Wasm, щоб перевірити свої шалені ідеї. Я не можу дочекатися, щоб побачити, що люди з цим зроблять.

Зображення для публікації
Хелловін цього тижня - я просто не міг встояти. :)

Що лежить попереду

WebAssembly, безумовно, зараз має свої підйоми та падіння, але він також має величезний потенціал, який лише чекає своєї реалізації.

З іншого боку, спільнота була зайнята. Вони висувають перспективні пропозиції та опікають всілякі стандарти. Зокрема, я стежу за темою Wasm Threads та стандартом WASI.

На жаль, є деякі мінуси. Одна з моїх найбільших перешкод - відсутність підтримки налагоджувача  для Wasm. Хоча у браузері є налагоджувач, він може лише переглядати асемблерні інструкції, а не вихідний код. Оскільки я не володію вільно  текстовим форматом Wasm, діагностувати та виправляти проблеми  надзвичайно неприємно.

Що стосується Go Wasm, перед нами велике захоплююче майбутнє. Якщо спільнота виявить інтерес, я хотів би додати такі функції, як підтримка мобільних пристроїв (менший обсяг пам'яті), збереження файлів у сеансах або, можливо, власне виконання програм WASI! 

Джерело: How to compile code in the browser with WebAssembly

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація