Kotlin/JS 1.4, how to output a NPM package?

Say you have a simple project with just the Kotlin standard library and one dependency from NPM. What would be a good pattern to output an NPM package? Also which tasks of the Kotlin/JS plugin (or Kotlin/MPP with js()) are key to do so?

1 Like

There are no such tasks in Gradle plugin yet, but we plan to add it in future. You can setup it on your own. We can task :publicPackageJson for generate package.json which can be used for publishing into NPM registry.

If you use legacy compiler, you have 2 options. You can publish compilation output js file (:compileKotlinJs). In this case you need to add all Kotlin/JS modules as dependencies to your package.json. But in fact there can be situation when some of your dependencies will not be in NPM registry. In this case you get error on npm install if your package.
So there is alternative variant, you can use webpacked version of your module. In this case you get one big bundle js file which can be used as a library. But in this case you get all NPM dependencies bundled as well, you can use configuration via webpack.config.d and Webpack externals

If you use IR compiler, you can use output of compilation, because it compile one javascript file from all Kotlin/JS modules, and using :publicPackageJson you can get valid package.json with all external npm dependencies

For not IR compilation I am finding that:

Option 1 - Publishing to npm

As mentiopned, the fact some dependencies wont be in NPM. Found this with some kotlin mutliplatform libs were only pushed to maven etc and not published to NPM.

But honestly I can live with this as any missing deps we just publish to our nexus.

However, even this way isnt an option as the package.json generated has absolute paths to the packages_imported folder dependencies instead of relative paths.

Option 2 - The one big bundled js in dist (or after manually running the webpack build)

Inspecting the output of this shows that there are a lot of things missing. We are creating a library code, with paths that aren’t called inside the codebase, but they are intended to be exported and called from the library consumer.

Seems the DCE is seeing paths that arent used and removing them from the output. But as mentioned they need to be there, and also need to not have obfuscated names when minified.

I tried the gradle kotlin plugins js/browser/keep settings to try and hint to DCE to leave this alone but the codepaths were always still missing.

Now with the IR compiler you can, if you enable binaries.executable(), a task named compileProductionExecutableKotlinJs with type KotlinJsIrLink will be added.

This task generates a JS bundled output with all dependencies from Maven but not from NPM. You could use that one with the node_modules folder created by the plugin to webpack all together. I’ve done a similar thing but for NodeJs here.