Introduction
Well, hello! Today is good day, which means it's time for a interesting story for your project this week! 😅 Alright, without too much foreplay, let's get started.
📝 Table of contents
- What have we got yet?
- What's to be done?
- Trials and errors
- Golang way
- What's next?
- Questions
- Exercises
What have we got yet?
Let's imagine, that we already have a well working SPA web application in production. Let it be a simple service for listening to podcasts on all kinds of development topics. And your client is satisfied...
💥 One day, your client comes to you and asks you to develop a native version of his website for macOS, Windows 10 and Ubuntu Linux. But web app have frontend on Svelte, which successful works with REST API, based on Fiber.
— What's Fiber? 😐
Fiber is a web framework that was inspired by Express.js and based on Fasthttp, the fastest HTTP engine written on Go. The framework was designed to simplify the process of fast development of high-performance web applications with zero memory allocation.
If you interested, please go to Fiber documentation, repository or my own introduction article for more details!
Yeah, maybe a little unrealistic situation, but we're still dreaming! 😁
What's to be done?
✅ App must run in its own system window.
✅ App must support for all media keys on keyboard.
✅ There must be a single code base with web version of app.
✅ Development and maintenance of app should not take too long time.
Trials and errors
Yep, you may take something, like Electron, but this will broke 3 and 4 rules above and will mean, that you'll have to translate all entire code base of your SPA (remember, already working in the production) to Electron.
If we developed our web app from scratch, this approach would be one of the best, but we have what we have. Such an approach would be longer and more expensive, than described below.
Golang way
As you might have known from my previous article, Go has a good package for displaying web pages zserge/webview. Also, we will need a tool to cross-compiling for all necessary operating systems — XGO (karalabe/xgo).
So, here's what we need to do 👇
- Install packages:
$ go get -u github.com/zserge/webview
$ go get -u github.com/karalabe/xgo
- Write simple Go code:
package main
import "github.com/zserge/webview"
func main() {
// Define webview settings
settings := webview.Settings{
Title: "SPA Desktop App", // title for window
URL: "https://example.com", // open URL
Width: 1280, // window width (px)
Height: 720, // window height (px)
Resizable: true, // enable resize window
Debug: false, // disable debug
}
// Create new webview app with settings
window := webview.New(settings)
// Run webview app
window.Run()
}
- Compile desktop app for Windows 10 to
./build
folder:
$ xgo -out ./build/spa_desktop \
-ldflags="-H windowsgui" \
--targets=windows-10/amd64 \
github.com/user/spa-desktop-app
- Compile desktop app for Linux and macOS to
./build
folder:
$ xgo -out ./build/spa_desktop \
--targets=linux/amd64,darwin/amd64 \
github.com/user/spa-desktop-app
⚠️ All compiled for 64-bit systems.
Hint for macOS
How to prepare files for .app
file, I have already told in this article. For shipping your desktop app to macOS users in usual manner (drag'n'drop installer on .dmg
format), we can use node-appdmg
:
LinusU / node-appdmg
💾 Generate your app dmgs
I like this Node.js library, because it have simple install and understandable configuration. If you have some design skills, result may be something like this:
Windows 10 problem
For a visual demonstration problem, I'll use my own Yandex.Music Desktop:
koddr / yandex-music-desktop
🎵 Yandex.Music Desktop (un-official port of website). Please note: this is only webview port of Yandex.Music website as desktop app for macOS, Windows 10 and GNU/Linux!
So, desktop app build this way always running from the default OS webview layer. That means, if you removed Edge browser — webview layer will be Internet Explorer 11 and not Chrome (FireFox, Opera, etc.), because it's third-party software for Windows!
I check it from my test-stand with Windows 10 Pro x64 (version 1903, OS build 18362.535). On screenshot below (from left to right):
Yandex.Music Desktop app, Internet Explorer 11, MS Edge 18 👇
How to solve this?
I have no answer to that question... Therefore, the best option is to warn, that service will not work, if Edge browser is not on the user's system.
You can set up a message, if catch User-Agent like this:
Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
What's next?
I advise you to experiment with this knowledge. For example, in the direction of porting your favorite websites in native apps as the same way. 👍
Questions
- What is happen with app window, when you change
webview.Settings.Resizable
tofalse
on your Go app? - How to disguise a Windows 10 problem by Golang (hint: use HTTP headers and make redirect to
ie-block.html
page, if IE detected)?
Exercises
- Build your Go app to other OS (and arch), using
XGO
package. - Solve a Windows 10 (Internet Explorer) problem, by catch
UserAgent
by JavaScript or Go (hint: see above hint).
Photo by
[Title] Med Badr Chemmaoui https://unsplash.com/photos/ZSPBhokqDMc
[1, 2] Somewhere from Google Search 🤷️
[3, 4] Vic Shóstak https://github.com/koddr/yandex-music-desktop
P.S.
If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻
❗️ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.
And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!
My main projects that need your help (and stars) 👇
- 🔥 gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
- ✨ create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
Top comments (2)
You can put web server (of any programming languages) inside Electron too. If not Node-based server, you will need to both
spawn
on start andkill
on exit.polvcode.dev/post/2019/07/electron...
I do know one thing that is impossible for Electron, though. You cannot opt out bundling of Chromium.
Thx for comment and link 😉