GUIPSS

Create-React-App (CRA) generates javascript and css files with names that contains a hash that varies everytime we build them. That is fine when you use the provided index.html file but sometime your use case does not allows that. Here is two (not perfect, but good enough) ways to load those files in another html file than the one provided by default.

The first would be to load the css and javascript files in your page directly from the assets-manifest.json file that is genereted by CRA, for example here with jQuery (in ES5) (but that could be done without it also) :

<div id="root"></div>

<script type="text/javascript">
    var BASE_URL = '/';

    function loadCss (cssFiles) {
        cssFiles.forEach(function (css) {
            $('<link>')
                .appendTo('body')
                .attr({
                    type: 'text/css',
                    rel: 'stylesheet',
                    href: css,
                });
        });
    }

    function loadNextScript (scripts) {
        if (!scripts.length) { return; }

        var script = scripts.shift();
        $.ajax(script, {
            dataType: 'script',
            success: function () { loadNextScript(scripts) },
        })
    }

    $.ajax(BASE_URL + 'asset-manifest.json', {
        dataType: "json",
        success : function (data, textStatus, jqXHR) {

            if (data && data.entrypoints && data.entrypoints.length > 0) {
                var scripts =
                    data.entrypoints
                        .filter(function (resource) {
                            return resource.match(/.+\.js$/)
                        })
                        .map(function (script) {
                            return BASE_URL + script;
                        });
                var cssFiles =
                    data.entrypoints
                        .filter(function (ressource) {
                            return ressource.match(/.+\.css$/)
                        })
                        .map(function (file) {
                            return BASE_URL + file;
                        });

                loadCss(cssFiles);
                loadNextScript(scripts);
            }
        },
        error: function () {
            console.log('unable to load react app, manifest file not accessible or corrupted');
        }
    })

</script>

I guess you could also use the asset-manifest.json file to generate the bundle during the build process and end up with just one javascript file. You can also not use the manifest file and bundle the files beforehand by putting some scripts in your package.json file, for example you can loop on the generated files and concatenate then into a bundle file:

{
  "bundle-js": "cd build/static/js/ ; for each in runtime*.js; do cat $each; echo \"\\n\"; done > ../bundle.js ; for each in *.chunk.js; do cat $each; echo \"\\n\"; done >> ../bundle.js",
  "bundle-css": "cd build/static/css/ ; for each in *.css; do cat $each; echo \"\\n\"; done > ../bundle.css",
}