marcomq / nimview

A Nim/Webview based helper to create Desktop/Server applications with Nim/C/C++ and HTML/CSS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build to single file binary

marcomq opened this issue · comments

It would be cool to just have a single executable binary that can be placed just anywhere.
Maybe it ist possible to add something like https://www.npmjs.com/package/html-inline or (better) https://github.com/remy/inliner

implemented for the current main, but there are 2 new security alerts... Maybe need to switch to more lightweight https://github.com/shff/parcel-plugin-inliner

The best solution would probably be to just include css and images and find some debuggable solution for javascript. It is currently hard to trace a bug, as the javascript file was changed and the .map files do not map anymore.

EDIT: Might have missunderstood the problem at hand here. This may not work since javascript files need to be imported from html... But your proposals with inlining the css and js into the html might work together with this approach.

Would an approach like nimassets work?

It copies all assetfiles (such as html, css and javascript), encodes it in base64 and puts it inside a assets.nim file with a table where the key is the path to the assetfile. That way, all assets are built into the final binary.

Thx. Sounds great!
Maybe it is possible to add the whole "dist" folder. By this, the js and css would be in separate files and would still be debuggable.
It currently might take some time, but I will have a look at it.

I actually tried the nimassets approach and while it did bundle everything, I was also getting above the page "error opening the file" then path to file.

Beneath that, the correctly rendered index.html

Then below that "No such file or directory"

Thoughts? I like the approach of nimassets since I tend to do my frontend work in vanilla html/css/js, so I would rather not deal with npm and the like if possible.

@wwderw

Thx for trying out :) But no idea why this might happen. Haven't seen something like this yet.
Not sure if I have time to check your issue, but I would be interested how you solved this with nimassets. Maybe this is working better in the long term than my current approach.

You can also name the file "../dist/inlined.html" if you have a single page static webpage.
Edit: But sure - if you have some css & js and don't want to use npm, nimassets might be a better solution.

Current status of this feature:

It already is possible to compile to a single executable binary. Check the readme for this.
The page "../dist/inlined.html" will be compiled into the executable binary if it exists.

You may need an "inliner" if you have some external references as there is no automated scanning for external references.

I haven't figured out when it seems to do that with nimassets with essentially just an h1 opening and closing and text in between it and the usual html boiler. No inline css or js. Pure html

If I were to have inline css/js and have embed svg (I was seeing if I could get around external dependencies with inline svg where I wanted custom images. Using nimassets, I only get "error opening file" then the path (which actually doesn't take the directory and the html file, it stops at the root path as if the html file was in the root folder).

If I do it where nothing is embedded it works, which isn't ideal or if I do it to where the entire page is in a variable and then I have it write to a temp html file while the program is running that works, but again not ideal.

Trying the inline method(../dist/inlined.html method that is), I just get a blank page. So I don't know if I have the file structure and everything in the main.nim file done correctly and I'm not getting any error in compilation or in webview's debug window. I don't know if it's due to the embedded svg info (I can't imagine why as that is valid html, unless there is some limit as to how big the file can be when it's embedded) or I'm doing something incorrect.

Thoughts?

I did just a simple, no frills inlined html that has just a button with click me (no JS at all, just the button and boilerplate).

When I go to release mode I get on top of the rendered window:

PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9IklFPWVkZ2UiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiPgogICAgPHRpdGxlPlRlc3Q8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5PgogICAgPGJ1dHRvbj5DbGljayBNZTwvYnV0dG9uPgo8L2JvZHk+CjwvaHRtbD4=

However, when I do debug release and use index.html version of the same page it works.

Is it converting it to base64 like nimassets and needs to be decoded? The first part of that line looks like it does going through nim assets in the resulting nim file that that module generates.

Ok, so nimassets works flawlessly if write everything to a file before use. I don't know if nimview can handle everything being pulled directly from memory or if it all has to be written to a file first and then used.

In my other thread, you mentioned that it shares code with the Go framework Wails, so I checked out a program that I have for flashing my keyboard firmware that is written in Go and uses Wails. I noticed that it used the build embed functionality of Go, so I'm sure that contributes to the difference of outcome, but when they embed, I hadn't found a place where it writes the files temporarily to anywhere that I'm used to temp files being written (.config, .local, /tmp etc). So I do think it is possible and it actually still may be possible as everything is now, I'm just not able to muddle through it (problem with just having enough knowledge to cause damage). Ideally, I think that is the behavior that we would want, but that could just be me.

Anyway, it does appear that there is some viability with nimassets as it did handle frontend files, audio files and images fine. Just at this point, have to go through the step of writing everything to a file first and then using the assets, can't pull directly from memory.