2

I would like to create a js library with Kotlin Multiplatform (an example of which is this project, where we have a webscocket server and a js client) which I will then build as a npm package and import in my Vue project (could be any other framework).

what I managed to do with chat project is:

  • build js sources with ./gradlew build
  • publish that via yarn publish (setting up remote registry url ofc)
  • add published package to package.json with (needed to update project name to @chat/client by hand in the generated package.json):
{
  "name": "@chat/client",
  "version": "0.0.1",
  "private": false,
  "workspaces": [
    "packages/chat-frontend",
    "packages/chat-frontend-test",
    "packages_imported/kotlin/1.6.21",
    "packages_imported/ktor-ktor-client-core-js-ir/2.0.0",
    "packages_imported/kotlin-test-js-runner/1.6.21"
  ],
  "resolutions": {},
  "devDependencies": {},
  "dependencies": {},
  "peerDependencies": {},
  "optionalDependencies": {},
  "bundledDependencies": []
}
  • added @JsExport annotation on writeMessage in src/frontendMain/kotlin/main.kt

what I didn't manage is (in my Vue project):

  • import writeMessage, I exported in .kt file (it's visible in source, not exported though)
  • import anything via import * from '@chat/client'
  • or any other folder along '@chat/client/*'
  • use the generated files in any other way

The generated package structure is very odd:

~ ls build/js/*

build/js/package.json  build/js/yarn.lock

build/js/node_modules:
... (npm dependencies from Kotlin/JS module)

build/js/packages:
chat-frontend  chat-frontend-test

build/js/packages_imported:
... (Kotlin/JS dependencies)

~ ls build/js/packages/chat-frontend/*

build/js/packages/chat-frontend/package.json  build/js/packages/chat-frontend/webpack.config.js

build/js/packages/chat-frontend/kotlin:
chat-frontend  chat-frontend.js  chat-frontend.js.map  chat-frontend.meta.js
(chat-frontend contains package dir tree and a file frontend.kjsm)

build/js/packages/chat-frontend/kotlin-dce:
chat-frontend.js
ktor-*.js
kotlinx-*.js
... (compiler output ???)

build/js/packages/chat-frontend/node_modules:
... (webpack cli and dev-server files)

Do you have any clues, tips or an example project which does that? I've processed whole section of Kotlin/JS docs but there is no information on how to import Kotlin generated .js files in a js/ts project.

EDIT:

I've updated my fork of ktor-samples with Kotlin/JS build files: build-js folder and src/backendMain/resources/chat.js. Here's the link to chat folder of the fork project

9
  • you can do npm install <PATH> where PATH is the generated JS files from your kotlin project. It would be the PATH to build folder where js and map file resides. In your case above, it would be PATH to that build/js/packages/chat-frontend/kotlin Commented May 11, 2022 at 20:59
  • isn't it the same as installing from a remote registry? I'll update the post with more info, I missed that part Commented May 11, 2022 at 21:01
  • yeah if you already have a remote npm module then yes, you can import that directly. Commented May 11, 2022 at 21:02
  • yep, and that is exactly what I'm doing, I've updated the post maybe my problem is better understandable now Commented May 11, 2022 at 21:27
  • can you somehow share your generated .js file? Want to see how the export name looks like. You would need to import the exported name like import chatlib from chat/client. then try console.log(chatlib) and see if you see the reference. here chatlib or whatever the exported name is something you would find in your generated js file. Commented May 12, 2022 at 18:18

2 Answers 2

1

I will try to help

  1. Kotlin/JS has 2 kinds of compiler: legacy and IR. @JsExport affects only IR compiler. But from kotlin-dce folder, you use legacy compiler backend. In IR compiler, DCE (dead code elimination) is included into compiler and there is no folder kotlin-dce. You can change compiler kind in gradle.properties with kotlin.js.compiler=ir|legacy.
  2. When you build project with IR, packages/*/kotlin will fully contain your library (similar with legacy's kotlin-dce)
  3. Then you need to prepare appropriate package.json file with name and main fields (task :publicPackageJson could help with that, but check, if it is ok for your case)
  4. Now in Kotlin/JS export works with packages. It means, that if you export io.ktor.samples.chat.frontend.writeMessage, it will be exported as io.ktor.samples.chat.frontend.writeMessage in js. So to import it, you need import io and then find necessary declarations.
import { io } from '@chat/client`

io.ktor.samples.chat.frontend.writeMessage("hello")
Sign up to request clarification or add additional context in comments.

1 Comment

I tried just copying packages and packages_imported and a generated package.json (changed name and private: false) and publishing it, but "warning Workspaces can only be enabled in private projects." plus "TS2307: Cannot find module '@signalling/client' or its corresponding type declarations.". Adding updateted package.json used for publishing.
0

In the case of classical (non-IR) js backend usage and you use only non-private NPM dependencies then the only thing that you need is to compile your Kotlin/js library (via :compileKotlinJs task), generate package.json for your library (via :publicPackageJson) and your package could be published to NPM or another private repository (by yarn publish).

After publication, you will have the ability to set your library as a dependency in any js project. (Note that the name and version of your library will be placed inside package.json (generated by :publicPackageJson task)).

Also, you can check this discussion. Hope it will help you.

1 Comment

hey Artem, thanks for the reply. I was able to publish the package, but cannot import the contents of it in another NPM-based project (please see comments under the post).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.