How to run Webpack project on apache server - reactjs

I've got a project that runs fine in the dev server environment, but now I am trying to get it to run on an Apache server. I ran 'npm run build' on my package.json file ("build": "babel-node tools/build.js && npm run open:dist"), and it created a dist folder with the following files:
index.html
main.js
main.map.js
main.css
main.css.map
I placed this folder inside of the htdocs folder in my Apache directory. I double clicked on index.html hoping it would take me to the home page of the app, but nothing happens. Not even an error in the console.
Here's the index.html file I'm using:
<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8"/>
<title>Survey Builder</title>
<link href="./dist/app/main.8286783e52fd295f2f9e5d678a8a2acd.css" rel="stylesheet">
</head>
<body>
<div id="app">
</div>
<script type="text/javascript" src="./dist/app/main.66670fe7523b3b72f307.js"></script>
</body>
</html>
Thanks a bunch in advance!

I'll answer my own question.
*If you're using React and you're deploying on Apache, you need to know that the path where you place your files in Apache must be reflected in your React routes. So, if you place your production ready React files inside of a folder in your htdocs Apache directory, you must also reflect that path in your routes. If you dump your production ready files straight into Apache's htdocs directory, it will work out of the box.
I hope this helps...

Related

Published site from dist folder is completely blank? [REACT]

I create a react-app using npx create-react-app and published the app to GitHub using vscode. My repository contains a public folder inside of the main repository that has my index.html file.
Here is my repository on GitHub
I then run the following command in my vscode terminal:
git subtree push --prefix public origin gh-pages
According to this tutorial on how to publish to github with a dist folder I did everything correctly.
When I check my repository it has 2 branches, main and gh-pages however if I go to my deployed site I get a completely blank site. What am I missing here?
The page isn't completely blank, if you visit https://atanasovcode.github.io/product-preview-card/ and view the source, you see the contents of your index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#500;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght#9..144,700&display=swap" rel="stylesheet">
<title>Product Preview Cardp</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
There are some comments in there that seem relevant:
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the tag.
To begin the development, run npm start or yarn start.
To create a production bundle, use npm run build or yarn build.

External script for type="text/babel" not working

Why is an external script for type="text/babel" not working in ReactJS?
I put the index.html and foo.js in the same folder. Nothing show after I open the index.html file with Google Chrome
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>ReactJS</title>
<script src="https://unpkg.com/react#17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
<script type="text/babel" src="foo.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
foo.js
ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById('root')
);
Just include the babel file before the main. It will work as expected.
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
<script type="text/babel" src="./main.js"></script>
You need to run a local server.
For example with https://www.npmjs.com/package/http-server :
npm -g install http-server
cd <path to app>
http-server
Then view your page on http://0.0.0.0:8080
There's also instructions for using python or php to run a local server here https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server .
lite-server package seems a bit more promising https://www.npmjs.com/package/lite-server
In comparison to http-server it:
opens your application immediately in browser
supports HMR
supports file-based configuration
installation and usage is pretty straightforward:
npm install --global lite-server
cd to your folder in terminal and execute lite-server command
If you go to your developer tools in your browser, you should see a message that CORS blocked the request when trying to open index.html:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource
followed by Reason: CORS request not http
This happens because the request origin that calls Babel to convert your React code to a browser compatible Javascript code come from a local file, such as file://, which triggers the CORS error. In order to avoid this error, your request origin should come from a http or https origin, which can be achieved by running a local web server. You can read more details about why it happens at MDN docs
If you have Python 3 installed, run the following command in the terminal, where you index.html is located. If you need help setting Python and the web server, check this MDN documentation:
python3 -m http.server
This will serve your page at http://localhost:8000 and by pasting localhost:8000 into your browser, now it can render your React code correctly.

Runtime environment variable for react app

We have three environments Dev, Staging and Prod. Create-react-app build is quite suitable for all the three environments but the only things change during the build is the environment variable for API endpoint.
We are using the Jenkins pipeline for the build process and putting the output in S3 Bucket, the only problem with that process is that we have to make a separate build for every environment although everything is same except that API environment variable. It takes a significant amount of time.
So I possible solution is to move from compiled environment variable to runtime environment. I came across this. But I don't know how to do it in practical being newbie to Jenkins and AWS
Our folder structure looks like this
Project
|---mocks
|---static
|---index.html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React APP</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
So, I am writing the way we have fixed this. In Jenkinfile file which is placed inside our project repo. We have made following changes for every environment.
Before every stage we simply re-writing the env.js with respective file.
stage('Push to Dev') {
...
steps {
.....
sh 'cp ./config/dev.js ./build/env.js'
.....
}
}

Blank Screen for Express-React app at Production: Uncaught SyntaxError: Unexpected token < | index.html doesn't serve other files

My app works great in the dev environment, where I use proxies. After I pushed to heroku (production), I saw a blank screen. In Chrome Developer Tools, I saw the following two errors:
Unexpected token. manifest.json:1
Uncaught SyntaxError: Unexpected token < main.bac17543.js:1
When i click on these two errors, I saw that the manifest file, the main.css file, and the main.css file all have the HTML file as the source. It fails to load the other files from the client/build/index.html.
Okay, so experimenting with this, I found when I run "npm run dev," it works great on the client port. However, there's an error when the app starts on the server port and serves the index.html file with the following express code shown in the course:
if (process.env.NODE_ENV === 'production') {
//Express will serve up production assets like main.js file
app.use(express.static('/client/build'));
//Express will serve up html file if it doesn't recognize the route
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'client', 'build', 'index.html'))
});
}
This code successfully serves up the html file. But all other files linked within fail.
After several reloads to Heroku, I reproduced the error by taking out the production if statement and navigating to localhost:5000 (sever port). After running "npm run build" from the client folder, I received the same errors when "npm run dev" is run. Even if i switch "build" to "public" to run index.html before "npm run build," I receive the same errors. To test if the html file was called, I wrote <h3>testing html</h3>, and the HTML successfully rendered to the screen as the only content. But it seems that manifest, favicon, css files, and javascript files were not found, returning the original index.html file and throwing an error at the beginning of the file: "<."
Here is my index.html file under the build folder:
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="./manifest.json"><link rel="shortcut icon" href="./favicon.ico"><title>Compass</title><link href="./static/css/main.c092d6b6.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript" src="./static/js/main.bac17543.js"></script></body></html>
And here it is in the public folder:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<h3>this HTML is called, but the javascript file fails when served from Express</h3>
<div id="root"></div>
</body>
</html>
I've tried both absolute and relative paths in the href and src attributes in both folders. Yet still no dice. I'm pretty confident the paths are right because they work otherwise, but for some reason it's not reading correctly. The build paths are server/build/index.html, sever/build/static/css/main.d3f5fbbb.css, and server/build/static/js/main.69f468ec.js.
Perhaps there is some configuration issue? I haven't touched configuration for webpack or anything. I'm just not sure why the buck stops with the HTML file when serving from express. Can you please advise?
I had this same exact issue. I was able to solve the problem by setting my homepage in my react package.json from the github page that was auto filled to the heroku url since that was what was serving the static files.
Found this info to be helpful and led me to checking homepage property in my package.json
https://github.com/facebook/create-react-app/issues/527
Hope this helps or someone else that is trying to deploy express and react from one repo to heroku.

Why won't React production build run on the browser?

I'm trying to build my react app using react's build tool. When I try to "npm start", the app works fine.
npm start
On http://localhost:3000 => I can access the application.
But when I build the application and try to access "index.html" file on the build folder, it doesn't work and I encounter with a white blank screen.
npm run build
http://myreact-app/build/index.html => White blank screen.
This is the build folder which has been created after run npm run build.
And this is the index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="/manifest.json">
<link rel="shortcut icon" href="/favicon.ico">
<title>React App</title>
<link href="/static/css/main.9a0fe4f1.css" rel="stylesheet">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="text/javascript" src="/static/js/main.46d8cd76.js"></script>
</body>
</html>
Am I doing something wrong? Can't I access the built index.html file on my apache web server?
Probably you've not noticed yet but I don't think your html file is able to import css and script files correctly. When I look at your file structure, I see the everything about build is under the build folder. But in your html file, there are slashes ("/") before the file paths. That's why browser is looking for those files under the parent of the "build". Try to remove slashes.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico">
<title>React App</title>
<style></style>
<link href="static/css/main.65027555.css" rel="stylesheet">
</head>
<body
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="text/javascript" src="static/js/main.316f1156.js"></script>
</body>
</html>
The above problem can be overcome if you add
"homepage":".",
in your package.json. This is not official but a good hack to follow.
https://github.com/facebookincubator/create-react-app/issues/1487
To fix this problem go to your build folder then you will see manifest.json file, open it and you will see your manifest.json have:
"start_url": ".",
change it to
"start_url": "/",
there is alternative way to fix the problem:
before your react project build go to your package.json file and specify homepage property with . value or maybe with your site base url, see example:
{
....
"homepage": ".",
......
}
you should try use the serve package here to run single page app.
npm install -g serve to install globally
serve help to see help texts
serve --single build to serve single page app. I server will be started from which you can access your react app
If nothing of above works. Maybe the problem is that you are using react-router-dom and the routes needs a special compilation generating individual htmls for each page that exists in your router config.
Ref:
I'm using create-react-app and I need to open build/index.html in browser directly without a server
In summary you need to use <HashRouter> instead <Router> and a <Switch> wrapper to your routes. For example:
<Switch>
<Route exact path='/' component={WelcomePage} />
<Route exact path='/game' component={GamePage} />
</Switch>
Consider that your routes will change to:
http://localhost:3000/#/ -> Root page
http://localhost:3000/#/game -> Other page
You need to install local server plugin/extenstion.
If you are vscode user then search live server extension and install it. Then there will be "Go live" option in bottom of your editor.
For other editor user (atom/sublime) search for live server plugins.
Sometimes the reason that the content is not served is because the command of "serve -s" was executed from outside of the build directory. The correct way is to go into the build directory then execute "serve -s" from therein.
I had an index.php in the webroot which prevented my app from running index.html.
I use HashRouter instead BrowserRouter & also need to add /# infront of every url like this:
href={`/#/blogs/${slug}`}
this works for me , thanks
Try using <HashRouter> instead of <Router>, and don't forget to import {HashRouter}.

Resources