-
-
Notifications
You must be signed in to change notification settings - Fork 390
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add very basic Kotlin/JS support: ability to compile the binary #3678
Conversation
4eb7ebd
to
26022df
Compare
26022df
to
bc5db4f
Compare
Thanks for the thorough investigation @0xnm. Regarding Kotlin 1.8 vs 1.9 vs 2.0, what do we currently support for KotlinModule on the JVM? All of those versions, or only specific version ranges? I think you're right that a full implementation of the Kotlin-JS will take a lot of time, more than I expected. Perhaps the three big challenges will be handling the Given that, I think the right thing to do is as follows:
|
import java.util.zip.ZipFile | ||
|
||
/** | ||
* This module is very experimental. Don't use it, it is still under the development, APIs can change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any API reference or example code you used to find all the different configuration keys that KotlinJS exposes, and you had to translate to Mill here? If so we should put it in the scaladoc so future readers can see where all this stuff came from
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is where I would avoid adding any documentation for now, because this Kotlin/JS module is not ready for being used at all, so it shouldn't be in the docs/example. The first blocker is inability to use .klib
instead of .jar
, the second one is API: it is subject to change anyway, and I took an inspiration from ScalaJSModule
, but API there looks strange - some methods have scalajs
prefix, some don't, etc.
The point of this PR is just to add the first building block to the Kotlin/JS support.
private def moduleName() = millModuleSegments.value | ||
.filter(_.isInstanceOf[Segment.Label]) | ||
.map(_.asInstanceOf[Segment.Label]) | ||
.last | ||
.value | ||
|
||
private def fullModuleName() = millModuleSegments.value | ||
.filter(_.isInstanceOf[Segment.Label]) | ||
.map(_.asInstanceOf[Segment.Label].value) | ||
.mkString("-") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do these two names end up being used? If it's just for the compiled .js
file, I wonder if we can get away with just providing a hardcoded name (IIRC ScalaJS just hardcodes it as main.js
) and leaving the user to override and rename the file themselves if they need to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess here comes the difference between the binary output of Scala.JS and Kotlin/JS: Kotlin/JS is able to split final .js
files per module by using the following flag, it can be seen here.
I guess the benefit of doing so lays mainly on the browser side, where such .js
files can be loaded by the client in parallel.
Considering that, it is not possible to hardcode the default name (and I would avoid doing so), having the output matching the module name is more meaningful.
The implementation and unit tests look pretty good. Just need an example test so we have something we can include in the docs |
No, for JVM target there is no restriction, because it is pretty established ecosystem of distributing
Yes, more or less. Although once For the test runners, yes - it is another blocker even for
Documentation can be added (but not something in
Well, if not only 1:1, because full tests support is not there,
By the way, Android libraries are published as |
6a781e5
to
b3b1780
Compare
@0xnm I pushed a simple Going further to the next bullet |
Thanks for adding the docs/simple example. Indeed, such plan makes sense. |
@0xnm I'll split that section of the bounty in half and pass you the half for the first bullet just to close that out, since it may be a while before we can proceed with the subsequent bullets |
Another part for #3611.
This PR adds a very basic foundation for the Kotlin/JS support. The code provided allows to:
org.jetbrains
(most likely) dependencies onlykotlinx-test
so far), but without any test results collection/tests selector, etc.However, I think that full Kotlin/JS support will take a lot of time, because even if there is a Scala.JS counterpart available, the way these technologies work is very different (distribution, format, etc.)
Issues I've encountered:
klib
file available (see https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-js/2.0.0/). When Gradle is used, it is able to fetch it using attributes declared in.module
file, but Coursier is not able to recognize and fetch it.jar
file published with Kotlin/JS library inside, it may be rejected by the compiler. For example, this https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-html-js/0.8.0/ has the necessaryjar
file with.meta.js
/.kjsm
files inside, but it is rejected by the compiler of Kotlin 1.8/1.9. Here https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-js/1.9.24/, for example, nothing is rejected, so I suppose there is an issue in the ABI/metadata version. Not sure how it can be solved (maybe by relying only onklib
? Butklib
cannot be fetched by Coursier).package.json
and add the necessary JS test frameworks/runners there if executed in Node environment, or even webpack for Browser environment. This is also a big chunk of work to be done. For now I've added only test binary execution, but there is no test results collection / test selector.klib
is published, andjar
of version 4 is not compatible with the 1.8/1.9 IR compiler.Kotlin/JS IR compiler has different modes: it can output either IR/Klib or can produce final JS (basically IR+linking). Kotlin Gradle plugin is using 2 passes: to generate IR and then produce final JS. I guess it is done for the better performance / better incremental support, but I, for the initial drop, rely on a single pass (IR+linking in a single compiler invocation) => need to make=> addressed in the 2nd commit.compile
task to produce only IR code and add kind oflink
task to produce executable in the future.