asticode / go-astilectron

Build cross platform GUI apps with GO and HTML/JS/CSS (powered by Electron)
MIT License
4.9k stars 344 forks source link

How to embed resources without bootstrap package ? #315

Closed nkoporec closed 3 years ago

nkoporec commented 3 years ago

I have a small application that has a one window. I have used the default go-astilectron without the bootstrap package and when running locally (using go run *.go) everything works as expected. When I compile using your bundler package then resources are not added to the output (only .exe, .dmg files are created), the end result is an application that shows a blank window. because it's missing all the html / css / js files.

I have searched the issues and every example is using the bootstrap package, so I'm wondering if this is a required step in order to embed resources ? Do I need to convert my existing code and use the bootstrap ?

Here is the astilectron part of my code:

l := log.New(log.Writer(), log.Prefix(), log.Flags())

gui.astilectronOptions = astilectron.Options{
  AppName:            "Ginker",
  BaseDirectoryPath:  "resources",
  AppIconDarwinPath:  "icon.ico",
  AppIconDefaultPath: "icon.png",
  SingleInstance:     true,
  }

// Set up astilectron.
ginker, err := astilectron.New(l, gui.astilectronOptions)
if err != nil {
  return nil, err
}
defer ginker.Close()
gui.Ginker = ginker

// Handle signals.
gui.Ginker.HandleSignals()

// Start the app
if err = gui.Ginker.Start(); err != nil {
  return nil, err
}

gui.windowOptions = astilectron.WindowOptions{
  Center: astikit.BoolPtr(true),
  Height: astikit.IntPtr(700),
  Width:  astikit.IntPtr(700),
}

// Create a new window.
if gui.window, err = gui.Ginker.NewWindow("resources/app/dist/index.html", &gui.windowOptions); err != nil {
  return nil, err
}

// Create windows
if err = gui.window.Create(); err != nil {
  return nil, err
}

// Create menus.
m := menuItems(gui.Ginker, gui.window)
m.Create()

// This will listen to messages sent by Javascript
gui.window.OnMessage(func(m *astilectron.EventMessage) interface{} {
  e := handleEvent(m)
  return e
})
asticode commented 3 years ago

You have 2 options :

I strongly recommend the 2nd option.

Bottom line is, if you want to use the bundler, you have to use the bootstrap in your project.

Luckily for you, it's not that complicated. Your project would look something like :

var (
    VersionAstilectron string
    VersionElectron    string
)

func main() {
    // Create logger
    l := log.New(log.Writer(), log.Prefix(), log.Flags())

    // Run bootstrap
    if err := bootstrap.Run(bootstrap.Options{
        Asset:    Asset,
        AssetDir: AssetDir,
        AstilectronOptions: astilectron.Options{
            AppName:            "Ginker",
            BaseDirectoryPath:  "resources",
            AppIconDarwinPath:  "icon.ico",
            AppIconDefaultPath: "icon.png",
            SingleInstance:     true,
        },
        Logger: l,
        MenuOptions: menuItems(),
        OnWait: func(_ *astilectron.Astilectron, ws []*astilectron.Window, _ *astilectron.Menu, _ *astilectron.Tray, _ *astilectron.Menu) error {
            // This will listen to messages sent by Javascript
            ws[0].OnMessage(func(m *astilectron.EventMessage) interface{} {
                e := handleEvent(m)
                return e
            })
            return nil
        },
        RestoreAssets: RestoreAssets,
        Windows: []*bootstrap.Window{{
            Homepage:      "resources/app/dist/index.html",
            MessageHandler: handleMessages,
            Options: &astilectron.WindowOptions{
                Center:          astikit.BoolPtr(true),
                Height:          astikit.IntPtr(700),
                Width:           astikit.IntPtr(700),
            },
        }},
    }); err != nil {
        l.Fatal(fmt.Errorf("running bootstrap failed: %w", err))
    }
}

At first, Asset, AssetDir and RestoreAssets will be unknown but once you run the bundler, they will be created.

You'll also have to adapt a bit menuItems and create handleMessages even if it does nothing.

Let me know if that answers your question.

nkoporec commented 3 years ago

Yes, thanks for the explanation and the code snippet.