icerockdev / moko-resources

Resources access for mobile (android & ios) Kotlin Multiplatform development
https://moko.icerock.dev/
Apache License 2.0
1.1k stars 120 forks source link

Module not found: Error: Can't resolve 'localization/comyourflixercommon_stringsJson.json' #574

Open sunildhiman90 opened 1 year ago

sunildhiman90 commented 1 year ago
Module not found: Error: Can't resolve 'localization/comyourflixercommon_stringsJson.json' in '/Users/sunil/AndroidStudioProjects/YourFlixer-KMP/build/js/packages/yourflixer/kotlin'

Getting following error in web app. Working fine now for all android, iOS, desktop but not on web.

codlab commented 1 year ago

Same on my end, noted that my project have a "resources" module which feeds a shared implementation and from there, jvmApp, jsApp, androidApp modules consumes the shared implementation.

I tried various thing, nothing works for now

edit : I also made the modification to copy the file from the "resources/webpack.config.d" project to the jsApp and it works but since I also have another module registering some resources, it fails. Only a manual modification to register both the content of those modules into the jsApp/webpack.config.d makes it working.

I made a script to had in the Js's app webpack.config.d . This script only needs a quick configuration :

// noinspection JSUnnecessarySemicolon
;(function(config) {
    const fs = require("fs");

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');

    // the actualRoot is actually normally always from this
    const actualRoot = path.resolve("./../../../..");

    const relativeModulesToLookUp = [
        "lorcana-shared",
        "resources"
    ];

    // lookp for all the absolute paths from each module up to the generated/moko/jsMain/*/res
    const jsMainsRes = relativeModulesToLookUp
        .map(folder => {
            // going from jsMain to ...
            const absoluteFolder = path.resolve(`${actualRoot}/${folder}/build/generated/moko/jsMain/`)
            const list = fs.readdirSync(absoluteFolder);

            // now lookup for the one folder where the sub res/ do exists
            const child = list.find(child => {
                const absolutePath = path.resolve(`${absoluteFolder}/${child}`);
                return fs.readdirSync(absolutePath).find(folder => folder == "res");
            })

            if (!child) {
                return null;
            }

            // ... jsMain/child/res
            return path.resolve(`${absoluteFolder}/${child}/res`);
        }).filter(child => !!child);

    config.module.rules.push(
        {
            test: /\.(.*)/,
            resource: jsMainsRes.map(resourcePath => { // map each res folder to the files, images & localisation
                return ["files", "images", "localization"].map(child => path.resolve(resourcePath, child));
            }).flat(), // then flatten the resulting multidimensional array
            type: 'asset/resource'
        }
    );

    config.plugins.push(new MiniCssExtractPlugin())
    config.module.rules.push(
        {
            test: /\.css$/,
            resource: jsMainsRes.map(resPath => path.resolve(resPath, "fonts")),
            use: ['style-loader', 'css-loader']
        }
    )

    config.module.rules.push(
        {
            test: /\.(otf|ttf)?$/,
            resource: jsMainsRes.map(resPath => path.resolve(resPath, "fonts")),
            type: 'asset/resource',
        }
    )

    // push each resolved res path to the modules
    jsMainsRes.forEach(path => config.resolve.modules.push(path));
})(config);