So I'm writing a new template, which will use a tool called leiningen to have a clojurescript template, using reagent (clojurescript bindings to react)
I was just wondering what tips I might have before embarking. It seems I make a minimum root project directory, but add a whole frontend/ directory as created exactly by the tool from its own templates, is that right? Or can I invoke lein from wails init?
I also imagine I need to bind to certain wails javascript libraries?
for the binding please have a look at the existing implementations https://github.com/wailsapp/wails/blob/develop/cmd/templates/create-react-app/frontend/src/index.js
https://github.com/wailsapp/wails/blob/develop/cmd/templates/angular-template/frontend/src/main.ts
https://github.com/wailsapp/wails/blob/develop/cmd/templates/vuebasic/frontend/src/main.js
wails needs two files, a javascript and a css inside a div with id app.
for the general anatomy of a template see https://github.com/wailsapp/wails/tree/develop/cmd/templates
Hey @Vaelatern, that's a cool idea. Templates are super flexible and can be whatever you want them to be. The main thing to consider is what is in metadata.json. This contains the commands run by wails init, build and serve. Obviously.more goes on that just those commands but they are the hooks.
The most complete example of template.json is the Angular one.
Let is know.if we can help you. Cheers.
Can I run a command to create the template? Or is the only option copying in the template folder?
Additionally, while I can get javascript to be served by a dedicated server, I don't know how to also plug in wails support. Is wails support plugged in entirely by javascript imported during the build?
you can do it via command line, although I don't ever use it, I just copy/paste the boilerplate and take for there.
take the react template as an example
wails expects a js and a css file.
func main() {
js := mewn.String("./frontend/build/static/js/main.js")
css := mewn.String("./frontend/build/static/css/main.css")
and if you take a closer look here js needs to have a div called 'app'
Wails.Init(() => {
ReactDOM.render(<App />, document.getElementById('app'));
});
Not sure if this got documented but if you build a custom wails binary with a "dev" tag then there's a template generator. It's pretty old though bit might be helpful?
I mean can I have wails run the script for me at init time. Seems the answer is no.
please explain what do u mean cause I got confused 馃槙
@Vaelatern Currently it can generate from any template that exists in this directory. Feel free to either add your template there manually or use the dev newtemplate command to make one for you. That template may be a bit old now (I'm sure it doesn't have the external runtime library) but should basically work.
If you want your template to be an official template and included in the project, please create a PR when it works 馃憤 As stated previously, we will be adding remote templates hopefully before v1.
I mean that when a template is used, not created, a script is run. As in, when I use wails init, not before then. This would save me adding unnecessary templating to whatever I want to put in templates/
now I got more confused tbh :smile:
The Wails cli has developer tooling built in, but needs activating. To create a developer version, do the following:
cd cmd/wails
go install --tags=dev
This unlocks a wails dev command that has subcommands for development.
#Creating new project templates
With a developer enabled cli, you can run 'wails dev newtemplate' to create a new project template. You will be asked a number of questions regarding your template and as a result, a new directory will be created in <project-root>/cmd/templates.
So, commands get run by you the developer, yes? Things like ls, cd etc. wails init is such a command.
To start a new leinginen project you run lein new . Instead of me running lein new on my system, I want to run it on the user's system, by having Wails run it.
Can I?
first of all I am 100% unfamiliar with clojure or leinginen.
if it was JS something like angular's cli (see how we dealt with it here) (or create-react-app or create-nuxt-app etc) could apply.
but if u need lein new to run, it is going to be a two step process, which I think is fine (!). It is just a matter of documentation though. Even if there were 3 or 4 steps, as long as the documentation is solid I think is fine.
Although I can see potential uses of wails being able to exec/run commands after wails init.
I can PR the support to run a template script if you like. I've run commands from other golang projects.
It sounds like you want to mainly use lein to do the actual projects and bolt Wails around it. Our current model is to dump out known working versions of templates and let people customise as they need. 'Outsourcing' the template generation could lead to a lot of support headaches so we probably wouldn't support that directly. However, if you really wanted to do this, you have the freedom to call what you like via the "install" and "build" values. Wails init will first call the "install" script, then, if successful, the "build" script. So you could have a template that is basically bare, but with a couple of scripts to "init + install" and then "build".
Are these the hooks you're looking for?
Install and build are used after the template is created, isn't that the case?
I'm looking for a oneshot creation, does install offer this? A creation script that's never called again?
Not directly. I was inferring that whatever you called for install could do that. I think it's something we could look at but I think probably in the context of remote templates. Mainly because issues with those tools shouldn't be flooding this project, which is the danger. I'm open to it, just needs some more thought and discussion.
I'm afraid I'm a bit of a javascript novice.
When wails projects have an npm dependency on @wailsapp/runtime, what does that mean? Specifically, why the @ sign? Special characters escape google, sadly.
What javascript must be called from my template? Must I begin my app with a Wails.Init() call?
That's the runtime library for the frontend. The @ just indicates the username. Your frontend can be Clojurescript. Just make sure you import the runtime and call the Init() function like the other templates. The callback to this is called when the runtime is ready.
Made progress: got it working! Now to get a minimal example working too.
Is there any reason wails serve should render the website and connect to wails, but a wails binary with wails build doesn't? Should I confirm my invocation of Wails.Init(()=>{})? I know it's at least in theory being called, because it works on wails serve. It seems when I inspect source that the javascript (source a total of 390892 bytes) is clipped short (there is an ellipsis at the end).
Hmmmm.... that's weird. Do you think it's a webpack thing? Do you have a link to your source you can share so I can debug it?
I'm trying to turn it into a reasonable template with the same CSS for the rotating image so I can demonstrate in a simple way. Also properly debug.
Let me know if I can help in any way.
Yeah, the default background, that's just done with CSS? I don't have to find any javascript doing weird magic?
Indeed! Simply CSS.
Ah. When I do a wails build, the wails connector doesn't get injected. window.wails never gets defined. (Though that may be unrelated).
But when I wails serve, the wails connector works great.
Relatedly, the binary (wails build) has connected in the past to a frontend left over from a previous run (wails serve).
Working on that minimum example still to get something tangible for debugging that isn't crazy long.
I think the problem is that your binary app isn't injected "wailsbridge.prod.js" properly and wails connector show up in build mode...
see there
https://github.com/wailsapp/wails/blob/7dd42f964b4998323668a17cddd64ecd11a67190/cmd/helpers.go#L276
Hm, that could well be. The deal with clojurescript is it doesn't use a traditional npm build, so things that only function within NPM normally will not necessarily do so here.
Still working on this though.
@Vaelatern can you show me the result of below command?
we have to check versions of wails.
wails version
cat go.mod|grep wails
0.17.15-pre right now.
data:text/html,%3C%21DOCTYPE%20html%3E%0A%3Chtml%20lang=%22en%22%3E%0A%3Chead%3E%3Cmeta%20charset=%22utf-8%22%3E%3Cmeta%20http-equiv=%22IE=edge%22%20content=%22IE=edge%22%3E%3C%2Fhead%3E%0A%3Cbody%3E%3Cdiv%20id=%22app%22%3E%3C%2Fdiv%3E%3Cscript%20type=%22text%2Fjavascript%22%3E%3C%2Fscript%3E%3C%2Fbody%3E%0A%3C%2Fhtml%3E:863:476: CONSOLE ERROR TypeError: undefined is not an object (evaluating 'window.he.Ld')
That's probably the closure compiler (Google Closure) munging the name, so yes window.wails I suppose became window.he
@Vaelatern any progress? Is there anything I can help with? I'm closing a lot of tickets temporarily whilst we go into feature freeze and will re-open post v1. Listing on the https://github.com/wailsapp/wails/wiki/Post-V1-Enhancements page.
Most helpful comment
Made progress: got it working! Now to get a minimal example working too.