Как работает Wails
Wails — это фреймворк для создания десктопных приложений, использующий Go для бэкенда и веб-технологии для фронтенда. Но в отличие от Electron, Wails не включает в себя браузер, а использует нативный WebView операционной системы.
Ключевые отличия от Electron:
| Аспект | Wails | Electron |
|---|---|---|
| Браузер | WebView от ОС | Встроенный Chromium (~100 МБ) |
| Бэкенд | Go (скомпилированный) | Node.js (интерпретируемый) |
| Коммуникация | Мост в памяти | IPC (межпроцессное взаимодействие) |
| Размер бандла | ~15 МБ | ~150 МБ |
| Память | ~10 МБ | ~100 МБ+ |
| Запуск | <0.5 с | 2–3 с |
Основные компоненты
Заголовок раздела «Основные компоненты»1. Нативный WebView
Заголовок раздела «1. Нативный WebView»Wails использует встроенный движок рендеринга веб-страниц операционной системы:
WebView2 (Microsoft Edge WebView2)
- Основан на Chromium (тот же, что и в браузере Edge)
- Предустановлен в Windows 10/11
- Автоматические обновления через Windows Update
- Полная поддержка современных веб-стандартов
WebKit (движок рендеринга Safari)
- Встроен в macOS
- Тот же движок, что и в браузере Safari
- Отличная производительность и энергоэффективность
- Полная поддержка современных веб-стандартов
WebKitGTK (GTK-порт WebKit)
- Устанавливается через менеджер пакетов
- Тот же движок, что и в GNOME Web (Epiphany)
- Хорошая поддержка стандартов
- Легковесный и производительный
Почему это важно:
- Нет встроенного браузера → Меньший размер приложения
- Нативный для ОС → Лучшая интеграция и производительность
- Автообновления → Патчи безопасности из обновлений ОС
- Привычный рендеринг → Тот же, что и в системном браузере
2. Мост Wails (Wails Bridge)
Заголовок раздела «2. Мост Wails (Wails Bridge)»Мост — это сердце Wails, обеспечивающее прямую коммуникацию между Go и JavaScript.
Как это работает:
- Фронтенд вызывает метод Go (через автоматически сгенерированное связывание)
- Мост кодирует вызов в JSON (имя метода + аргументы)
- Маршрутизатор находит метод Go в зарегистрированных сервисах
- Метод Go выполняется и возвращает значение
- Мост декодирует результат и отправляет его обратно на фронтенд
- Promise разрешается в JavaScript с результатом
Характеристики производительности:
- В памяти: Нет накладных расходов сети, нет HTTP
- Zero-copy там, где это возможно (для больших данных)
- Асинхронно по умолчанию: Неблокирующе с обеих сторон
- Типобезопасно: Автоматически генерируются определения TypeScript
3. Система сервисов
Заголовок раздела «3. Система сервисов»Сервисы — это рекомендуемый способ экспорта функциональности Go на фронтенд.
// Define a service (just a regular Go struct)type GreetService struct { prefix string}
// Methods with exported names are automatically availablefunc (g *GreetService) Greet(name string) string { return g.prefix + name + "!"}
func (g *GreetService) GetTime() time.Time { return time.Now()}
// Register the serviceapp := application.New(application.Options{ Services: []application.Service{ application.NewService(&GreetService{prefix: "Hello, "}), },})Обнаружение сервисов:
- Wails сканирует вашу структуру при запуске
- Экспортируемые методы становятся доступными для вызова из фронтенда
- Информация о типах извлекается для связываний TypeScript
- Обработка ошибок автоматическая (ошибки Go → исключения JS)
Сгенерированное связывание TypeScript:
// Auto-generated in frontend/bindings/GreetService.tsexport function Greet(name: string): Promise<string>export function GetTime(): Promise<Date>Почему сервисы?
- Типобезопасность: Полная поддержка TypeScript
- Автообнаружение: Не требуется ручная регистрация методов
- Организованность: Группировка связанной функциональности
- Тестируемость: Сервисы — это обычные структуры Go
4. Система событий
Заголовок раздела «4. Система событий»События обеспечивают pub/sub коммуникацию между компонентами.
Сценарии использования:
- Коммуникация между окнами: Одно окно уведомляет другие
- Фоновые задачи: Сервис Go уведомляет UI о прогрессе
- Синхронизация состояния: Поддержание синхронности нескольких окон
- Слабая связанность: Компонентам не нужны прямые ссылки друг на друга
Пример:
// Go: Emit an eventapp.Event.Emit("user-logged-in", user)// JavaScript: Listen for eventimport { Events } from '@wailsio/runtime'
Events.On('user-logged-in', (user) => { console.log('User logged in:', user)})Жизненный цикл приложения
Заголовок раздела «Жизненный цикл приложения»Понимание жизненного цикла помогает знать, когда инициализировать ресурсы и очищать их.
Lifecycle hooks:
app := application.New(application.Options{ Name: "My App",
// Called before windows are created OnStartup: func(ctx context.Context) { // Initialise database, load config, etc. },
// Called when app is about to quit OnShutdown: func() { // Save state, close connections, etc. },})Build Process
Заголовок раздела «Build Process»Understanding how Wails builds your application:
Build steps:
-
Analyse Go code
- Scan services for exported methods
- Extract parameter and return types
- Generate method signatures
-
Generate TypeScript bindings
- Create
.tsfiles for each service - Include full type definitions
- Add JSDoc comments
- Create
-
Build frontend
- Run your bundler (Vite, webpack, etc.)
- Minify and optimise
- Output to
frontend/dist/
-
Compile Go
- Compile with optimisations (
-ldflags="-s -w") - Include build metadata
- Platform-specific compilation
- Compile with optimisations (
-
Embed assets
- Embed frontend files into Go binary
- Compress assets
- Create single executable
Result: A single native executable with everything embedded.
Development vs Production
Заголовок раздела «Development vs Production»Wails behaves differently in development and production:
Characteristics:
- Hot reload: Frontend changes reload instantly
- Source maps: Debug with original source
- DevTools: Browser DevTools available
- Logging: Verbose logging enabled
- External frontend: Served from dev server (Vite)
How it works:
Benefits:
- Instant feedback on changes
- Full debugging capabilities
- Faster iteration
Characteristics:
- Embedded assets: Frontend built into binary
- Optimised: Minified, compressed
- No DevTools: Disabled by default
- Minimal logging: Errors only
- Single file: Everything in one executable
How it works:
Benefits:
- Single file distribution
- Smaller size (minified)
- Better performance
- No external dependencies
Memory Model
Заголовок раздела «Memory Model»Understanding memory usage helps you build efficient applications.
Memory regions:
-
Go Heap
- Your services and application state
- Managed by Go garbage collector
- Typically 5-10MB for simple apps
-
WebView Memory
- DOM, JavaScript heap, CSS
- Managed by WebView’s engine
- Typically 10-20MB for simple apps
-
Bridge Memory
- Message buffers for communication
- Minimal overhead (<1MB)
- Zero-copy for large data where possible
Optimisation tips:
- Avoid large data transfers: Pass IDs, fetch details on demand
- Use events for updates: Don’t poll from frontend
- Stream large files: Don’t load entirely into memory
- Clean up listeners: Remove event listeners when done
Learn more about performance →
Security Model
Заголовок раздела «Security Model»Wails provides a secure-by-default architecture:
Security features:
-
Method whitelisting
- Only exported methods are callable
- Private methods are inaccessible
- Explicit service registration required
-
Type validation
- Arguments checked against Go types
- Invalid types rejected
- Prevents injection attacks
-
No eval()
- Frontend can’t execute arbitrary Go code
- Only predefined methods callable
- No dynamic code execution
-
Context isolation
- Each window has its own context
- Services can check caller context
- Permissions per window possible
Best practices:
- Validate user input in Go (don’t trust frontend)
- Use context for authentication/authorisation
- Sanitise file paths before file operations
- Rate limit expensive operations
Next Steps
Заголовок раздела «Next Steps»Application Lifecycle - Understand startup, shutdown, and lifecycle hooks
Learn More →
Go-Frontend Bridge - Deep dive into how the bridge works
Learn More →
Build System - Understand how Wails builds your application
Learn More →
Start Building - Apply what you’ve learned in a tutorial Tutorials →
Вопросы об архитектуре? Задавайте их в Discord или смотрите справочник API.