https://kotlinlang.org logo
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
benchmarks
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
confetti
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
lincheck
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by
Title
m

moltendorf

08/21/2022, 3:18 PM
Hi there, I've been working on building libraries and getting to providing/using them via implementation() calls; however in this final case the "dependency" is a Kotlin/JS project and I want to serve it using Ktor (Kotlin/Jvm; i.e. this dependency belongs in resources kinda?) Not sure how to use it as that instead of "code" (the library doesn't even show up in the build/ directory so I can't manually copy it even?)
b

Big Chungus

08/21/2022, 4:44 PM
You cannot "serve" kjs dependency as it's just a compile-time entity. You'd need to gave a js module that compiles and exports the dependency as a js file
petuska.dev/kamp sounds like a good example if I understand your use-case correctly
The website (client) is also a kjs app and is embedded and served via ktor server
To recap, kjs dependency is not the same as web jar
m

moltendorf

08/21/2022, 4:51 PM
Sorry I'm not that advanced in a sense that I've used web jars before. I'm really coming from PHP - 10 years gap - Some Minecraft - At the moment I'm setting up a TeamCity server (among other things I've not used nor had before); and I am attempting to assemble a docker container to serve my ktor server (serving static files built by another teamcity build) behind nginx. I can really assemble this any-which-way I suppose but I was looking for a clean solution that was maybe directly in the gradle build scripts for pulling the files from an ivy repository (teamcity server); in there I can serve the .klib, the .jar, the .js, etc files; and sticking those directly into the resources (for serving with /static) I'll study that project in a moment I'm a bit adhd in which there's a thousand moving parts I'm attempting to roll forward here simultaneously ^^
b

Big Chungus

08/21/2022, 4:52 PM
Have a look at kamp I've linked. It's fully managed by gradle and just running build command produces a fully self-contained server with embedded web client
m

moltendorf

08/21/2022, 4:55 PM
b

Big Chungus

08/21/2022, 5:06 PM
Yep
jsMain is client, jvmMain is server
m

moltendorf

08/21/2022, 5:06 PM
Oh I see you put them together in one repository? Another solution I suppose.
Didn't think of the simplicity of a git subproject actually perhaps.
My main issue stems from I'm not as advanced at gradle so I couldn't get a final multiplatform project to build correctly with all my subprojects (of which some built correctly fine as a multiplatform library). I additionally wanted the common code I share between 'jsMain' and 'jvmMain' to be in its own libraries to be importable into other projects anyway (I have multiple frontends and backends) so I decided to go with my naivety and split the projects up since that also seemed easier anyway.
b

Big Chungus

08/21/2022, 5:14 PM
Nothing stops you from doing that in monorepo
m

moltendorf

08/21/2022, 5:14 PM
Also clicking build on such a final multiplatform project is like ~4 minutes for me oof.
(for hello world)
b

Big Chungus

08/21/2022, 5:15 PM
Same project, but modular structure for client/server https://github.com/mpetuska/kamp
Also clicking build on such a final multiplatform project is like ~4 minutes for me oof. Don't click build then, use proper gradle commands for the modules that you actually want to build
i.e. instead of doing "gradlew build" to build all modules, do "gradlew :client:build" to only build the "client" module
Gradle module dependencies are treated almost the same as external maven dependencies in a multi-module project (except that they're built on demand)
m

moltendorf

08/21/2022, 5:18 PM
I suppose. ^^. Again I prefer systems to work with 'defaults' wherever possible. I'm just looking for the best possible way to get there as I don't want to have to convey this information to the next engineer. I appreciate all the options and even if it's not what I want to use it always helps to hear them out (I might use them anyway).
b

Big Chungus

08/21/2022, 5:19 PM
Using module dependencies is the "default" approach in the ecosystem tbh. No hassle required to publish unnecessary artefacts. But to each its own.
m

moltendorf

08/21/2022, 5:27 PM
I feel we may have a conflict in terminology or understanding. I may use this solution as it does have its advantages but right now I don't have any common code shared between client a & server a that isn't also shared between client b & server b ... i mean perhaps client b and server b could grab client a/server a's library directly? it just seems weird when they're lopping off the actual front end and back end
b

Big Chungus

08/21/2022, 5:30 PM
No issues with that too, you can choose to have all servers in the same monorepo or have only the server that serves your client together with the client code. Common code can then be either ingested as gradle module dependency and also published for other repos or be in it's own repo and published.
m

moltendorf

08/21/2022, 5:31 PM
ultimately i may be pulling from all solutions because it appears industry standards don't work here; this product is entirely unique; down to the physics engine and email distribution 😛
b

Big Chungus

08/21/2022, 5:31 PM
Key point here is to have common code module to declare all targets you plan on consuming it from
Your go-to should be to have as much stuff in a gradle multimodule project and only selectively publish some modules for remote repos where you cannot avoid it.
IMHO*
m

moltendorf

08/21/2022, 5:35 PM
I guess this is what you mean by monorepo?
b

Big Chungus

08/21/2022, 5:36 PM
Monorepo is a git repo that has multiple projects inside. Gradle multimodule project is more specific version of that specifically focussed on gradle tooling to manage it.
m

moltendorf

08/21/2022, 5:43 PM
Ah ignore monorepo I guess; see I don't want to do that (the multimodule project) for the bulk of my development. I want everything to be broken up as much as possible in small targeted projects which I publish on my repo. So like basically I'm following your advice but flip one word. I selectively publish to remote repos but only for other people. I cannot avoid publishing code in private repositories anymore to make sure I distribute code securely and since I'm doing this all 'privately' and don't want to hit limits of teamcity, dockerhub, etc, anyway... Well it's become a writer's block to also not be able to endlessly publish miniature modules that can then be selectively included across projects... So with the private servers I've opted to publish as much to repositories but I guess that's because I don't view them as remote...
idk if I can expose much of /why/ everything must be in micromodules to the point where 2 products are built from a thousand modules ... that's where I'm nda
b

Big Chungus

08/21/2022, 5:56 PM
In that case you can still have your kjs client in a separate repo, but build it into js and publish that as a webjar
Then you can simply add it to your server dependencies and load/serve your kjs app from resources
Simmilar strategy to kamp with an extra step of packaging and publishing js output as a jar
m

moltendorf

08/21/2022, 5:58 PM
I mean like ... with the way my cdn caching is I could just literally link to it from the ivy repository ... like not even in the gradle script just the index {} I serve from ktor would be an actual https:// link.
b

Big Chungus

08/21/2022, 5:59 PM
FYI: webjar is just a jar that has only resources (usually js, html and css)
With cdn it would result in redirection. Some might not want that.
m

moltendorf

08/21/2022, 5:59 PM
It's actually all possible behind the same domain with my setup
b

Big Chungus

08/21/2022, 6:00 PM
But in general, most people just host kjs apps on cdn as standalone
You don't win much by having your server serve the app anyways since you're not doing ssr/ssg
kamp is actually hosted in both modes kamp.azurewebsites.net is served by ktor, whereas kamp.petuska.dev is hosted as a standalone webapp
I have it served by the ktor server as a fallback in case cdn fails
A bit redundant, i know... 😀
m

moltendorf

08/21/2022, 6:06 PM
um -- well yeah the ktor setup is more just extra steps I could concise this all and just use webpack in the kotlin/js build... but I do plan to do ssg eventually... and even without ssg, ktor is useful since there's lots of apis I plan to build here?
b

Big Chungus

08/21/2022, 6:08 PM
I'm not arguing that ktor is not useful. We're discussing how to serve your client here to which I recommend standalone cdn hosting
m

moltendorf

08/21/2022, 6:08 PM
Although for a proper API I plan to have a standalone ktor for that that doesn't even deal with static resources maybe
b

Big Chungus

08/21/2022, 6:08 PM
Also you can only build SPAs with kotlin.js for now. If you plan to do ssg, use ktor plus kotlinx.html
m

moltendorf

08/21/2022, 6:09 PM
For now I -- guess I could just make the ktor setup all about the API no serving of content directly
For the content I'll just do nginx rewrites onto the teamcity literally ... since the 'production' build step is to actually do cloudflare pages (this is the dev setup we're talking about; but it needs to be semi-production-like so containers/etc)
well i don't think you directly solved my problem but thanks for talking it solved my problem 🙂
b

Big Chungus

08/21/2022, 6:13 PM
Either way you got it resolved 😀
m

moltendorf

08/21/2022, 6:14 PM
you said 'we're just talking about serving your content here' and it refocused me a bit I was like yeah ... ktor isn't going to serve my content period it's cloudflare pages ... why am I making ktor serve it for development purposes?
b

Big Chungus

08/21/2022, 6:15 PM
Ah yes, we all get "boxed" in your inital ideas sometimes. Always good to get a second opinion to talk it through even if the other party is spitting out nonsense.
Although we certainly took a long way around the problem now that I read through this 😂
m

moltendorf

08/21/2022, 6:18 PM
still would like to figure out how to copy(..., resources) in gradle ... i mean I think I know it's literally that simple I just want to use gradle's dependency-resolution logic to convert the implementation-style-uri
io.ktor:ktor-server-core-jvm:$ktor_version
to actual url to copy from (maybe with a /blah.js to refer specifically to the js file I want; or I've seen other syntax like
io.ktor:ktor-server-core-jvm:$ktor_version/ktor-server-core-jvm-$ktor_version.jar!/META-INF/MANIFEST.MF
b

Big Chungus

08/21/2022, 6:19 PM
I might be wrong on this, but webjars would be your best option
m

moltendorf

08/21/2022, 6:20 PM
I'll read into them for sure. It's just something about my 'early 2000s enterprise' logic that's making me go web ... jar ... ew who uses those?
b

Big Chungus

08/21/2022, 6:20 PM
That or just having a custom gradle task to download the files you need and shove them into resources folder
m

moltendorf

08/21/2022, 6:20 PM
But I'm like Kotlin Ktor Jar Web ... Duh
b

Big Chungus

08/21/2022, 6:21 PM
You can even register a second resources folder and put downloaded files there. Then .gitignore it to avoid comitting
Sorry if it's a bit too basic or obvious, just trying to avoid assuming your gradle expertise
m

moltendorf

08/21/2022, 6:22 PM
Just the one-line implementation() so juicy. Maybe there needs to be a gradle plugin lol? I mean maybe I'm underrating my gradle knowledge after generating well over 1000 of the projects just never doing something as mystical as you have with the build.gradle(.kts) so like maybe I'll just go code that randomly here in the next few years out of needing it
We're all unicorns.
b

Big Chungus

08/21/2022, 6:23 PM
A plugin to pack a webjar from kjs project sounds very useful!
m

moltendorf

08/21/2022, 6:24 PM
I told Kotlin team about idk a bug... and "remote kotlin development" and got very confused looks in KotlinConf
Now I'm paying for the feature of remote kotlin development and very happy lmao
I've like subtly submitted bug reports on all languages and so far Kotlin has made me feel the most valuable ^.~
I feel it's something of a language barrier I have with the team but it shows they care a ton when they actually fix what I ask them to is what I'm saying. ❤️