ScandiPWA is traditionally compiled in one of 2 modes: magento and storefront mode. When optimizing performance, ideally, we want to server production-like build, but with HTTP2 and compression enabled, to match the future deployment environment. To achieve it, we need to setup an express server.

To setup the express server, you will need to:

1. Install the dependencies

From ScandiPWA application root, install the dependencies:

yarn add express compression http-proxy-middleware spdy # using Yarn
npm i express compression http-proxy-middleware spdy # using NPM

2. Generate SSL certificates

From ScandiPWA application root, generate SSL certificates (no need to add them to trusted):

openssl req -x509 -newkey rsa:2048 -nodes -sha256 -keyout privateKey.key -out certificate.crt

3. Create a server configuration

In ScandiPWA application root, create a server.js file:

/* eslint-disable @scandipwa/scandipwa-guidelines/export-level-one, no-console */

const express = require('express');
const compression = require('compression');
const { createProxyMiddleware } = require('http-proxy-middleware');
const fs = require('fs');
const path = require('path');
const spdy = require('spdy');

const PORT = 8080;
const PROXY_TO_URL = '<https://my-real-production-server.com/>';
const PATH_TO_BUILD_FOLDER = './build'

const app = express();

app.use(compression());

app.use(express.static(PATH_TO_BUILD_FOLDER));

app.use('/graphql', createProxyMiddleware({
    target: PROXY_TO_URL,
    changeOrigin: true
}));

app.use('/media', createProxyMiddleware({
    target: PROXY_TO_URL,
    changeOrigin: true
}));

app.get('/*', (req, res) => {
    res.sendFile(path.join(__dirname, PATH_TO_BUILD_FOLDER + '/index.html'));
});

const options = {
    key: fs.readFileSync(path.join(__dirname, '/privateKey.key')),
    cert: fs.readFileSync(path.join(__dirname, '/certificate.crt'))
};

spdy.createServer(options, app).listen(PORT, (error) => {
    if (error) {
        console.error(error);
        process.exit(1);
    }

    console.log(`HTTP/2 server listening on port: ${PORT}`);
});

Replace the constants with desired values:

const PORT = 8080;
const PROXY_TO_URL = '<https://my-real-production-server.com/>';

4. Build the application

From ScandiPWA application root, run build the application in storefront mode:

yarn build # using Yarn
npm run build # using NPM

5. Start the server

From ScandiPWA application root, run the express server: