React app caching & bundle issues

Your issue
We’re getting errors in production that say that our react bundles couldn’t be found

The javascript console spits out the above error, which disappears when we refresh the page. We only see these issues loading pages after deploys (doesn’t happen incognito). My best guess is that there’s some caching issue with our webpack bundles that’s causing the app to search for an old file / not find an existing one.

Dockerfile content (if any)

FROM node:16-alpine3.11 as build

WORKDIR /app

ENV PATH /app/node_modules/.bin:$PATH

ARG REACT_APP_API_URL
ENV REACT_APP_API_URL=$REACT_APP_API_URL

COPY package.json ./
COPY yarn.lock ./

RUN yarn
COPY . ./
RUN yarn build

# production environment
FROM nginx:stable-alpine as production
RUN rm /etc/nginx/conf.d/default.conf
COPY conf.d/default.conf /etc/nginx/conf.d
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Hey @nimo, thanks for your patience.

Can you give me a way to reproduce your issue?

@rophilogene – I’m not sure what the best way to reproduce this is. It happens on deploys, perhaps I can setup a simple create react app with some lazy loaded bundles, and we can try deploying, updating & deploying again? The issue seems to be happening at the second deploy.

If you can do that it would be great. Then we can make sure it will be fixed for ever :slight_smile: thank you @nimo

@rophilogene @Pierre_Mavro do you have any update on this topics. I currently have the same issue with my react app. the index.html file is cached and is not pointing to the write compiled js and css files.


Here the js file is /static/js/main.b6c0d344.js but it should be /static/js/main.1a93fa3f.js

After a force refresh it’s working properly

Could you please share the Nginx configuration you have added to your container?

@Pierre_Mavro

{
    "deployment.delay_start_time_sec": 30,
    "deployment.custom_domain_check_enabled": true,
    "build.timeout_max_sec": 1800,
    "network.ingress.proxy_body_size_mb": 100,
    "network.ingress.enable_cors": false,
    "network.ingress.cors_allow_origin": "*",
    "network.ingress.cors_allow_methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS",
    "network.ingress.cors_allow_headers": "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization",
    "network.ingress.proxy_buffer_size_kb": 4,
    "network.ingress.keepalive_time_seconds": 3600,
    "network.ingress.keepalive_timeout_seconds": 60,
    "network.ingress.send_timeout_seconds": 60,
    "network.ingress.proxy_connect_timeout_seconds": 60,
    "network.ingress.proxy_send_timeout_seconds": 60,
    "network.ingress.proxy_read_timeout_seconds": 60,
    "network.ingress.enable_sticky_session": false,
    "network.ingress.whitelist_source_range": "0.0.0.0/0",
    "readiness_probe.type": "TCP",
    "readiness_probe.http_get.path": "/",
    "readiness_probe.initial_delay_seconds": 30,
    "readiness_probe.period_seconds": 10,
    "readiness_probe.timeout_seconds": 1,
    "readiness_probe.success_threshold": 1,
    "readiness_probe.failure_threshold": 9,
    "liveness_probe.type": "TCP",
    "liveness_probe.http_get.path": "/",
    "liveness_probe.initial_delay_seconds": 30,
    "liveness_probe.period_seconds": 10,
    "liveness_probe.timeout_seconds": 5,
    "liveness_probe.success_threshold": 1,
    "liveness_probe.failure_threshold": 9,
    "hpa.cpu.average_utilization_percent": 60,
    "security.service_account_name": ""
}

I’m talking about the one you’re adding into your container (from the Dockerfile above)

I didn’t write any. Using buildpack but have the issue

Actually no problem, I fixed it on my side

I setup an express server with no cache header

/* eslint-disable */

const express = require("express");
const path = require("path");

const port = process.env.PORT || 3000;
const app = express();

app.enable("trust proxy");

if (process.env.NODE_ENV === "production") {
  app.use((req, res, next) => {
    res.setHeader("Cache-Control", "no-cache");

    if (req.protocol !== "https") {
      res.redirect(`https://${req.headers.host}${req.url}`);
    } else {
      next();
    }
  });
}

app.use(express.static(path.join(__dirname, "build"), { etag: false }));

app.get("/*", function (req, res) {
  res.sendFile(path.join(__dirname, "build", "index.html"));
});

app.listen(port);


Thanks for the solution! We’re talking internally to give more control over the Nginx configuration :slight_smile: