Shared code


#1

I'm very interested in being able to share code between JS and JVM, but there are currently a few things in the way of this.

  1. Projects have to either be JS or JVM, so any code you intend to be for both needs to be built via build tool and not the IDE
  2. JS library support isn't quite there -
    1. Is there a way to have JS library dependencies with ant?
    2. Is there a way to produce a JS Jar?
  3. There are a few differences between JS and JVM code that I would consider to be 'core' to the language.
    1. Annotations in JS projects will not compile
    2. There is no common code for number constants such as POSITIVE_INFINITY, NaN, etc. Copying the number constants from Java will compile in JS, but not in JVM (Divide by zero errors)
    3. Certain features such as inner classes exist in JVM but not JS

One of the bullet points for Kotlin on the homepage is "Versatile - Suitable for any type of application. Even for sharing code between JVM/JS". I don't think this is currently a true statement, but I hope it will be soon!

A number of these issues are already in issue tracker, and I will try to add more as I see them. What I would love to see is just general progress towards the ability to share code between JS/JVM projects.

-N


#2

Hi Nicholas,

Regarding point one, I definitley agree that we need some sort of mult-target project support. In terms of JavaScript output, what do you think of the current way it works in that your entire module is compiled down to a single file/JS-module? Also, what are your thoughts on server-side package to object mapping in JavaScript?


#3

Re: single file / js-module There are two workflows here, the final production result and a fast iteration for development. For development, I like my iteration to be on as small of a piece as possible, so if I'm working on a class, I want to be working in a unit test, only needing to recompile as little as possible. If I'm working on something visual in a multi-module project, I want to be able to only recompile the changed module(s) and quickly see the changes within a browser. I'll sound like a broken record, but to me, iteration speed is probably the most important thing when developing user interface. Things need to "feel" right, and unlike systems work, this can't be proved without trial and error. However, for producing something for production, iteration speed doesn't matter and instead it's all about the result. When compiling for production, you want something optimized, minimized (optional), obfuscated (optional), and highly performant. I think you would probably want one JS file per module in production so that when your application changes but the the libraries haven't, the browser can still keep the cached libraries. I wouldn't want them split up more than that because requests themselves have a large overhead, so a lot of tiny files would have a slower load time.

Re: package to object mapping
I may be misunderstanding what you mean by server-side package to object mapping. Do you mean creating objects to match packages in order to namespace the JS classes?

Currently the output is very verbose and unoptimized, e.g.:

this.assetManager$delegate = Kotlin.modules['stdlib'].kotlin.properties.Delegates.notNull(); this.time$delegate = Kotlin.modules['stdlib'].kotlin.properties.Delegates.notNull();

Ideally you should be able to use generated KotlinJS code from plain JS without too much noise. With KDoc this would allow us to create complex self-documenting libraries for non-kotlin users. Cleaner output:

// imports var stdlib = Kotlin.modules['stdlib']; var Delegates = stdlib.kotlin.properties.Delegates;

this.assetManager$delegate = Delegates.notNull();
this.time$delegate = Delegates.notNull();