Hello everyone, I'm working on sharing my models i...
# javascript
c
Hello everyone, I'm working on sharing my models in a Ktor app, targeting the
jsMain
module, which will be called from a front-end written in React with Vite. I used the KMP Wizard to generate the Ktor server and added the
jsMain
module manually. In the
composeApp
package's
build.gradle.kts
, I added this block to configure JavaScript:
Copy code
js {
    useCommonJs()
    moduleName = "kotlinJs"
    browser {
        testTask {
            enabled = false
        }
        webpackTask {
            outputFileName = "kotlin.js"
            output.libraryTarget = COMMONJS2
        }
        @OptIn(ExperimentalDistributionDsl::class)
        distribution {
            outputDirectory.set(projectDir.resolve("output"))
        }
    }
    binaries.executable()
}
In the
shared
module's
build.gradle.kts
, I only added:
Copy code
js {
    browser()
    binaries.executable()
}
When I run
jsBrowserProductionWebpack
, it creates the
kotlin.js
bundle. However, I’m having trouble importing this JS file into my React project. Any help would be greatly appreciated!
I have tried adding support for commonJs in vite using https://github.com/vite-plugin/vite-plugin-commonjs my vite config looks like
Copy code
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import commonjs from 'vite-plugin-commonjs'

// <https://vitejs.dev/config/>
export default defineConfig({
  plugins: [
    react(),
    commonjs()
  ],
})
React app components is
Copy code
import * as kotlin from "./kotlin"


function App() {
  console.log("==== start =====");
  console.log(kotlin);
  return (
    <>
      <div className="text-xl">Hello Ch8n!</div>
    </>
  )
}

export default App
a
And what is shown in the console log for the
kotlin
namespace? And could you describe the problem itself? Is it a runtime error or you just don't see the expected declarations in JS?
c
hi @Artem Kobzar thanks for replying im getting uncaught expection in console log
Copy code
Uncaught SyntaxError: The requested module '/src/kotlin.js' does not provide an export named 'composeApp' (at App.jsx:1:10)
inspecting source kotlin.js file shows this error
a
Could you please show how do you import the composeApp in your App.jsx?
c
I just generate js bundle and mapping using gradle
jsBrowserProductionWebpack
task, then copy paste generated js and mapping file into src directory
t
You can build standalone JS file in ES module format without Webpack
ES module - fine format for Vite (no additional plugins required)
c
Hi @turansky thanks what changes do i need to do for that any resource?
t
1.
kotlin.js.ir.output.granularity=whole-program
in
gradle.properties
2.
target="es2015"
in compilation task 3. Use result of
...ProductionExecutable
task
c
hi @turansky 1. I have added
kotlin.js.ir.output.granularity=whole-program
in
gradle.properties
2. added below to compilation task
Copy code
tasks.withType<KotlinJsCompile>().configureEach {
        compilerOptions {
            target = "es2015"
        }
    }
do i need to update or remove
Copy code
useCommonJs()
...
webpackTask {
            outputFileName = "kotlin.js"
            output.libraryTarget = COMMONJS2
        }
...
t
You should disable Webpack tasks only - they won't be required:
Copy code
webpackTask {
    enabled = false
}
c
Hi @turansky I tried the same, disabled webpackTask and run gradle
compileProductionExecutableKotlinJs
but there is no .js file in any build folders of composeAppModule or in shared module. there is a sikko.js file in root level build folder but it doesn't have my code generated from my file. I have created a repository if you can check my configuration,it would be a great help https://github.com/ch8n/kmm-full-stack
t
Copy code
tasks.compileProductionExecutableKotlinJs {
    doLast {
       println(this.destinationDir)
    }
}
AFAIK It would be
%subproject%/build/compileProduction...
directory
%root%/build/js/packages/composeApp
?
c
Yes it has kotlinJS package which is my module name in which I have sikko.js and KotlinProject-shared.js but both of them doesn't contain any object call called injection which I exposed using @Jsexport
t
which I exposed using Json export
Do you want to embed JSON inside Kotlin/JS distribution?
c
Sorry fixed typo it's @Jsexport annotation
t
Which module contains
@JsExport
?
c
root > composeApp > jsMain > ... > Injector.kt
Copy code
@OptIn(ExperimentalJsExport::class)
@JsExport
object Injector : KoinComponent {
    fun test(): String = "Hello from Kotlin Singleton!"
}
generated sikko.js or KotlinProject-shared.js both don't have this
Injector
object or function
t
Copy code
./gradlew clean
./gradlew composeApp:compileProductionExecutableKotlinJs
👀 1
And check
composeApp/build
and
build/js/packages/composeApp
And yes - you can print task configuration to see where output file located
c
composeApp folder isnt getting generated in build/js/packages/composeApp -> I have added moduleName in js config block to kotlinJS
t
moduleName in js config block to kotlinJS
Sorry, but it’s very bad name from debugging perspective
kotlin.js
- default name of stdlib file
c
okay removing all lets see what default packages generates
t
composeApp.mjs
- is what you need
c
this file? (KotlinProject) is name of root
Copy code
KotlinProject-composeApp.mjs
t
Yes
gradle intensifies 1
Fixed
moduleName
is preferred
c
how to i use it in my react app? directly import .mjs ?
t
Looks like all this folder - library output (except
META-INF
and
index.html
)
You can start from direct import just for check
🔥 1
c
okay thanks i will check and update soon
Hi @turansky thanks it worked, after importing
KotlinProject-composeApp.mjs
directly I'm able to module object in log
t
It's highly recommended to have fine fixed module name (not
kotlin.js
)
1
c
Yup thanks will update that!
Hi @turansky @Artem Kobzar you have idea about this? all of my members are coming as obfuscated names
on dev build im getting names but _1 is appended to them
t
It's expected behaviour
c
oh okay! will this
_1
will remain same or can change?
t
I see internal (non-exported) API on screenshots.
c
All the logic starting from Viewmodel is in my shared module, do I need to add exported annotation on all?. do you have any project from which I can read more?