indigo icon indicating copy to clipboard operation
indigo copied to clipboard

Need something better/faster than NPM installed Electron..

Open davesmith00000 opened this issue 1 year ago • 10 comments

Once upon a time, we just used a globally installed Electron, and all was good, because there was no delay caused by NPM checking that the local install was present and correct.

Except all wasn't well at all, because globally installed Electron instances have shockingly bad / unpredictable performance for reasons I've never really dug into.

So now we do the local install thing, and this slows down our ability to iterate quickly, and sometimes NPM just hangs.

Is there something else we can use? Is it time to revisit WebView or something? Or if we stay with Electron, how about bundling up known good versions in a Jar or something?

davesmith00000 avatar Oct 14 '23 08:10 davesmith00000

Help! I'm in danger of starting a new project (since this isn't really an Indigo specific thing, in fact.)

What do you get, if you combine:

Why... you have a hot reloading dev server!

Then what if you layer on, say, selective asset copying and processing as we have in Indigo?

Well now you've got a primitive bundler.

And what if, you strap a WebView to it?

Well, now you've got a crude electron/tauri replacement.

And what if, as well as (or instead of?) running standalone, you put it in a Mill/sbt plugin?

Now you've got a full Scala FE dev server built right into your normal dev flow... do you not?

And none of that needs NPM.

davesmith00000 avatar Oct 15 '23 08:10 davesmith00000

Here is the embarrassingly small amount of code needed for a simple static service using cask, that I used to run an indigo game from a subdir called site:

package app
object StaticFiles extends cask.MainRoutes {

  override def port: Int = 1234
  override def host: String = "localhost"

  @cask.get("/")
  def index() = {
    cask.Redirect("/indigo/index.html")
  }

  @cask.staticFiles("/indigo", headers = Seq("Cache-Control" -> "no-cache"))
  def staticFileRoutes() = "site/."

  initialize()
}

davesmith00000 avatar Oct 15 '23 08:10 davesmith00000

Some comments from a quick reading:

Step 1 (hot reloading dev server) sounds awesome. I would love to see something like that. I think some plugins like scalajs-bundler do that, but they need npm/webpack under the hood, and I would love to see something simpler.

Step 2 (primitive bundler) sounds OK to me, although I'm not sure if it's entirely necessary (you could always fetch the assets from the static server), but if it's already done, it's a nice extra.

Step 3 (Java WebView) is what I have more concerns. I didn't know about JavaFX WebView, and it's nice that it uses Webkit, but I wonder what's the JS engine (Nashorn, maybe?). I'm a bit worried that especially for Indigo there might be a weird mismatch with features like WebGL/WebGPU, or weird performance caveats compared to up to date browsers. It shouldn't be too hard to test this, though.

JD557 avatar Oct 15 '23 08:10 JD557

Help! I'm in danger of starting a new project (since this isn't really an Indigo specific thing, in fact.)

What do you get, if you combine:

Why... you have a hot reloading dev server!

Then what if you layer on, say, selective asset copying and processing as we have in Indigo?

Well now you've got a primitive bundler.

And what if, you strap a WebView to it?

Well, now you've got a crude electron/tauri replacement.

And what if, as well as (or instead of?) running standalone, you put it in a Mill/sbt plugin?

Now you've got a full Scala FE dev server built right into your normal dev flow... do you not?

And none of that needs NPM.

Hi think it is a very good idea and I was surprised this hasn't been done before by Laminar team or other SJS frontend. It would be very useful not only for Indigo but also Tyrian, Laminar etc...

And what if, you strap a WebView to it?

If I understand correctly, it would be JavaFX-based? This seems to be a good idea since we could eventually use all the JFX tools (like Gluon Native etc...) to package our app.

Also for your interest, someone made a working Scala Native/SJS project with Webview (I failed to find the repository again sadly).

Iltotore avatar Oct 15 '23 08:10 Iltotore

very useful not only for Indigo but also Tyrian, Laminar etc...

Yes indeed @Iltotore, I think it should be a separate project that is agnostic to what you're building or what tools you're using. I was also thinking how nice it would be for Tyrian to (optionally / by-default) be an NPM-less dev experience...

Step 3 (Java WebView) is what I have more concerns.

Yes to all of that @JD557, particularly the WebGL support concerns. However, as long as it has WebGL 2.0 support, even if it's sub-par to a full electron build, it might still be good for use during development, and then you package it up in something more sophisticated (and well supported) for publication. This is really all about a lovely, fast, responsive, hot loading, pure scala / scala-first, dev experience.

davesmith00000 avatar Oct 15 '23 09:10 davesmith00000

From @zetashift:

For the webview stuff, maybe this example https://github.com/keynmol/scalajs-tauri-example could be helpful

davesmith00000 avatar Oct 15 '23 12:10 davesmith00000

WebView isn't going to work well. There are two problems:

  1. WebGL isn't supported, so, yeah.
  2. It's immensely fiddly and platform specific.

On the other hand, the dev server part looks very doable.

davesmith00000 avatar Oct 21 '23 08:10 davesmith00000

Which "WebView" isn't going to work? The project or JavaFX's WebView?

Iltotore avatar Oct 21 '23 08:10 Iltotore

JavaFX / ScalaFX.

davesmith00000 avatar Oct 21 '23 08:10 davesmith00000

I have a workaround for this... (needs the next Indigo release i.e. > 0.15.2, due any day now) as long as you're a Nix flakes user. :stuck_out_tongue: (Well, it probably works for other set ups too, I'm just getting Nix to do it and haven't tried it any other way...)

Nix based global Electron installs are as bad as any other, I think I tried them in a flake too and they were also bad, as mentioned in the original message. However, what can do is add this to your nix flake hook (naturally I have yarn being installed in the flake too...):

       shellHook = ''
          yarn add --dev electron
          yarn install
        '';

This gives you a good, local electron accessible via npx. So then you update your game build's indigoOptions as follows:

.useElectronExecutable("npx electron")

...and hey presto, no more waiting for npm to check the install on every launch. Much faster.

davesmith00000 avatar Dec 30 '23 23:12 davesmith00000