Search code examples
reactjswebpackgzipreact-snap

Prerendering React app with compressed (gzip) sources with use of react-snap


I am trying to prerender my react app with react-snap. My project is not using create-react-app.

// react-snap configuration
{
    inlineCss: true,
    source: "dist",
    skipThirdPartyRequests: true
}

Prerendering worked correctly if I built my application with webpack mode: development. But it does not when I use my production build. After spent some time debugging, I discovered, that problem happened only when I use compression-webpack-plugin. When I commented on it out, it finished successfully.

/// webpack.config.prod.babel.js

/* eslint-disable import/default */
import merge from 'webpack-merge';
import CompressionPlugin from 'compression-webpack-plugin';

import common from './webpack.config.common.babel';

module.exports = (env = {}) => {
    return merge(common(env), {
        mode: 'production',
        devtool: 'nosources-source-map',
        plugins: [
            /* when I uncomment the use of plugin, the prerendering stops to work */
            // new CompressionPlugin({
            //     algorithm: 'gzip',
            //     compressionOptions: {level: 9},
            //     test: /\.css$|\.js$|\.map|\.svg|\.woff|\.woff2|\.ttf|\.eot$/,
            //     threshold: 2 * 1024,
            //     deleteOriginalAssets: true
            // })
        ]
    });
};

The error reported by react-snap: pageerror at /: SyntaxError: Unexpected token '<'

I figured out, that it tries to get my built main or vendor javascript file with extension .min.js. But in my built, there is only file with extension .min.js.gz, which is successfully handled with a standard request from the browser.

My production build is working correctly without prerendering. So I suppose it is a problem of some react-snap configuration, but I did not find any solution for it.

It is possible to use react-snap and gzipped sources at all?


Solution

  • There is a deleteOriginalAssets: true option, without it CompressionPlugin should preserve the original .min.js files for you to use with react-snap. While your server will continue serve browsers with the .min.js.gz files because they still exist.