@sandwwraith I have a project generated by create-react-kotlin-app, so there is no gradle or maven build file, just a package.json.
In my package.json, I have dependencies like:
"dependencies": {
"@jetbrains/kotlin-css": "^1.0.0-pre.48",
"@jetbrains/kotlin-css-js": "^1.0.0-pre.48",
"@jetbrains/kotlin-styled": "^1.0.0-pre.48",
...
}
While kotlinx.serialization purports to have JavaScript support, I am at a loss as to how to manage the dependency in a node/npm deployment ... in the absence of gradle or maven.
Any ideas?
Unfortunately no support outside of gradle now. Publishing to npm is not complex, but webpack currently doesn't know anything about compiler plugins
Unfortunately no support outside of gradle now. Publishing to npm is not complex, but webpack currently doesn't know anything about compiler plugins
Do we have any updates on this topic? I'm using kotlin-react too and have the same problem.
For create-react-kotlin-app, there's a separate support ticket: https://youtrack.jetbrains.com/issue/CRKA-84
It will likely contain a solution to pass plugin option to compiler from webpack. NPM publishing could be done earlier, but without the plugin, so purely js programs dependent on libraries with serialization could work.
I was trying to WKA this issue and get it working for create-react-kotlin-app, however it's working only when running the dev server (npm start), not when I try to build it, see:
https://stackoverflow.com/questions/53585910/how-to-configure-create-react-kotlin-app-in-order-to-get-kotlinx-serialization-w
o purely js programs dependent on libraries with serialization could work.
I believe that is my scenario:
I have a multiplatform library which is consumed in a regular JS project (a vscode extension), for the library I have a handwritten package.json with:
"dependencies": {
"kotlin": "1.3.60",
"kotlinx-coroutines-core": "1.3.2"
/*need kotlinx-serialization-runtime here*/
}
Is there a workaround for this in the meantime?
I am currently trying to publish a library using kotlinx.serialization to npm as well. Like the others in this thread, I am missing a dependency I can add to package.json.
I guess, in the meantime, we could manually copy the kotlinx-serialization-kotlinx-serialization-runtime sources to the package?
Did it work? Was this you: https://www.npmjs.com/package/@cachet/kotlinx-serialization-runtime
@nbransby Yes, this was me. Instead of including the kotlinx.serialization sources in my library sources, I figured I can just as well publish the sources as a separate package myself.
Right now, I have my library with the @cachet/kotlinx-serialization-runtime dependency installed in npm. I am still in the process of testing whether everything works.
I am unfamiliar with JavaScript and the npm ecosystem, so this might take some time. You can try pulling in this dependency yourself and see whether your project works as expected. The current version is 0.14.0. In a hurry, I unpublished this version since I reorganized the sources (but same source code), not knowing I can't reuse this version number in the future. I will thus keep incrementing 0.14.0-rc.x if needed (in case the current release does not work for my project), until Jetbrains increments their version number.
@Whathecode hey I tried it - needed a few hacks but it seems to work! Im now getting SerializationException: Can't locate argument-less serializer for class User. User is a class with @Serializable annotation so maybe my assumption here is not correct:
https://youtrack.jetbrains.com/issue/KT-28602#focus=streamItem-27-3854636.0-0
As far as I know, your assumption on youtrack is correct.
However, it looks like the compiler plugin was not applied while compiling the JS target. Can you find a function User$$serializer() in the generated JS sources? It should be there.
And, of course, double-check that you apply the kotlinx-serialization compiler plugin!
I checked the JS and the serializer has been generated correctly. But:
function compiledSerializer($receiver) {
var tmp$, tmp$_0;
return Kotlin.isType(tmp$_0 = (tmp$ = get_js($receiver).Companion) != null ? tmp$.serializer() : null, KSerializer) ? tmp$_0 : null;
}
Is still returning null because Companion does not exist on get_js($receiver), $receiver is a SimpleKClassImpl and get_js returns the JS constructor function User which has no property for the Companion.
Thought it could potenially be a kotlin version mismatch issue but I've got everything on 1.3.60. Is it working for you?
Can you extract serializer explicitly, via User.serializer() (in Kotlin) ?
It was a kotlin version mismatch issue - an older version of kotlin was being pulled in via npm due to another dependency.
@Whathecode you need to update the main field in the package.json to:
"main": "kotlinx-serialization-kotlinx-serialization-runtime.js"
Also I use a gradle script to replace the require() in the generated js so it uses your package name (was doing this before for other packages anyway as kotlin/js doesnt support @ npm package prefixes), you might find it useful:
Can you extract serializer explicitly, via
User.serializer()(in Kotlin) ?
Actually it seems I still have to do this as using a @ImplicitReflectionSerializer methods still causes a SerializationException: Can't locate argument-less serializer for class
Thank you for that information, @nbransby (and happy NY!)
Also I use a gradle script to replace the require() in the generated js
I noticed you do this since the require calls generated by Kotlin Multiplatform seem to be somehow derived from the Gradle-defined dependencies. This works fine for Maven publications, but not for NPM publications for which a scope needs to be defined rather than Maven's reverse domain name notation. I have a similar problem in my multi-project build in which I use project(':project-name') dependencies in commonMain.
This raises two questions:
require call sufficient?I haven't dug deep in such nuances, probably someone from Kotlin/JS team (@anton-bannykh ?) could help. The single dependency of kotlinx.serialization is the kotlin stdlib, so I assume it can be safely packed inside (however, if you use another kotlin/js produced artifacts, won't it leave you with stdlib packed twice?)
In the meanwhile, I'll try to see if kotlinx.couroutines npm publishing gradle scripts can be adapted for kotlinx.serialization
@Whathecode
Hi @Whathecode, you planning to update your npm package to 0.20.0? Im upgrading today, guessing you are still running on 0.140?
We have upgraded, but, we now publish the package internally (a colleague set this up and I haven't had a chance to look at how it all works yet). I have to do the same for the open source part of this project for which I'll need to publish it to NPM, but that is not a priority right now.
Ok, where do you take the js file for the module from exactly?
When running tests and such, right now I copy them from the jars. You can check my build script: https://github.com/cph-cachet/carp.core-kotlin/blob/develop/build.gradle
// Copy JS sources into ...
from it.compileKotlinJs.destinationDir
def configuration = it.configurations.jsTestRuntimeClasspath
from(files {
configuration.collect { File file ->
file.name.endsWith(".jar")
? zipTree(file.absolutePath).matching {
include '*.js'
include '*.js.map' }
: files()
}
}.builtBy(configuration))
// ... 'node_modules' so that test can retrieve dependencies.
into "./${typescriptFolder}/node_modules"
@sandwwraith Any update on this?
We still have to jump through hoops to publish libraries depending on kotlinx.serialization to npm. One of the latest challenges is the module on the legacy backend contains an upper case (kotlinx-serialization-kotlinx-serialization-json-jsLegacy) which is not allowed on npm.
It would be nice if the runtime library is published to npm by this project, just like the kotlin standard library and coroutines are.
Also running into the same issue as @Whathecode
If I understand correctly, this seems to be an issue because the JS compiler's naming conventions are not aligned with NPM's, rather than an issue with kotlinx.serialization…
--
Either way, are there any known workarounds?
Maybe a script to convert all instances of jsLegacy to jslegacy in
Most helpful comment
@sandwwraith Any update on this?
We still have to jump through hoops to publish libraries depending on
kotlinx.serializationto npm. One of the latest challenges is the module on the legacy backend contains an upper case (kotlinx-serialization-kotlinx-serialization-json-jsLegacy) which is not allowed on npm.It would be nice if the runtime library is published to npm by this project, just like the kotlin standard library and coroutines are.