Add Kotlin Web (Ktor & KotlinJS) examples (2000USD Bounty)
From the maintainer Li Haoyi: I'm putting a 2000USD bounty on this issue, payable by bank transfer on a merged PR implementing this.
The goal of this ticket is to implement support for example/kotlinlib/web example tests for using Kotlin for web development, mirroring the example/javalib/web and example/scalalib/web, and support for KotlinJS in the spirit of scalajslib/. I would want the following example tests, broken down into smaller groups each with its own bounty:
650USD:
- [x]
example/kotlinlib/web/1-hello-ktor- A hello-world example using Kotlin and KTor to set up a web server serving a single
"<h1>Hello, World!</h1>"web page, in the spirit ofexample/javalib/web/2-hello-spring-boot
- A hello-world example using Kotlin and KTor to set up a web server serving a single
- [x]
example/kotlinlib/web/2-todo-ktor- An implementation of the common TodoMVC demo application, including HTML templating, JS/CSS resources, database access and unit/integration/
runBackground+curltests, in the spirit ofexample/javalib/web/3-todo-spring-boot
- An implementation of the common TodoMVC demo application, including HTML templating, JS/CSS resources, database access and unit/integration/
650USD:
- [x]
example/kotlinlib/web/3-kotlinjs-module(325USD)- How to define a simple KotlinJS module that can be compiled to Javascript, testing, and run using
node, in the spirit ofexample/scalalib/web/3-scalajs-module
- How to define a simple KotlinJS module that can be compiled to Javascript, testing, and run using
- [x]
example/kotlinlib/web/4-webapp-kotlinjs(325USD)- How to wire up a KotlinJS module with a Kotlin/Ktor server to serve the generated Javascript, in the spirit of
example/scalalib/web/4-webapp-scalajs
- How to wire up a KotlinJS module with a Kotlin/Ktor server to serve the generated Javascript, in the spirit of
700USD:
- [x]
example/kotlinlib/web/5-webapp-kotlinjs-shared(350USD)- How to implement code sharing between a JVM KTor server and a KotlinJS javascript module, such that common code and utilities can be used by both. In the spirit of
example/scalalib/web/5-webapp-scalajs-shared,
- How to implement code sharing between a JVM KTor server and a KotlinJS javascript module, such that common code and utilities can be used by both. In the spirit of
- [ ]
example/kotlinlib/web/6-cross-platform-publishing(350USD)- How to define a library with both Kotlin-JVM and Kotlin-JS versions and publishing it to maven central. In the spirit of
example/scalalib/web/6-cross-version-platform-publishing.
- How to define a library with both Kotlin-JVM and Kotlin-JS versions and publishing it to maven central. In the spirit of
Each of these examples above has a corresponding javalib/scalalib equivalent, and it should generally follow the style of those equivalents (scope, testing, etc.) but translated to Kotlin (Java/Scala -> Kotlin, Scalajs -> Kotlinjs, Cask/SpringBoot -> KTor, etc.)
For now the Kotlin-JS logic should live in kotlinlib/ together with the rest of the kotlin-specific configuration.
Let me try if I can do anyone
Hello, I'm new here.
How do I run the tests in the examples directory? mill testin where build.mill file is located output
build.sc file not found. Are you in a Mill project folder?
@c0d33ngr please see the readme.md at the root of the repo
I did a quick overview of the things which should be done here, and it seems that the work can be sliced in a bit more granular way.
The main complexity here comes actually from implementing Kotlin/JS support (similar to the Scala/JS) which is itself a quite big task, because:
- There are 2 modes here: only module content output (may be the case for libraries) or a complete output with Kotlin runtime and other libraries included (basically output with linking applied) - this is the case for the executable output.
- What about the NPM modules support (Kotlin/JS supports it)? I don't think it should come in the initial version, but it is a quite handy feature.
- Different module kind support (should be just a configuration flag, I hope, though).
So I think maybe implementing Kotlin/JS support is worth to be extracted into a different task? Making examples is easier than that.
Also this raises a design question: say there is a code which should be compiled to both JVM and JS targets. How this could be done with existing Scala modules, for example? I believe ScalaModule and ScalaJSModule cannot be declared for the same module at the same time, because of the conflicting declarations (ScalaJSModule extends ScalaModule).
@0xnm as written, the KotlinJS stuff (bullets 3-6) is already in separate milestones from the pure Ktor/web stuff (bullets 1-2). Bullets 3 and 6 seem pretty independent of Ktor and should be doable without any pre-requisites, and bullets 1-2 should be independent of KotlinJS. I don't mind adding more non-KotlinJS web stuff, just not sure what that would entail.
In Scala-land, cross-platform Scala code is normally handled via PlatformScalaModule, which defines multiple sub-modules for .jvm .js (and maybe .native) that share the same code. Thus the code ends up being compiled multiple times by the different versions of the Scala compiler. KotlinJS/KotlinJVM could use the same approach, or if they have any other techniques for cross-platform code we could use their thing as well.
I'm hoping the KotlinJS tooling already has a decent API/CLI, and most of the work would just be wiring it into Mill. I'm not sure how true that actually is, but as a point of reference Mill's ScalaJS support is 14 files and 1600 lines of code with another 1000 lines of tests for basically 100% coverage of ScalaJS' functionality. I'm hoping KotlinJS won't be that much more work, but I don't know
The bounty amounts are pretty arbitrary TBH and are just my best guess w.r.t. the amount of work necessary. For the KTor stuff they should be pretty reasonable, since those bullets shouldn't require any special tooling background. But if we think the KotlinJS bounties aren't proportionate to the amount of work necessary, I can totally bump them up, or if someone wants a different arrangement (e.g. some payment up front to de-risk the effort )
I added a very basic PR with a foundation for Kotlin/JS support in https://github.com/com-lihaoyi/mill/pull/3678, but there are many issues/missing functionality. See that PR for more details.
First 3 bullets (mostly) work. Further progress is blocked by https://github.com/com-lihaoyi/mill/issues/3695
@0xnm Now that we can resolve klib files, the subsequent two bullets should be doable if you're up for taking a crack at them, since the only thing blocking them before was accessing third party library for DOM interactions. The other limitations around module file support and test framework setup are issues but not blockers, at least for demo purposes. Using the same approach as the scala examples using PlatformScalaModule should work i think
The last bullet may require more work, I'm not sure how much work the gradle kotlin/kmp plugin does to support publishing. We can investigate when we get to that
Thanks @0xnm, I merged the two kotlinjs/webapp examples with some minor fixes and closed out the bounty for 4-webapp-kotlinjs.
For example/kotlinlib/web/6-cross-platform-publishing, I think this would require code changes (in PlatformKotlinModule to properly generate the module files and upload them. We also should add support in Coursier for resolving those, but I think that can be done separately.
Yes, I would suggest to split bounty for bullets 5/6 and maybe extract bullet 6 into a new issue (to have a clean space free of previous discussions), because it will definitely require some exploration work to be done and it won't contain only sample migration.
@0xnm sounds good. I'll split it out into a separate bounty and pay out the first bullet first