reactjsgoogle-cloud-runcraco

Deploy React Craco app to GCP Cloud Run Error: React Refresh runtime should not be included in the production bundle


I am trying to deploy a React app with Craco to GCP Cloud Run. I am using the Cloud Code in Visual Studio Code to deploy. It say deployment is successful, but I am getting really weird error when viewing in browser, it runs locally just fine, please help.

For build, I am using the remote build option in GCP, it autmatically create a dockerfile and use nginx to build I guess? It's really confusing.

My package.json

{
  "name": "material-app",
  "version": "3.1.0",
  "description": "Material App Pro - React Admin & Dashboard Template",
  "author": "Bootlab <support@bootlab.io>",
  "private": true,
  "license": "https://material-ui.com/store/license/",
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "eject": "craco eject",
    "lint": "eslint src --ext .js,.jsx --fix"
  },
  "browserslist": [
    "> 0.5%",
    "last 2 versions",
    "Firefox ESR",
    "not dead",
    "not IE 11"
  ],
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "dependencies": {
    "@auth0/auth0-spa-js": "1.18.0",
    "@craco/craco": "6.3.0",
    "@date-io/date-fns": "2.11.0",
    "@fullcalendar/core": "5.9.0",
    "@fullcalendar/daygrid": "5.9.0",
    "@fullcalendar/interaction": "5.9.0",
    "@fullcalendar/react": "5.9.0",
    "@mui/icons-material": "5.0.0",
    "@mui/lab": "5.0.0-alpha.47",
    "@mui/material": "5.0.0",
    "@mui/styled-engine-sc": "5.0.0",
    "@mui/styles": "5.0.0",
    "@mui/system": "5.0.0",
    "@mui/x-data-grid": "5.0.0-beta.1",
    "@reduxjs/toolkit": "1.6.1",
    "amazon-cognito-identity-js": "5.1.1",
    "axios": "0.21.4",
    "axios-mock-adapter": "1.20.0",
    "chart.js": "3.5.1",
    "css-vendor": "2.0.8",
    "csvtojson": "^2.0.10",
    "d3": "^7.1.1",
    "date-fns": "2.24.0",
    "deepmerge": "4.2.2",
    "faker": "5.5.3",
    "firebase": "8.10.0",
    "formik": "2.2.9",
    "google-map-react": "2.1.10",
    "history": "5.0.1",
    "i18next": "20.6.1",
    "jsonwebtoken": "8.5.1",
    "jss": "10.8.0",
    "jwt-decode": "3.1.2",
    "polished": "4.1.3",
    "react": "17.0.2",
    "react-app-polyfill": "2.0.0",
    "react-chartjs-2": "3.0.4",
    "react-dom": "17.0.2",
    "react-dragula": "1.1.17",
    "react-feather": "2.0.9",
    "react-helmet-async": "1.1.2",
    "react-i18next": "11.12.0",
    "react-jvectormap": "0.0.16",
    "react-perfect-scrollbar": "1.5.8",
    "react-quill": "2.0.0-beta.4",
    "react-redux": "7.2.5",
    "react-router-dom": "6.0.0-beta.4",
    "react-scripts": "4.0.3",
    "react-syntax-highlighter": "15.4.4",
    "redux": "4.1.1",
    "redux-thunk": "2.3.0",
    "styled-components": "5.3.1",
    "web-vitals": "2.1.0",
    "yup": "0.32.9",
    "craco-alias": "3.0.1"
  },
  "devDependencies": {
    "@babel/preset-env": "7.15.6",
    "redux-devtools-extension": "2.13.9"
  },
  "resolutions": {
    "jss": "10.8.0"
  },
  "optionalDependencies": {
    "fsevents": "^2.3.2"
  }
}

My Craco config file:

const CracoAlias = require("craco-alias");

module.exports = {
  plugins: [
    {
      plugin: CracoAlias,
      options: {
        source: "options",
        baseUrl: "./",
        aliases: {
          "@mui/styled-engine": "./node_modules/@mui/styled-engine-sc",
        },
      },
    },
  ],
};

My .docker file:

# build environment
FROM node:14-alpine as react-build
WORKDIR /app
COPY . ./
RUN yarn
RUN yarn build

# server environment
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/configfile.template

COPY --from=react-build /app/build /usr/share/nginx/html

ENV PORT 8080
ENV HOST 0.0.0.0
EXPOSE 8080
CMD sh -c "envsubst '\$PORT' < /etc/nginx/conf.d/configfile.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"

My nginx.inf

server {
     listen       $PORT;
     server_name  localhost;

     location / {
         root   /usr/share/nginx/html;
         index  index.html index.htm;
         try_files $uri /index.html;
     }

     gzip on;
     gzip_vary on;
     gzip_min_length 10240;
     gzip_proxied expired no-cache no-store private auth;
     gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
     gzip_disable "MSIE [1-6]\.";

}

The error I am getting:

Error: React Refresh runtime should not be included in the production bundle.
./node_modules/react-refresh/cjs/react-refresh-runtime.production.min.js
node_modules/react-refresh/cjs/react-refresh-runtime.production.min.js:10
__webpack_require__
/workspace/webpack/bootstrap:856

What does it mean?


Solution

  • Okay fixed it, modify the start script to this:

    node server.js
    

    Then add a server.js file in your root directory with this content:

    //server.js
    const express = require('express');
    const favicon = require('express-favicon');
    const path = require('path');
    const port = process.env.PORT || 8080;
    const app = express();
    app.use(favicon(__dirname + '/build/favicon.ico'));
    // the __dirname is the current directory from where the script is running
    app.use(express.static(__dirname));
    app.use(express.static(path.join(__dirname, 'build')));
    app.get('/ping', function (req, res) {
     return res.send('pong');
    });
    app.get('/*', function (req, res) {
      res.sendFile(path.join(__dirname, 'build', 'index.html'));
    });
    app.listen(port);
    

    It works now, craco was definitely the problem.