What is the current golden standard for writing a ...
# javascript
m
What is the current golden standard for writing a js frontend plus jvm backend multiplatform project. I'm quite new to this (coming from kmm) and different examples and frameworks I find seem to do a lot of very specific magic in gradle. What I'm looking for is a basic solution where I build bsckend and frontend swparately and the generated js files (and html and other static) are then accessible for the backend app (because it handles the routing). Is this the right approach at all or should I have a separate apps with separate routing for frontend (with html/css/js views) and backend (with rest/json views)
r
It depends on what backend server you want to use. You can find different examples for different backends in the KVision examples repository: https://github.com/rjaros/kvision-examples
m
I wrote parts of the backend first with ktor and then tried to add frontend to it. And even tried with kvision which looks pretty neat on the frontend side, but the fullstack docs seem to focus on an integrated app and I want kvision just for the frontend. Couldn't make it work yet, though. Not sure how to expose the generated js stuff to the running backend
I guess I'm asking for general patterns more than ready to use recipes
b
Kotlin js app is just a static js app in the end. Copy that to your server's classpath and serve them as any other static resource
In the example above focus on how js module output is made available for both, jar and run tasks on the server and how ktor is configured to serve them from the classpath
🙏 1
m
So just a gradle script that moves js files around and that's the way to go? Sounds fine, I'll try that, thank you :)
k
How about the approach having one project with: • Gradle module for backend • Gradle module for Frontend Gradle module for API - Rest (websockets, or other) API to intergrate both modules and have possibility to integrate with other apps? For the Frontend part I started looking into Kotlin wrapper for React, but have not explored it to the extent I would feel comfortable using it for big, commercial projects. Anyone having opinion on it, maybe?
b
My example above does almost exactly that. FE is a standalone module which gets added on backend classpath during local runs and packaged into the fat-jar during builds. That way you can deploy your FE as standalone or just have BE serve it. KAMP is utilising both • kamp.petuska.dev - standalone FE • kamp.azurewebsites.net - embedded and served from BE
With that, you can think of your entire FE as a static file bundle that does not impose any opinion on how it should be deployed. It also does not have to be kotlin.js based. You could just as easily embed TS/JS app into your fat-jar with the same strategy.
1
If you're unsure how to make it work for your particular project, DM me and we can discuss. Happy to help.
m
@Big Chungus what should be the result of this? I created something similar and imagined that when I
run
, I'd get my frontend files copied to the backend build folder or sth like that. But first of all, the
jar
is not called during
run
. And when I call
jar
, the
jsBrowserDistribution
is run properly and it creates a
distribution
folder which contains the necessary files, but it's all in the
frontend/build
. And I don't think these files are now accessible by the backend app (should be under sth like
{{base_url}}/WEB-INF/index.html
, right?)
b
The idea for run task is to make frontend optional to avoid builds. That's why it's not copied anywhere in the example, but instead frontend app is simply added to the run task classpath. That way you can choose when you want to build a frontend and when you just want to run the backend
Once static files are on the classpath, it's up to you to mount them on whatever endpoint you wish by ktor or any other server framework. Browse through linked repo for setup example to see how everything ties together.
m
So I guess my problem is that I can't reference (mount) them from ktor or they are not on the classpath. Had to apply some modifications, though, so maybe messed sth up :)
b
Make sure you prebuild js module and mount resources via correct path
m
thank @Big Chungus, your code helped me a lot 🙂 and the last missing piece for me was properly referencing the directories from frontend app -
Copy code
distribution { directory = buildDir.resolve("dist/js/WEB-INF") }
b
Glad to hear you've got it sorted