I have a React app project using Node Express. I'm trying to deploy it on heroku. I think everything is working fine except that my server.jsis looking for index.html file in the wrong folder.
How to solve it?
My folder structure looks like this:
I have logged in to bash in heroku. I have everything there. When I go into dist folder in frontend I can see the dist folder. But when running the server.js it trying to find index.html in the server folder. But it's in frontend. How to solve it?
This is my code in server.js file:
if (process.env.NODE_ENV === "production") {
// Set static folder
app.use(express.static("frontend/dist"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "frontend", "dist", "index.html"));
});
}
Try this
Note: if server.js file is in the server folder.
res.sendFile(path.resolve(__dirname, "../frontend", "dist", "index.html"));
for more detail : path.resolve([...paths])
Related
I have a React app + Node server with the following architecture from the root :
/build
/src
server.js
package.json
etc.
In production, I want to get to the index.html inside the folder "build", so I have this code in the server, but I think I did it wrong :
server.js
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "build")));
app.get("*", function(req, res) {
res.sendFile(path.join(__dirname, "build", "index.html"));
});
}
Can somebody help me ? Thanks
There is nothing wrong with your code, though I don't think there is a need to define a route GET "*". When you serve public static files, they can be accessed directly through the browser.
For now, to debug your app:
Make sure that the "build" directory exists and actually contains an index.html
Log 'NODE_ENV' environment variable, just to make sure that it's set correctly to 'production'.
When I set a static path public folder and set angular index in public:
app.js (node.js):
//node.js static file path
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.get('/*', (req, res) => {
//angular index
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
There are some problems with this setup:
(1)I can't put all angular build files in a specific folder(like put in dist folder), index.html will not be able to take the correct location of the relevant file(like runtime.js)
(2)Some files may be stored in the public folder, such as files uploaded by users. angular build will be clear all files in the folder(public), so I have to pack it in another folder(ex:dist) and manually copy all the files to the public folder. This setting is quite inconvenient, and every time you update it, make sure the old file is cleared.
Update
app.js (node.js):
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/dist', 'index.html'));
// or res.sendFile(path.join(__dirname, 'public', 'dist/index.html'));
});
angular.json:
"outputPath": "server/public/dist/",
angular build
ng build --prod --deploy-url /dist/ --base-href /dist/
When I link index url:
http://localhost:3000/
angular router will be render /index like http://localhost:3000/index,
but node.js it's render http://localhost:3000/dist/index
Can't the URL hide the folder path dist?
Is this the correct way to set up?
For run project on live domain. Follow this steps.
Step 1: Make a build with this command. ng build --prod.
Step 2: In Dist/index.html , Update base URL with your domain name.
Step 3: Make ZIP file of dist folder.
Step 4: Copy and paste ZIP folder into you respective server. you can use filezilla for that.
Step 5: Unzip folder.
Step 6: Update dist folder name to your project folder name.
Step 7: Check on browser.
This is my first project using nodejs and react, I have been working a aplication by following this this tutorial.Its working fine localhost
but not working on prodution mode.I have created a build and its generated a directory called "dist". I have moved everthing to live server from "Dist" folder.
But the node route not working , its says 404 error.How to deploy nodejs with react on production?
Can please help me get rid of it?
Thanks
Your backend server will not know how to handle the routes on your client or know the location of your "client" folder, if you have a dist folder you would need to do something similar to this:
if (process.env.NODE_ENV === 'production') {
app.use(express.static('dist'));
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));
});
}
Hope this helps.
I am having issues w/ serving static files in my current Express app, although I've done a similar setup in a bunch of other apps.. My folder structure is as follows:
/rootfolder/
/app
package.json
/client
/dist
/static
index.html
/server
/src
index.js
Relevant part of my server/src/index.js:
app.use(express.static(path.join(__dirname, "client", "dist")));
Where __dirname = /rootfolder/app/server/src
And when the user hits the / endpoint:
app.get("/", (req, res) => {
res.sendFile(appRoot.path + "/client/dist/index.html");
});
Where appRoot.path = /rootfolder/app
When I hit the / endpoint, I get a status 200 with the following text:
/rootfolder/app/client/dist/index.html
From what I can tell, the files are coded relative to each other correctly.. Does anyone know what I might be doing wrong?
Thanks in advance!
You're using res.send() instead of res.sendFile()
Also I suggest resolving your path via the path module, instead of concatenating a string.
const path = require('path')
app.use(express.static(path.join(__dirname, 'client', 'dist', 'static')))
And for the response of /:
res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html')))
Try
app.use(express.static(path.join(__dirname,'client','dist')));
It basically gets the root directory and combines it with /client+ /dist + /static to give you the full route, without being relative path.
Now Let's call rootdirectory/client/dist X. That is the main directory for static files
If you have other files that are static but not in the same folder, you will have to give relative path from the X directory
Example:
app.get('/',function(req,res){
res.sendFile('/static/data.txt');
}
In the example above you indicate that the static file(data.txt) is located in the X/static directory.
Therefore => rootDirectory/client/dist/static/data.txt
2nd Example:
Let's say you have a folder in dist called images which you want to only store images.
when you are giving routes, you MUST use /images/filename.extention
I must be missing something extremely simple here, because I don't understand how anyone can have a functioning angular-cli app without the ability to do the following...
Context
I have an Angular 2 app with an express.js backend acting as an API. I have switched from webpack to angular-cli to bundle my files as it offers easy Ahead-Of-Time compilation.
What I didn't expect was angular-cli is so opinionated, it even requires me to keep an index.html file inside the angular app directory in my repository (I had previously kept it in /views for express.js to send to clients).
Problem
I am struggling to see how I can load the outputted JS bundles from angular-cli if I have node.js server. Consider the following angular-cli.json snippet:
"apps": [
{
"root": "app",
"outDir": "public/dist",
],
Both my bundle.js files and my index.html will be outputted in public/dist. This means I have to update my node.js routes to change:
// Root
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/../views/index.html'));
});
to:
// Root
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/../public/dist/index.html'));
});
Now the problem is that my public/dist/index.html file has a <base href="/"> tag, and the following generated script tags:
<script type="text/javascript" src="inline.bundle.js"></script><script type="text/javascript" src="vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script>
Well, obviously when I run my node.js server, those above bundles won't be found because they don't exist at the base href's location. There is no /inline.bundle.js, because it's located at /public/dist/inline.bundle.js. So, how can I ever load my frontend app?
I don't this will work, as it expect an absolute path, not relative.
res.sendFile(path.join(__dirname + '/../public/dist/index.html'));
You should point in a relative way all the dist server to / from the express folder, something like:
app.use('/', express.static('../public/dist'));
app.get('*', (req, res) => {
res.sendFile('index.html', { root: '../public/dist' });
});
I handle this kind of problems in a different way. I never send a file using sendFile, instead I only send JSON data.
Sending a file is suitable for traditional non-SPA applications. Sending JSON data is suitable for modern SPA applications.