mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 19:50:15 +08:00
Merge branch 'blog/v3-roadmap'
This commit is contained in:
commit
18d0ed890a
240
website/blog/2023-01-17-v3-roadmap.mdx
Normal file
240
website/blog/2023-01-17-v3-roadmap.mdx
Normal file
@ -0,0 +1,240 @@
|
||||
---
|
||||
slug: the-road-to-wails-v3
|
||||
title: The Road to Wails v3
|
||||
authors: [leaanthony]
|
||||
tags: [wails, v3]
|
||||
---
|
||||
|
||||
```mdx-code-block
|
||||
<div class="text--center">
|
||||
<img
|
||||
src={require("@site/static/img/blog/multiwindow.webp").default}
|
||||
width="90%"
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
```
|
||||
|
||||
# Introduction
|
||||
|
||||
Wails is a project that simplifies the ability to write cross-platform desktop applications using
|
||||
Go. It uses native webview components for the frontend (not embedded browsers), bringing the power
|
||||
of the world's most popular UI system to Go, whilst remaining lightweight.
|
||||
|
||||
Version 2 was released on the 22nd of September 2022 and brought with it a lot of enhancements
|
||||
including:
|
||||
|
||||
- Live development, leveraging the popular Vite project
|
||||
- Rich functionality for managing windows and creating menus
|
||||
- Microsoft's WebView2 component
|
||||
- Generation of Typescript models that mirror your Go structs
|
||||
- Creating of NSIS Installer
|
||||
- Obfuscated builds
|
||||
|
||||
Right now, Wails v2 provides powerful tooling for creating rich, cross-platform desktop
|
||||
applications.
|
||||
|
||||
This blog post aims to look at where the project is at right now and what we can improve
|
||||
on moving forward.
|
||||
|
||||
# Where are we now?
|
||||
|
||||
It's been incredible to see the popularity of Wails rising since the v2 release. I'm constantly
|
||||
amazed by the creativity of the community and the wonderful things that are being built with it.
|
||||
With more popularity, comes more eyes on the project. And with that, more feature requests and
|
||||
bug reports.
|
||||
|
||||
Over time, I've been able to identify some of the most pressing issues facing the project.
|
||||
I've also been able to identify some of the things that are holding the project back.
|
||||
|
||||
## Current issues
|
||||
|
||||
I've identified the following areas that I feel are holding the project back:
|
||||
|
||||
- The API
|
||||
- Bindings generation
|
||||
- The Build System
|
||||
|
||||
### The API
|
||||
|
||||
The API to build a Wails application currently consists of 2 parts:
|
||||
|
||||
- The Application API
|
||||
- The Runtime API
|
||||
|
||||
The Application API famously has only 1 function: `Run()` which takes a heap of
|
||||
options which govern how the application will work. Whilst this is very simple to use,
|
||||
it is also very limiting. It is a "declarative" approach which hides a lot of the
|
||||
underlying complexity. For instance, there is no handle to the main window, so you can't
|
||||
interact with it directly. For that, you need to use the Runtime API. This is a problem
|
||||
when you start to want to do more complex things like create multiple windows.
|
||||
|
||||
The Runtime API provides a lot of utility functions for the developer. This includes:
|
||||
|
||||
- Window management
|
||||
- Dialogs
|
||||
- Menus
|
||||
- Events
|
||||
- Logs
|
||||
|
||||
There are a number of things I am not happy with the Runtime API. The first is that it
|
||||
requires a "context" to be passed around. This is both frustrating and confusing for
|
||||
new developers who pass in a context and then get a runtime error.
|
||||
|
||||
The biggest issue with the Runtime API is that it was designed for applications that only
|
||||
use a single window. Over time, the demand for multiple windows has grown and the API is
|
||||
not well suited to this.
|
||||
|
||||
### Thoughts on the v3 API
|
||||
|
||||
Wouldn't it be great if we could do something like this?
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := wails.NewApplication(options.App{})
|
||||
myWindow := app.NewWindow(options.Window{})
|
||||
myWindow.SetTitle("My Window")
|
||||
myWindow.On(events.Window.Close, func() {
|
||||
app.Quit()
|
||||
})
|
||||
app.Run()
|
||||
}
|
||||
```
|
||||
|
||||
This programmatic approach is far more intuitive and allows the developer to interact
|
||||
with the application elements directly. All current runtime methods for windows would
|
||||
simply be methods on the window object. For the other runtime methods, we could move
|
||||
them to the application object like so:
|
||||
|
||||
```go
|
||||
app := wails.NewApplication(options.App{})
|
||||
app.NewInfoDialog(options.InfoDialog{})
|
||||
app.Log.Info("Hello World")
|
||||
```
|
||||
|
||||
This is a much more powerful API which will allow for more complex applications to be built.
|
||||
It also allows for the creation of multiple windows, [the most up-voted feature on GitHub](https://github.com/wailsapp/wails/issues/1480):
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := wails.NewApplication(options.App{})
|
||||
myWindow := app.NewWindow(options.Window{})
|
||||
myWindow.SetTitle("My Window")
|
||||
myWindow.On(events.Window.Close, func() {
|
||||
app.Quit()
|
||||
})
|
||||
myWindow2 := app.NewWindow(options.Window{})
|
||||
myWindow2.SetTitle("My Window 2")
|
||||
myWindow2.On(events.Window.Close, func() {
|
||||
app.Quit()
|
||||
})
|
||||
app.Run()
|
||||
}
|
||||
```
|
||||
|
||||
### Bindings generation
|
||||
|
||||
One of the key features of Wails is generating bindings for your Go methods so they may be
|
||||
called from Javascript. The current method for doing this is a bit of a hack. It involves
|
||||
building the application with a special flag and then running the resultant binary which
|
||||
uses reflection to determine what has been bound. This leads to a bit of a chicken and egg
|
||||
situation: You can't build the application without the bindings and you can't generate the
|
||||
bindings without building the application. There are many ways around this but the best one
|
||||
would be not to use this approach at all.
|
||||
|
||||
There was a number of attempts at writing a static analyser for Wails projects but they
|
||||
didn't get very far. In more recent times, it has become slightly easier to do this with
|
||||
more material available on the subject.
|
||||
|
||||
Compared to reflection, the AST approach is much faster however it is significantly more
|
||||
complicated. To start with, we may need to impose certain constraints on how to specify
|
||||
bindings in the code. The goal is to support the most common use cases and then expand
|
||||
it later on.
|
||||
|
||||
### The Build System
|
||||
|
||||
Like the declarative approach to the API, the build system was created to hide the
|
||||
complexities of building a desktop application. When you run `wails build`, it does a
|
||||
lot of things behind the scenes:
|
||||
- Builds the backend binary for bindings and generates the bindings
|
||||
- Installs the frontend dependencies
|
||||
- Builds the frontend assets
|
||||
- Determines if the application icon is present and if so, embeds it
|
||||
- Builds the final binary
|
||||
- If the build is for `darwin/universal` it builds 2 binaries, one for `darwin/amd64` and one for `darwin/arm64` and then creates a fat binary using `lipo`
|
||||
- If compression is required, it compresses the binary with UPX
|
||||
- Determines if this binary is to be packaged and if so:
|
||||
- Ensures the icon and application manifest are compiled into the binary (Windows)
|
||||
- Builds out the application bundle, generates the icon bundle and copies it, the binary and Info.plist to the application bundle (Mac)
|
||||
- If an NSIS installer is required, it builds it
|
||||
|
||||
This entire process, whilst very powerful, is also very opaque. It is very difficult to
|
||||
customise it and it is very difficult to debug.
|
||||
|
||||
To address this in v3, I would like to move to a build system that exists outside of Wails.
|
||||
After using [Task](https://taskfile.dev/) for a while, I am a big fan of it. It is a great
|
||||
tool for configuring build systems and should be reasonably familiar to anyone who has used
|
||||
Makefiles.
|
||||
|
||||
The build system would be configured using a `Taskfile.yml` file which would be generated
|
||||
by default with any of the supported templates. This would have all of the steps required
|
||||
to do all the current tasks, such as building or packaging the application, allowing for
|
||||
easy customisation.
|
||||
|
||||
There will be no external requirement for this tooling as it would form part of the Wails
|
||||
CLI. This means that you can still use `wails build` and it will do all the things it does
|
||||
today. However, if you want to customise the build process, you can do so by editing the
|
||||
`Taskfile.yml` file. It also means you can easily understand the build steps and use your
|
||||
own build system if you wish.
|
||||
|
||||
The missing piece in the build puzzle is the atomic operations in the build process, such
|
||||
as icon generation, compression and packaging. To require a bunch of external tooling would
|
||||
not be a great experience for the developer. To address this, the Wails CLI will provide
|
||||
all these capabilities as part of the CLI. This means that the builds still work as expected,
|
||||
with no extra external tooling, however you can replace any step of the build with any tool
|
||||
you like.
|
||||
|
||||
This will be a much more transparent build system which will allow for easier customisation
|
||||
and address a lot of the issues that have been raised around it.
|
||||
|
||||
## The Payoff
|
||||
|
||||
These positive changes will be a huge benefit to the project:
|
||||
- The new API will be much more intuitive and will allow for more complex applications
|
||||
to be built.
|
||||
- Using static analysis for bindings generation will be much faster and reduce a lot
|
||||
of the complexity around the current process.
|
||||
- Using an established, external build system will make the build process completely
|
||||
transparent, allowing for powerful customisation.
|
||||
|
||||
Benefits to the project maintainers are:
|
||||
|
||||
- The new API will be much easier to maintain and adapt to new features and platforms.
|
||||
- The new build system will be much easier to maintain and extend. I hope this will lead to a new ecosystem of community driven build pipelines.
|
||||
- Better separation of concerns within the project. This will make it easier to add new features and platforms.
|
||||
|
||||
## The Plan
|
||||
|
||||
A lot of the experimentation for this has already been done and it's looking good.
|
||||
There is no current timeline for this work but I'm hoping by the end of Q1 2023, there
|
||||
will be an alpha release for Mac to allow the community to test, experiment with and
|
||||
provide feedback.
|
||||
|
||||
## Summary
|
||||
|
||||
- The v2 API is declarative, hides a lot from the developer and not suitable for features such as multiple windows. A new API will be created which will be simpler, intuitive and more powerful.
|
||||
- The build system is opaque and difficult to customise so we will move to an external build system which will open it all up.
|
||||
- The bindings generation is slow and complex so we will move to static analysis which will remove a lot of the complexity the current method has.
|
||||
|
||||
There has been a lot of work put into the guts of v2 and it's solid.
|
||||
It's now time to address the layer on top of it and make it a much better experience for the developer.
|
||||
|
||||
I hope you are as excited about this as I am. I'm looking forward to hearing your thoughts and feedback.
|
||||
|
||||
Regards,
|
||||
|
||||
‐ Lea
|
||||
|
||||
PS: If you or your company find Wails useful, please consider [sponsoring the project](https://github.com/sponsors/leaanthony). Thanks!
|
||||
|
||||
PPS: Yes, that's a genuine screenshot of a multi-window application built with Wails. It's not a mockup. It's real. It's awesome. It's coming soon.
|
BIN
website/static/img/blog/multiwindow.webp
Normal file
BIN
website/static/img/blog/multiwindow.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 269 KiB |
Loading…
Reference in New Issue
Block a user