Guide to importing a Kotlin/JS generated module into a separate npm-dependent project

I am interested in developing a JavaScript library using Kotlin Multiplatform (such as the project found here, which includes a websocket server and a JavaScript client). My goal is to build this library as an npm package and then import it into my Vue project, or any other framework.

What I have achieved so far with the chat project:

  • Built the JavaScript sources using ./gradlew build
  • Published them using yarn publish (configured remote registry URL)
  • Added the published package to package.json by manually updating the project name to @chat/client 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

Challenges I faced in my Vue project:

  • Importing writeMessage that was exported in a .kt file (visible in source but not actually exported)
  • Importing anything via import * from '@chat/client'
  • Accessing any other folder along '@chat/client/*'
  • Using the generated files in any meaningful way

The structure of the generated package seems unconventional:

~ 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)

If you have any insights, tips, or examples of projects that demonstrate this integration, please share. I have reviewed the Kotlin/JS documentation extensively but could not find information on importing Kotlin-generated .js files in a JavaScript/TypeScript project.

EDIT:

I have updated my fork of the ktor-samples project with Kotlin/JS build files: build-js folder and

src/backendMain/resources/chat.js
. Here is the link to the chat folder in the forked project.

Answer №1

I am here to offer some assistance

  1. In Kotlin/JS, there are two types of compilers: legacy and IR. The @JsExport feature only affects the IR compiler. However, if you are using the kotlin-dce folder, then you are utilizing the legacy compiler backend. In the IR compiler, dead code elimination (DCE) is integrated into the compiler itself, so there is no need for a separate kotlin-dce folder. You can switch between compiler types in the gradle.properties file by setting kotlin.js.compiler=ir|legacy.
  2. When building your project with the IR compiler, the packages/*/kotlin directory will fully include your library (similar to how it works with the legacy's kotlin-dce).
  3. Next, you must create a suitable package.json file with the required name and main fields (you can use the :publicPackageJson task for this, but make sure it suits your specific requirements).
  4. Currently in Kotlin/JS, exporting functions involves working with packages. This means that exporting
    io.ktor.samples.chat.frontend.writeMessage
    will export it as such in JavaScript. So, when importing it, you first import io, and then locate the necessary declarations.
import { io } from '@chat/client`

io.ktor.samples.chat.frontend.writeMessage("hello")

Answer №2

If you are using classical (non-IR) JavaScript backend and relying on non-private NPM dependencies, the process is quite simple. All you need to do is compile your Kotlin/JS library using the :compileKotlinJs task, generate a package.json for your library with the :publicPackageJson task, and then publish your package to NPM or any other private repository using yarn publish.

Once published, you can easily reference your library as a dependency in any JavaScript project. Just remember that the name and version of your library will be included in the package.json file generated by the :publicPackageJson task.

For more information, refer to this insightful discussion. Hopefully, it will provide you with useful insights.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Querying the database to check for the presence of a file in a .js file on Google App Engine

I'm currently working on implementing an upload button for users to upload files to our storage system using Google App Engine with Python, as well as HTML and JavaScript for the views. To achieve this, we have an HTML file and a.js script that promp ...

Tips for assigning a Custom Formik Component's value to the Formik value

I'm currently integrating Formik into my form alongside Google Places auto-complete feature. My goal is to display the places auto-complete functionality as a custom component within the Formik field. form.js <Formik initialValues={location:" ...

Setting up the Font Awesome Pro version in Angular using the Font-Awesome package

The process of installing the pro version of Angular Font-awesome began with setting up my registry using these commands: npm config set "@fortawesome:registry" https://npm.fontawesome.com/ && \ npm config set "//npm.fontawesome.com/:_authTo ...

Sorting data in AngularJS using the OrderBy filter in ascending

I am using ng-repeat in my code: <label ng-repeat="atp in Keywords | unique:'atp'"> {{atp}} </label> The values in atp are as follows: client animal zoo boat I want the final output to be: animal boat client zoo Thank you for ...

the term 'this' does not pertain to the user object within the mongoose model

Here is a snippet of my code that saves a user object to a database using Express: api.post('/signup', function (req, res) { var user = new User(); user.name = req.body.name; user.email = req.body.email; user.setPassword(req.body ...

How can I stop jQuery mobile from updating the document title?

It appears that jQuery mobile automatically uses the text content of data-role="header" to set the document.title. For example: <div data-position="fixed" data-role="header"> <h1>This text</h1> </div> To work around this, I ha ...

Unlocking Worldwide Availability for Identifying URL Parameters

Is there a way to obtain global access to the current URL ID params? I am facing difficulty accessing the current URL ID in a child component within React. The ID is essential for querying a MongoDB database in my ChecklistTool component. Typically, I wou ...

Is there a way to execute a PHP script using Ajax without needing any return values?

Currently, I am attempting to execute a php script with ajax without needing any output or echos. Is there a method to achieve this? Below is the approach I have taken: $('button')[1].click(function () { $.ajax({ met ...

Creating a self-chaining function in JavaScript: A guide

Currently, my goal is to create an Array.prototype function called union( array_to_union ), and then utilize it in the following manner: var a = [1,2,3]; a.union([2,3,4]).union([1,3,4]) ...... I am aiming for the outcome to be the union of these arrays. ...

Arranging buttons in a row with Bootstrap 5

Struggling to align the buttons on my webpage side by side in the center, I've tried two Bootstrap 5 classes but they're not achieving the desired look: https://gyazo.com/c23f2eade4614380aec547b11e61387a https://gyazo.com/e40a678b02c9f641f746b1c ...

Retrieve the image description using the file_picker_callback and image uploader in Tinymce

TL:DR I am attempting to retrieve the value of the image_description field using JavaScript to include it in my post XHR request Original query: I am utilizing the file_picker_callback type image I have enabled the image_description input field in my ...

Tips for converting a large number into a string format in JavaScript

I created this easy loan calculator by following online tutorials and using my basic coding skills. It works well, but I would like to add spaces in the output numbers for readability. For example, instead of "400000", I want it to display as "400 000". ...

Is it possible to swap images by clicking on them?

Let's say I'm working with 3 images. Image A, B and C. A is the main image initially. If I click on image B, it will become the main image and image A will take its place in the old position. The same condition applies when B is the main image a ...

npm installation encounters an error

I'm facing a problem with npm installation as it keeps failing. Despite this, I can see that the node-modules folder has been generated in my local path. How can I resolve this issue shown in the image above? Check out the installation error here. ...

After following the official guide, I successfully installed Tailwind CSS. However, I am facing issues with utilizing the `bg-black` className for styling the background,

Following the installation guide for Tailwind CSS, I ran the command npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p. Despite this, the background className (bg-black) is not working as expected. Here are the file paths: Directory ...

Looking for assistance with accessing elements using the "document.getElementById" method in Javascript

Below is the code snippet I am working with: <html> <head> <script> function adjustSelection(option) { var selectList = document.getElementById("catProdAttributeItem"); if (option == 0) { ...

How to Efficiently Organize OpenAI AI Responses Using TypeScript/JavaScript and CSS

I'm using a Next.js framework to connect to the OpenAI API, and I've integrated it seamlessly with an AI npm package. The functionality is incredible, but I've encountered an issue regarding line breaks in the responses. You can find the AI ...

Tips for updating the pagination layout in Material UI Table

Currently, I am attempting to modify the background color of the list that displays the number of rows in MUI TablePagination. <TablePagination style={{ color: "#b5b8c4", fontSize: "14px" }} classes={{selectIcon: ...

Error: Unable to authenticate password for user "Joshua Rieth" in Knex database connection

Encountering an issue while working on my PostgreSQL database setup using Knex. When I try to run knex migrate:latest, the following error message pops up: Error: password authentication failed for user "Joshua Rieth" at Parser.parseErrorMessage (C:&bs ...

Having trouble getting the JSONP request to render properly, encountering persistent errors

Need assistance with JSONP Rendering to HTML. The request is present in the source code, but I keep encountering errors on the foreach line. Any help would be greatly appreciated. <meta name="viewport" content="width=device-width, initial-scale=1"&g ...