React app changes not updaiting after running npm run build - reactjs

I have a react app with the following file structure:
When I run npm run build the app compiles everything using webpack and npm gives me the following output:
In the output (build folder), it creates an asset-manifest.json file, containing the newly created files:
{
"files": {
"main.css": "/static/css/main.607e5368.chunk.css",
"main.js": "/static/js/main.08012c8a.chunk.js",
"main.js.map": "/static/js/main.08012c8a.chunk.js.map",
"runtime~main.js": "/static/js/runtime~main.a8a9905a.js",
"runtime~main.js.map": "/static/js/runtime~main.a8a9905a.js.map",
"static/css/2.8643d4fb.chunk.css": "/static/css/2.8643d4fb.chunk.css",
"static/js/2.1aae919f.chunk.js": "/static/js/2.1aae919f.chunk.js",
"static/js/2.1aae919f.chunk.js.map": "/static/js/2.1aae919f.chunk.js.map",
"index.html": "/index.html",
"precache-manifest.ca81004b99ff7fc6f769d98332234f01.js": "/precache-manifest.ca81004b99ff7fc6f769d98332234f01.js",
"service-worker.js": "/service-worker.js",
"static/css/2.8643d4fb.chunk.css.map": "/static/css/2.8643d4fb.chunk.css.map",
"static/css/main.607e5368.chunk.css.map": "/static/css/main.607e5368.chunk.css.map",
"static/media/index.scss": "/static/media/slick.f97e3bbf.svg"
}
}
However, if I go into my browser the react app doesn't update and keeps using the old filenames. If I go to the network inspector I can see that the files are loaded with 200 OK (from ServiceWorker).
Why are the newly genrated files not being used in the new index.html?
I've tried clearing my cache, using a clean installation of the template, using another browser, using incognito mode,...

It is due to service worker. Unregister your service worker to show updated content
In your index.js or whatever is main file in react app
// import registerServiceWorker from './registerServiceWorker'; // comment this line
import { unregister } from './registerServiceWorker';
Comment registerServiceWorker()
// registerServiceWorker()
unregister();// add this

Related

Rendering problem with React app inside Docker container

The React app described below is built in VS Code with React v18.0.0, node v.14.15.4 and npm v8.4.1. It also imports modules from a 3rd party mapping API called the ArcGIS JavaScript API and I'm running v4.18 of that.
I've used this mapping API to create many vanilla JS web apps over the years. I reference its JS and CSS via CDN. The current need is to leverage it within a React app that's deployed in a Docker container running NGINX.
I can launch the app from VS Code using 'npm start'. It runs at localhost:3000 and everything works as expected. The map renders within the correct div and it shows the gray canvas basemap tiles. The CSS is also loading correctly and the zoom +/- buttons render correctly. All of this correct behavior happens when the app is launched locally. I can deploy it IIS or I can just run 'npm start' in VS Code and it runs without issues. This is how it displays:
Code within the React app that creates the map and map view:
import logo from './logo.svg';
import './App.css';
import { useEffect, useState, useRef } from "react";
import esriConfig from "#arcgis/core/config";
import Map from "#arcgis/core/Map";
import MapView from "#arcgis/core/views/MapView";
import FeatureLayer from "#arcgis/core/layers/FeatureLayer";
function App() {
const mapRef = useRef();
esriConfig.apiKey = "REMOVED";
const initMap = () => {
const map = new Map({
basemap: "arcgis-light-gray",
layers: []
});
const view = new MapView({
map: map,
center: [-82.354, 27.895],
zoom: 9,
container: mapRef.current,
});
};
useEffect(() => {
initMap();
}, []);
return (
<div className="App">
<div id="map-div" ref={mapRef}>
</div>
</div>
);
}
export default App;
All of the above works when hosted locally or builT and deployed to IIS.
But the ultimate goal is to deploy this app within a Docker container running NGINX. The docker image builds successfully and also runs successfully, but when I browse the app running inside the container the basemap tiles don't render. CSS and JS are both being loaded, I get 200 responses for both. The 3rd party content is loading but for some reason the images tiles in the map don't render and all I get is a map with a blank background.
I get the same result in Chrome and Edge. There are no errors or exception thrown in the browser's console. It's as if the JS API is loading successfully but somehow the image tiles aren't rendering and I can't see any reason why this would fail only inside a Docker container.
Dockerfile
FROM node:latest as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:latest
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/build/ /usr/share/nginx/html/
.dockerignore file
node_modules
Dockerfile
.git
default.conf for NGINX
server {
listen 80;
listen [::]:80;
root /usr/share/nginx/html;
index index.html index.htm index.nginx-debian.html;
server_name localhost;
location / {
try_files $uri $uri/ =404;
}
}
Because I have other React apps with ArcGIS JS maps working perfectly, I believe the problem has to have something to do with Docker and/or NGINXand how it is failing to handle the image tiles correctly.
I also noticed some differences in the requests being made by each version of this app. In the network tab of Chrome's developer tools it looks like the app makes an extra call when running locally that is not made when it's running in a docker container.
Locally it makes two calls to LightGray:Base and LightGray:Labels, and also World_Basemap_v2 further down.
I see fewer calls for the light gray basemap resource in the Docker container and no request for World_Basemap_v2 at all.
Unfortunately I don't know if the above differences are significant at all.
Has anyone else had any issues along these lines? I've already called for help on the ArcGIS forum but I sense that almost nobody is trying to run this API within Docker.
Thanks
Update & Work-Around
Uninstalling #arcgis/core and installing esri-loader instead resulted in correct rendering of the basemap I'm using.
import logo from "./logo.svg";
import "./App.css";
import { loadModules } from "esri-loader";
function App() {
loadModules(['esri/config', 'esri/views/MapView', 'esri/Map']).then(([esriConfig, MapView, Map]) => {
esriConfig.apiKey = "REMOVED";
const map = new Map({
basemap: 'arcgis-light-gray'
});
const mapView = new MapView({
map: map,
zoom: 10,
center: [-82.5, 28],
container: "map-div"
});
});
return (
<div className="App">
<div id="map-div"></div>
</div>
);
}
export default App;
I found two work-arounds.
The problem seems to be with the esriConfig module, specifically defining an API key within a React app. A key is required to use the premium set of basemaps which includes the one I'm using, "arcgis-light-gray". I have always defined my developer API key in my ArcGIS JS apps and I've done so in this React app as well. But this module appears to be broken in React. Either that or I need to reference the module differently than I currently am. If so, it's not covered in any documentation I could find.
Work-around #1 - use a non-premium basemap like "gray" or "gray-vector". These basemaps lack the same level of detail at higher zoom levels, making this approach unacceptable if you want to zoom in to larger scales and see detail on individual parcels.
Work-around #2 - uninstall #arcgis/core and install esri-loader instead. This set of modules appears to be the better way to use the ArcGIS JS API in React. With esri-loader the modules are imported with the loadModules function instead of require or import. After refactoring the app to use esri-loader I am now able to define my API key and the premium "arcgis-light-gray" basemap renders correctly. I'll put updated code in the original post.

Fetch React components from server

I am working on ReactJs for a will. I used Typescript in both client and server side for development. I used npm run build to build my project, I will deliver only the build folder now.
Client:
Client
build
-static
-index.html
Server
node_modules
src
package.json
package-lock.json
tsconfig.json
everything is file, For few cases I need get ReactjsComponents from server. These new Components are created by each user.
New ReactJs
ButtonList
ButtonListComponent.tsx
index.ts
IProps.ts
I converted .tsx file to .js using babel
ButtonList
ButtonListComponent.d.ts
ButtonListComponent.js
index.d.ts
index.js
IProps.d.ts
IProps.js
And In server I rendered to plain html and sent the html as string to client and printed.
ReactHelper.ts
import React from 'react'
import * as ReactDOMServer from 'react-dom/server'
import ButtonList from '../../NewComponents/ButtonList'
export function ExportReactComponent(){
var reactHtml = ReactDOMServer.renderToStaticMarkup(ButtonList);
return reactHtml
}
But I used functional Components and materialUI the hooks are not working. So instead of create reactComponents and converting to js. I wrote Plain html and sent to client for printing. but in those case scripts are not working.
ReactHelper.ts
export function ExportReactComponent(){
var htmlInput = `<h1>The script element</h1>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
`;
return htmlInput
}
someone help me, if tried these things but not works as expected, is there any other good solution to this? Thanks in advance.
Git repo: https://github.com/nivedhauswin/ReactApp.git
I used Iframe to display user components. I want to track location change in Iframe contentWindow.location.href but i get
SecurityError: Blocked a frame with origin "http://localhost:3000" from accessing a cross-origin frame.

service worker does not install reactjs

Good evening, I'm trying to work with Reactjs and ServiceWorker to create a PWA but when creating a new project everything seems to work fine but when running npm run build and dispatch the result with npm's http-server opens the application correctly but the browser never records that there is a service worker.
I have already dealt with 3 projects and different browsers but everything remains the same.
The projects are as they are installed with create-react-app.
Does anyone know why the service worker is not installed?
Attached image of how it is not registered by the browser even though it is in the build folder.
If I do this without using react as proof with a simple service worker file if I can register it but with reacrt I do not get it that way.
Thanks.
Does you import your SW in the App entry point module? Example:
// index.js:
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Thanks partners. I was able to solve it by modifying in line src / index.js the line 1 that I had:
serviceWorker.unregister();
By: serviceWorker.register();
And now it works.
Regards!

Do we have to restart webserver everytime we made changes?

I've just cloned a repo from github, and started the server and able to see the default text showing at http://localhost:8080
The default text is showing inside src/components/app.js. And making any changes to the text, simply switch back to browser and reload the webpage to see the changes.
Now I try to create the src folder from scratch, so I've deleted src and recreated it and added a file index.js, without any content. (My web server is still running all this while)
So my question is, when I reload the webpage, I was expecting no content to be showing in the webpage. But truth is I can still see the previous changes showing on webpage. It seems to be cached or something? In order to reflect the latest changes, I have to kill the webserver and npm start again.
This is my first timer in Web Development so wondering if it's a common scenario and best practices to restart webserver everytime we make any changes?
Usually when developing with react you don't even have to refresh the page you are in. Once you save the changes in the Editor they sould be visible in the browser immediately. Maybe you have made a mistake by setting up the index.js
When starting with react I would suggest you to use https://github.com/facebook/create-react-app
With that it's very easy to start and you can play around a bit and get started with React.
You should use Hot Module Replacement.
Here is an example:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
ReactDOM.render(
<App />,
document.getElementById('root')
);
if (module.hot) {
module.hot.accept();
}
Hot Module Replacement (HMR) is a tool to reload your application in the browser, so that the
browser doesn’t perform a page refresh.
BTW #Zander is right, you don't have to kill the server. The page automatically refreshes. For your help, I hope you installed create-react-app using npm as
npm install -g create-react-app and to initiate a new app as create-react-app yourApp. If done so, everything basic is automatically configured.

create react app - npm run build issues

I am using create-react-app to build an application and when I run npm run build it creates a build folder with static folder inside it which is expected.
build--> static
But when I see the index.html file inside the build folder, the path to assets is /static and not /build/static which is why the page does not load properly as it is missing the assets .
Is there any config setting I can do to fix this problem ?
If all you want is to run your app, all that you have to do is run the command: npm start
But, if you are really trying to prefix the static references to upload your code on an specific subdirectory you should add on your package.json the homepage you want to use on your create-react-app.
So, if you want your react app to use /build in the beginning of each reference you should add the following line to your package.json:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"homepage": "/build",
...
}
The following message is displayed when you generate your build without the homepage in the configurations:
The project was built assuming it is hosted at the server root.
To override this, specify the homepage in your package.json.
For example, add this to build it for GitHub Pages:
"homepage" : "http://myname.github.io/myapp",
The build folder is ready to be deployed.
You may serve it with a static server:
yarn global add serve
serve -s build```
But when I see the index.html file inside the build folder, the path to assets is /static and not /build/static
This behaviour is expected.
You're supposed to deploy the build folder and serve the application from it. Since index.html is inside build, it would be served for /, and files in build/static/* will be served for /static/*.
For more specific instructions for this, please read the Deployment section of the User Guide.
It sounds like you're trying to use unimported assets.
I prefer to create an assets folder and place these sort of files here, and then import/use them accordingly.
From the documentation:
import React from 'react';
import logo from './logo.png'; // Tell Webpack this JS file uses this image
console.log(logo); // /logo.84287d09.png
function Header() {
// Import result is the URL of your image
return <img src={logo} alt="Logo" />;
}
export default Header;
If you really want to use the public folder, you can use the PUBLIC_URL variable.
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

Resources