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?
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.