Eugene Fedorenko
05/26/2025, 1:17 PMArtem Kobzar
05/26/2025, 2:42 PMKtMutableSet from the kotlin-stdlib.mjsEugene Fedorenko
05/27/2025, 7:19 AMEugene Fedorenko
05/27/2025, 8:17 AMEdoardo Luppi
05/27/2025, 8:45 AMwhole-program granularity, which could have been a workaround. There is no output from compilation both in 2.1.21 and 2.2.0-RC.Artem Kobzar
05/27/2025, 8:47 AMEdoardo Luppi
05/27/2025, 8:49 AMkotlin("js") plugin, and I moved it to kotlin("multiplatform"), but forgot to adjust the sources from src/ to jsMain/kotlin/Edoardo Luppi
05/27/2025, 8:53 AMkotlin.js.ir.output.granularity = whole-program
to your gradle.properties file as a workaround. The Kt* objects should be exported at that point.Eugene Fedorenko
05/27/2025, 8:55 AMArtem Kobzar
05/27/2025, 8:58 AMEdoardo Luppi
05/27/2025, 9:03 AMbut it substantially increases the size of the js script a browser need to fetchAs far as I understand, the browser would end up fetching all the modules anyway, even in a per-module scenario, as you're not using dynamic imports.
Olexandr Marchuk
05/27/2025, 9:48 AMAs far as I understand, the browser would end up fetching all the modules anyway, even in a per-module scenario, as you're not using dynamic imports.The workaround with
kotlin.js.ir.output.granularity = whole-program should work for us, but we would like to use per-module because it seems more flexible in terms of code-splitting.
Currently, we bundle our code and kotlin libraries to the separate chunks assuming that kotlin libraries change not frequently(only when version is updated or DCE changes the output).Edoardo Luppi
05/27/2025, 9:52 AMOlexandr Marchuk
05/27/2025, 10:11 AMper-module approach.
I've thought that DCE and mangling should produce the same result for the same input.
the generation of additional variables uses stable namesIn case of vendor code, this happens when DCE changes the output, doesn't it? Or do you mean that additional variable in non-vendor code may change the result of mangling in vendor code? We did not check this case as well, but this is a good point.
Edoardo Luppi
05/27/2025, 10:16 AMpublic fun <T, R> array(values: Array<T>, transform: (T) -> R): Array<R> {
val array = Array<Any?>(values.size) {
transform(values[it])
}
return array.unsafeCast<Array<R>>()
}
compiles to
function array(values, transform) {
var tmp = 0;
var tmp_0 = values.length;
// Inline function 'kotlin.arrayOfNulls' call
var tmp_1 = Array(tmp_0);
while (tmp < tmp_0) {
var tmp_2 = tmp;
tmp_1[tmp_2] = transform(values[tmp_2]);
tmp = tmp + 1 | 0;
}
var array = tmp_1;
// Inline function 'kotlin.js.unsafeCast' call
// Inline function 'kotlin.js.asDynamic' call
return array;
}
And I'm not sure if generated intermediate variables like the tmp* ones use stable names or if the compiler generates different names from time to time.
Or if non JsExport-ed exported declarations are stable or not:
var VOID = kotlin_kotlin.$_$.b;
var captureStack = kotlin_kotlin.$_$.q1;
var initMetadataForClass = kotlin_kotlin.$_$.b2;
var get_indices = kotlin_kotlin.$_$.d1;
var IllegalArgumentException = kotlin_kotlin.$_$.l3;
var toString = kotlin_kotlin.$_$.m2;
var Unit_instance = kotlin_kotlin.$_$.j;
var get_lastIndex = kotlin_kotlin.$_$.f1;
var ArrayList = kotlin_kotlin.$_$.k;
Like those k, f1, etc. Although that's CJS, but I guess the same reasoning applies to ESM.Olexandr Marchuk
05/27/2025, 10:30 AMEdoardo Luppi
05/27/2025, 10:34 AMwhole-program now, while the K/JS team attempts to fix the underlying issue. If six months from now it's not fixed yet, then I'd begin experimenting with per-module and caching effectiveness.