Containerized webpack-dev-server doesnt respond to file change - reactjs

I have a React app running as part of a docker-compose setup, with the following configuration:
version: "3.7"
services:
client:
image: node:10-jessie
volumes:
- ./client:/app:rw
ports:
- 9000:9000
working_dir: /app
command: npm run dev
...
The client folder that the volume points to, has webpack.config.js and the src folder. When i run docker-compose up the application loads up fine. I can navigate to localhost:9000 and view my app, and by navigating to the console, i can see that Live reloading is enabled.
But when i make changes to the files, which webpack-dev-server would detect and update had i run the app locally, no changes are captured. If i refresh the page manually, the changes are not detected either.
Are there anyone with any suggestions as to what i am doing wrong? I will happily provide more of my code, i just wasn't sure what else was needed to initially convey my problem.

I solved the problem by adding the following to my webpack.config.js:
watchOptions: {
ignored: /node_modules/,
aggregateTimeout: 300,
poll: 500
},

Related

React hot reload doesn't work in docker container

I am trying to set up React with docker, but for some reason I cannot get the hot reload to work. Currently, if I create a file it recompiles, but if I change something in a file it does not. Also, I didn't change any packages or configuration files, the project was generated with npx create-react-app projectname --template typescript.
From researching this online I found out that I needed to add CHOKIDAR_USEPOLLING=true to a .env file, I tried this but it didn't work, I tried placing the .env in all directories in case I placed it in the wrong one. I also added it to the docker-compose.yml environment.
In addition to this, I also tried downgrading react-scripts to 4.0.3 because I found this, that also didn't work.
I also tried changing a file locally and then checking if it also changes inside the docker container, it does, so I'm pretty sure my docker related files are correct.
Versions
Node 16.14
Docker Desktop 4.5.1 (Windows)
react 17.0.2
react-scripts 5.0.0
Directory structure
project/
│ README.md
│ docker-compose.yml
│
└───frontend/
│ Dockerfile
│ package.json
│ src/
│ ...
Dockerfile
FROM node:16.14-alpine3.14
WORKDIR /app
COPY package.json .
COPY package-lock.json .
RUN npm install
CMD ["npm", "start"]
docker-compose.yml
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- "./frontend:/app"
- "/app/node_modules"
environment:
CHOKIDAR_USEPOLLING: "true"
If you are on Windows and use react-scripts 5.x.x or above, CHOKIDAR_USEPOLLING is not working. Make changes your package.json instead in the following way:
"scripts": {
...
"start": "WATCHPACK_POLLING=true react-scripts start",
...
}
The Dockerfile you have is great for when you want to package your app into a container, ready for deployment. It's not so good for development where you want to have the source outside the container and have the running container react to changes in the source.
What I do is keep the Dockerfile for packaging the app and only build that, when I'm done.
When developing, I can often do that without a dockerfile at all, just by running a container and mapping my source code into it.
For instance, here's a command I use to run a node app
docker run -u=1000:1000 -v $(pwd):/app -w=/app -d -p 3000:3000 --rm --name=nodedev node bash -c "npm install && npm run dev"
As you can see, it just runs a standard node image. Let me go through the different parts of the command:
-u 1000:1000 1000 is my UID and GID on the host. By running the container using the same ids, any files created by the container will be owned by me on the host.
-v $(pwd):/app map the current directory into the /app directory in the container
-w /app set the working directory in the container to /app
-d run detached
-p 3000:3000 map port 3000 in the container to 3000 on the host
--rm remove the container when it exits
-name=nodedev give it a name, so I can kill it without looking up the name
at the end there's a command for the container bash -c "npm install && npm run dev" which starts by installing any dependencies and then runs the dev script in the package.json file. That script starts up node in a mode, where it hot reloads.
Polling wasn't my issue -- watching the docker output I saw it recompiled correctly. My problem was related to networking in the hot loader. I found that the browser is trying to open a websocket back to the node server to ws://localhost:3000/sockjs-node but whatever network settings are like on my computer, this wouldn't route back to the docker container. I added
WDS_SOCKET_HOST=127.0.0.1
to the environment variables. After restarting, the browser successfully connects to ws://127.0.0.1:3000/sockjs-node and hot reloading works properly.
This was tied to using a docker-compose solution similar to the original post. I was able to also make things with with a variation on the docker run approach, but it was much slower to launch.
WSL Workaround for CRA 5.0+
watch.js
const fs = require('fs');
const path = require('path');
if (process.env.NODE_ENV === 'development') {
const webPackConfigFile = path.resolve('./node_modules/react-scripts/config/webpack.config.js');
let webPackConfigFileText = fs.readFileSync(webPackConfigFile, 'utf8');
if (!webPackConfigFileText.includes('watchOptions')) {
if (webPackConfigFileText.includes('performance: false,')) {
webPackConfigFileText = webPackConfigFileText.replace(
'performance: false,',
"performance: false,\n\t\twatchOptions: { aggregateTimeout: 200, poll: 1000, ignored: '**/node_modules', },"
);
fs.writeFileSync(webPackConfigFile, webPackConfigFileText, 'utf8');
} else {
throw new Error(`Failed to inject watchOptions`);
}
}
}
package.json
"scripts": {
"start": "node ./watch && react-scripts start",
I had same issue once, This issue was in my Dockerfile The workdir was /var/app/ while in my docker-compose.yml I mounted current working directory to /var/app/frontend, I just removed that /frontend and works fine. please check yours. thanks
Make sure you use --legacy-watch tag in package.json file
{
"name": "history",
"version": "1.0.0",
"description": "",
"main": "./src/index.js",
"scripts": {
"start": "node ./src/index.js",
"start:dev": "nodemon --legacy-watch ./src/index.js"
},
I had the same issue, and my mistake was that I was editing on my local machine and was expecting code reload inside the docker container. Since 2 of them are at different locations - it will never work out and I had to restart the docker-compose again and again.
Later I used the vscode command palette
"Attach to Running Container..."
option and the selected required container and cd into my code folder and made changes and live reload (or apply code changes on the refresh page) started working.
This helped me solve one issue, the next issue is to use the local ssh-key inside the docker container such that I can do my git sync inside the container itself.
Setting the NODE_ENV="development" in the Dockerfile enables the hot reload

Vite Server is running but not working on localhost

Vite + Reactjs server is running but I am getting
"This localhost page can’t be found
No webpage was found for the web address: https://localhost:4200/"
on the browser
A common mistake when moving from create react app/react-scripts to Vite is having the index.html in the public folder.
Make sure your index.html file is in the root directory for your Vite project.
TLDR: Change the Port
For me, it was that I already had something running on the port that Vite was trying to serve the app on (3000).
Doing a quick lsof -nPi :3000 (MacOSX) I saw that my docker desktop was running on that port.
You can do this statically by updating a server key in the vite config (vite.config.js)
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
port: 8000
}
})
Or dynamically via the start command:
vite --port 8000
https://vitejs.dev/config/#config-file
I had the same problem and it was related to the project folder name.
It had some spaces in the name of the project's folder.
I removed spaces and the node_module folder then I installed packages again, and now it's working fine.
Just in case someone is looking for a solution and the other answers didn't work, here is what worked for me.
In vite.config.js I had to set the host to '127.0.0.1' in the server options.
{
server: {
host: '127.0.0.1'
}
}
The default value is localhost but why that doesn't work I still don't know...
I got the same problem. click collapse your project structure in vscode, vite config file was not at the level of index.html. So make sure it should be at where index.html is, Double check please!!
My issue that happened to me that seems possible to commonly happen was I had another index.html file in my public dir. That file will take precedence over the one in your project root, so make sure you delete that or move it elsewhere. For me, it was a remnant of a vite build that I didn't notice hung around
None of the answers here helped me. It turns out uBlock Origin was preventing the index.html page from loading when accessing it through localhost:3000. Disabling it or trying it in incognito mode works!
For me, beside server host true in the vitejs settings, I needed to update the docker run command with "--service-ports" (https://docs.docker.com/engine/reference/commandline/compose_run/):
docker-compose -p myservice run --service-ports --rm node npm run dev
I have the same issue, but there was nothing using the port 3000, but anyways, I change it to port 8000 and it's working
export default defineConfig({
plugins: [react() tsconfigPaths()],
server: {
port: 8000
}
});

React source code exposed in AWS amplify deployment

I am testing deployment of an app on AWS amplify. These are the steps I followed:
created a sample create-react-app (called deploy_test app here),
Pushed the code to a GitHub repo
AWS Amplify console > Deploy app > linked GitHub repo > used default config (as shown below)
version: 1
frontend:
phases:
preBuild:
commands:
- yarn install
build:
commands:
- yarn run build
artifacts:
baseDirectory: build
files:
- '**/*'
cache:
paths:
- node_modules/**/*
The deployment works beautifully, even when I push new changes. The issue is that I can see the entire source code in the Chrome Dev Tools (as shown below). Any tips on how I can resolve this?
by default, create-react-app will generate full sourcemaps:
A build script to bundle JS, CSS, and images for production, with hashes and sourcemaps.
https://github.com/facebook/create-react-app#whats-included
you can set GENERATE_SOURCEMAP=false before the build script:
build:
commands:
- GENERATE_SOURCEMAP=false yarn run build
you can see it defined in the source code of create-react-app webpack config:
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js#L43-L46

Loopback 4 served static files not showing on kubernetes

everyone. Have been banging my head against this for a while, and maybe someone else has a better idea of what my issue is. I have a react and lb4 application and I want to host it on our kubernetes cluster. I build the react project and put it into a build folder in my lb4 project and serve those files while using the lb4 backend also for APIs. I put everything in a docker container, and when I run the container locally, it works as I would expect. When I put the container on kubernetes, I am able to hit the APIs from the loop back project but get a 404 when trying to hit the GUI.
In my LB4 project, I have this to serve the static files:
constructor(options: ApplicationConfig = {}) {
super(options);
// Set up the custom sequence
this.sequence(MySequence);
// Set up default home page
this.static('/',path.join(__dirname, '../build'));
// Customize #loopback/rest-explorer configuration here
this.bind(RestExplorerBindings.CONFIG).to({
path: '/explorer',
});
this.component(RestExplorerComponent);
this.projectRoot = __dirname;
and here is my docker file that I'm using:
RUN mkdir -p /src/app
COPY . /src/app
WORKDIR src/app
ARG env_name
ENV NODE_ENV=env_name
ENV PUBLIC_PATH "/"
RUN npm install
RUN npm run build:client
COPY /src/client/build /src/server/
EXPOSE 3001
CMD ["npm", "run", "start"]
Anyone notice anything that might be the issue? Would appreciate it greatly. Thanks.
Edit: Kind of found the issue, I think. Looks like the copying of the static files at the copy step in my dockerfile doesn't quite work as I intended, so I think it's looking at an empty folder on the kubernetes cluster. Now just to see why that isn't working.

Need help getting pm2 to run a react app that has webpack configured in a dev server

Forgive me I am new to programming in general. I'm having trouble a lot of trouble trying to use pm2 to run a react app that has webpack set up. We are using an apache server for the production. For work we are trying to have the development server constantly running, the way that webpack dev server would have had it running so that more than one person can work on it at the same time. I thought I had enabled and got the app running but I am not sure if I am pointing to the wrong source file or if it should be pointing to a script or if I'm using the wrong interpreter.
I've looked into this https://github.com/facebook/create-react-app/issues/774 but having installed webpack the react scripts stopped working because of babel-cli. I can't afford to go back to react scripts at this point since I spent so much time trying to configure webpack.
Was wondering if anyone can guide me as to where the script in the pm2 should point to for react? is it the index.js? or is it the webpack.config file that i set up? And if I'm using webpack where should I point the interpreter to if i have webpack set up with babel?
Any help would be appreciated.
This is my pm2 config file.
module.exports = {
apps: [{
name: "ucdirectorapp",
script: "./src/index.js",
watch: [
"./build",
"./public",
"./src",
".babelrc",
"package.json"
],
watch_delay: 1000,
ignore_watch: ["node_modules"],
watch_options: {
"followSymlinks": false
},
env: {
name: 'ucdirector-dev',
NODE_ENV: 'development',
"PORT": 3000,
},
error_file: "./resource/log/pm2/err.log",
out_file: "./resource/log/pm2/out.log",
log_file: "./resource/log/pm2/log.log",
max_memory_restart: "500M",
interpreter: "./node_modules/#babel/cli/bin/babel.js"
}],
};
I've been using this script pm2 start config/server/pm2.config.js --watch --interpreter ./node_modules/#babel/cli/bin/babel.js in the package.json
I get this error
[PM2][ERROR] NVM is not available in PATH
[PM2][ERROR] Fallback to node in PATH
and I get a babel parse error. The app's status seem to be online but nothing is showing up on the host at port 3000 saying the site can't be reached and that it refused to connect.

Resources