I have a kotlin js module library, which i want to...
# javascript
a
I have a kotlin js module library, which i want to consume from an other koltin js project. The library has some npm dependencies specified in build.gradle.kts. However when i try to run the project, the js runtime complains how it doesn't find the dependency. Is there a way to have the library package all the dependencies, so that the consumer doesn't need to specify the libraries in their own dependencies?
a
@Adam Semenenko @Ilya Goncharov [JB] as far as I know we should copy transitive NPM dependencies to the package.json of the current executable/library. Am I right? Doesn't it look like as a bug?
h
Does the Kotlin JS library uses
api
?
Because it does work well with my libraries 🤔
a
it doesn't. the dependencies are only used inside of the library module and I don't want them to leak into the client
e
> the dependencies are only used inside of the library module and I don't want them to leak into the client This is kinda impossible to do. If your dependency is using an external JS package, that will get included with your final bundle. > However when i try to run the project, the js runtime complains how it doesn't find the dependency Most of the time it's a matter of upgrading the npm/yarn lockfile. IIRC the klib comes with a
package.json
correctly populated with the library's JS dependencies, and the lockfile upgrade process should pick them up.
c
Does the Kotlin JS library uses
api
?
This shouldn't matter, both
api
and
implementation
should declare a transitive dependency that the end-user downloads. Only
compileOnly
doesn't do that, but KGP will error out if you try to.
e
Yup that's correct.
api
does not matter in a K/JS context when you use
npm(...)
.
a
This is kinda impossible to do. If your dependency is using an external JS package, that will get included with your final bundle.
first things first. my main thing here is to not force the consumers of my library to manually add dependencies just to use my library
will try with api
I think I know what's up, sort of. will report back
e
> first things first. my main thing here is to not force the consumers of my library to manually add dependencies just to use my library They will not, that's not a problem. But they will have to remember to regenerate their lockfiles, as the normal import process doesn't do that.
a
I think there is a bug somewhere, when you have a broken multiplatform project with nodejs and jvm target. I removed the jvm target from the library, while the client was having both. There was no error on the IDE or via gradle, so the project was defo corrupted. Ended up removing the jvm target on the consumer too and all is well. Now for some reason I cannot get it to work on my VPS though, as it crashes complaining it cannot find:
Copy code
import * as UnifiedSdk from 'unified';
which is a package the library uses
I just tried with
api
. It definitely doesn't copy over the dependencies. Tried deleting
node_modules
on the consumer project, then gradle sync and the dependencies from the library are never installed in node_modules
e
Did you upgrade the lockfile and run the npm/yarn install task?
a
I did not. how do i do that?
e
You can run
kotlinUpgradeYarnLock
and see if the versioned lockfile changes first. And then you can run
kotlinNpmInstall
a
doing
kotlinUpgradeYarnLock
on the consumer does update the lock file and I can see the missing dep in there. doing
kotlinNpmInstall
does not add the missing package in the node modules tho
trying on the lib itself now. EDIT: that one caused no changes
e
Difficult to know what's going wrong without some code to check : ( But the key is your library should have a
package.json
file at the root of the
*-js.klib
. Try to check if it's indeed there.
a
But the key is your library should have a
package.json
file at the root of the
*-js.klib
. Try to check if it's indeed there.
what is klib? never seen that
e
klibs are the artifacts produced by the Kotlin compiler. Each platform gets its own klib file.
This is a local example. If the library is being pulled from Maven Central, you can examine the Maven Central artifacts.
a
i started connecting the dots i think. I think it has to do with my setup
the consumer project run by a node js project. it has a
package.json
with minimal setup. the
package.json
has a script which builds the kotlin/js consumer. that kotlin js is the one using the library:
Copy code
{
  "name": "backend",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "scripts": {
    "tailwind": "npx tailwindcss -i styles.css -o public/css/output.css",
    "watch-tailwind": "npx tailwindcss -i styles.css -o public/css/output.css --watch",
    "watch-kotlin": "./gradlew backend:jsNodeDevelopmentLibraryDistribution -t --quiet",
    "watch-backend": "bun run --insecure --watch dist/backend/alexstyl-backend.mjs",
    "dev": "concurrently \"bun run watch-backend\" \"bun run watch-kotlin\" \"bun run watch-tailwind\" \"bun run dev-stripe\"",
    "prod": "bun i && pm2 start ecosystem.config.cjs",
    "build": "./gradlew jsNodeDevelopmentLibraryDistribution --quiet",
    "dev-stripe": "stripe listen --forward-to localhost:3000/api/stripe-webhook"
  },
  "dependencies": {
    "tailwindcss": "^3.4.1",
    "@tailwindcss/line-clamp": "^0.4.4",
    "@tailwindcss/typography": "^0.5.13"
  },
  "devDependencies": {
    "concurrently": "^8.2.2",
    "dotenv-cli": "^10.0.0",
    "postcss-import": "^16.1.1"
  }
}
The thing here is that the output fo the kotlin consumer is placed in
dist/
I have setup a custom path for the distribution of the library
e
the consumer project is a node js project.
Ah well, that changes quite a lot everything. I thought the consumer was a Kotlin project too.
a
it is. that was a typo. the consumer project is indeed a koltin project, which is run by a nodejs app
ok figured this out. so when i do
./gradlew kotlinNpmInstall
that installs app npm packages. at
build/node_modules
. But i specify a custom distrbution path, it just doesn't install anything
am i missing something here? all i am doing is using the
outputDirectory
in kotlin/js/nodejs/distribution within build.gradle.kts
e
The distribution path should not change anything related to the installation of dependencies.
a
it definatelly does. tried a few times and when i set the output directory then the
build/js/node_modules
never gets created
cc @Artem Kobzar. Not sure whether
[Kotlin]
is the right project for it, but no other made sense
👀 1
thank you color 1
e
Could you make the repro public, or is it proprietary code?
a
does it matter?
The library might eventually become open source, but cant be right now. In terms of workarounds I can copy pasting the dependencies on the consumer side for now
e
No I meant the reproducer you've added to the issue, not the original code. I'd be curious to try it out myself.
a
the issue has both library and consumer to try it out
needs to be 2 projects so that you publish one on maven local and the other one consumes it via maven local
e
the issue has both library and consumer to try it out
I think you've set the visibility to JetBrains-only tho.
a
TIL there is a visibility option. Just changed it. can you try again?
e
Yup now I can see them, thanks!
👌 1