moko-resources
moko-resources copied to clipboard
Moko Resources does not support muti-module projects for JS
If you create a multi-module kmm project where some Module A depends on some Module B and Module B uses dev.icerock.mobile.multiplatform-resources
plugin to generate string resources, Module A is not set up to use those strings correctly.
I've created a repository here to reproduce the issue and demonstrate the local fix we're using.
The first commit shows a simple js kmm project using moko-resources in a single module, which works fine.
The second commit introduces a second module and moves the strings to that module. This commit fails to run correctly.
The third commit manually adds a moko-resources-generated.js
to the top module which fixes the issue.
Thank you kindly for your time.
Here's an example of the error that's displayed:

This is related to #385
@sproctor you should apply moko-resources plugin in application module too. plugin read dependencies and copy resources into output application.
Ah, perfect, thanks! Ignore my previous comment.
Getting this issue too after updating to kotlin 1.7.20. 1.7.10 was working for me.
I'm working around it with a task like:
tasks.register<Copy>("jsCopyResourcesFromModuleB") {
from("../moduleb/build/generated/moko/jsMain/comexamplemoduleb/res")
into("build/generated/moko/jsMain/comexamplemodulea/res")
}
tasks.getByName("jsProcessResources").dependsOn("jsCopyResourcesFromModuleB")
tasks.getByName("jsCopyResourcesFromModuleB").dependsOn(":moduleb:generateMRjsMain")
inside Module A's build.gradle.kts
where Module A depends on Module B
I'm getting this error most of the time too on kotlin 1.8.0 and 1.8.10 on a multi module project
My fix currently is to use the shared module resource path for the moko generated webpack config in the js application module instead of the applications module resource path
const mokoResourcePath = path.resolve("path-to-shared-module-resources");
Working for me now using Kotlin 1.8.20 and moko-resources 0.23.0.
Make sure you are using the Kotlin multiplatform plugin in both the application and library module and also apply the moko-resources plugin in both of them.
I still have to add this webpack config to the web project
// noinspection JSUnnecessarySemicolon
;(function(config) {
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const mokoResourcePath = path.resolve("/projectpath/shared/build/generated/moko/jsMain/appnameshared/res");
config.module.rules.push(
{
test: /\.(.*)/,
resource: [
path.resolve(mokoResourcePath, "files"),
path.resolve(mokoResourcePath, "images"),
path.resolve(mokoResourcePath, "localization"),
],
type: 'asset/resource'
}
);
config.plugins.push(new MiniCssExtractPlugin())
config.module.rules.push(
{
test: /\.css$/,
resource: [
path.resolve(mokoResourcePath, "fonts"),
],
use: ['style-loader', 'css-loader']
}
)
config.module.rules.push(
{
test: /\.(otf|ttf)?$/,
resource: [
path.resolve(mokoResourcePath, "fonts"),
],
type: 'asset/resource',
}
)
config.resolve.modules.push(mokoResourcePath);
})(config);
@Burtan This is the moko-resources-generated.js that is generated by the moko-resources plugin. You should not have to add it yourselve. Where do you take that file from?
What versions of Kotlin and moko-resources plugin are you using?
Are you using the Kotlin multiplatform plugin for all relevant modules?
Have you applied moko-resources plugin to all relevant modules?
It is similiar to the generated configs, but it adds the resource part of the shared module to the web module. Yes I have applied the multiplatform and moko plugin to all relevant modules. I'm using moko 0.23.0 and kotlin 1.8.22
For those using multi-module / composite build, the generator plugin should also be applied to modules that aim to bring resources transitively to consuming modules. More simply, each module in the resources provisionning toolchain must apply the resource plugin.
Assuming you have three modules A, B and C:
- Module A declares resource strings.xml
- Module B depends on module A
- Module C depends on module B but not on module A
If you want the module C to consume strings.xml from module A then module B should apply the resource plugin event if it doesn't declare resources by itself nor consumes resources from module A. That said, module C must also apply the resource plugin, and naturally, module A too.
Behind the scene, applying the plugin to module B will copy the generated resources from build directory of module A to the build directory of module B. The same apply to module C which will copy the generated resources from module B build directory to the module C build directory. As module A generated resources are copied to the module B build directory, module C will benefits from the generated resources of module A by this process. At the end, all resources from direct and transitives dependencies of module C will reside in the module C build directory.
By applying the plugin correctly in the necessary module, the generated moko-resources-generated.js file in the webpack.config.d directory of module C is sufficient to include all resources in your JS application and there's no need to edit it.
I specify that this reasoning is based on my own analysis of the functioning of the plugin. The author must confirm if this is the expected functioning.
@Manriif hi. yes. and this also in readme - https://github.com/icerockdev/moko-resources#multi-module-gradle-projects