moko-resources icon indicating copy to clipboard operation
moko-resources copied to clipboard

Moko Resources does not support muti-module projects for JS

Open jeran opened this issue 2 years ago • 14 comments

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.

jeran avatar Oct 31 '22 20:10 jeran

Here's an example of the error that's displayed:

image

jeran avatar Oct 31 '22 20:10 jeran

This is related to #385

sproctor avatar Nov 04 '22 03:11 sproctor

@sproctor you should apply moko-resources plugin in application module too. plugin read dependencies and copy resources into output application.

Alex009 avatar Nov 04 '22 12:11 Alex009

Ah, perfect, thanks! Ignore my previous comment.

sproctor avatar Nov 04 '22 13:11 sproctor

Getting this issue too after updating to kotlin 1.7.20. 1.7.10 was working for me.

luca992 avatar Nov 09 '22 21:11 luca992

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

luca992 avatar Nov 09 '22 21:11 luca992

I'm getting this error most of the time too on kotlin 1.8.0 and 1.8.10 on a multi module project

Burtan avatar Feb 13 '23 12:02 Burtan

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");

Burtan avatar Feb 28 '23 20:02 Burtan

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.

geworfener avatar Jun 10 '23 18:06 geworfener

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 avatar Jul 04 '23 17:07 Burtan

@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?

geworfener avatar Jul 05 '23 19:07 geworfener

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

Burtan avatar Jul 06 '23 15:07 Burtan

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 avatar Dec 30 '23 14:12 manriif

@Manriif hi. yes. and this also in readme - https://github.com/icerockdev/moko-resources#multi-module-gradle-projects

Alex009 avatar Dec 30 '23 14:12 Alex009