Nuxt & Express server not getting api requests in production /dist - javascript

I have a Nuxt app running successfully on my local server and all API requests are successfully running from the same server (using the serverMiddleware property in nuxt.config.js). When I run a yarn generate, the path to the API server is lost and no data is loaded. Below are a few screenshots.
Loads data successfully from the API.
Unable to find API
Here is an example of an api call in project_dir api/index.js file
const express = require("express");
const passport = require("passport");
const allRoutes = require("../api/routes/routes");
const guestRoutes = require("../api/routes/guest");
const fileUpload = require("express-fileupload");
const path = require("path");
// Create express instance
const app = express();
// Init body-parser options (inbuilt with express)
app.use(express.json());
app.use(fileUpload());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "../", "dist")));
/**
* -------------- PASSPORT AUTHENTICATION ----------------
*/
// Need to require the entire Passport config module so index.js knows about it
require("./config/passport-jwt");
// Initialize Passport
app.use(passport.initialize());
/**
* -------------- ROUTES ----------------
*/
// Imports all of the routes from ./routes/index.js
app.use(guestRoutes);
app.use(passport.authenticate("jwt", { session: false }), allRoutes);
console.log("express");
console.log(path.join(__dirname, "../", "dist"));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "../", "dist", "index.html"));
});
// Export express app
module.exports = app;
I don't know why I'm not able to get data from the API routes which I'm running on the same server.

Here is an in-depth answer on how to run an Express server alongside Nuxt: https://stackoverflow.com/a/72102209/8816585
First thing to know, is that you cannot have a Node.js server with yarn generate because it's using target: 'static' and as you can guess, when something is static, it doesn't need a Node.js server to be served to the end-user (only the html + css + js static files are hosted on a CDN or alike).
This mode is meant to host the code on Netlify, Vercel or alike, with no Node.js server available there.
Why is it working locally? Because you do have a Webpack dev server running (with a Node.js server so) for debugging purposes like HMR etc...
TDLR: this is normal (works as intended so far). More info on the given link above on how to make it work.

After much research and debugging I came up with a new idea.
Instead of running npm run start or yarn start containing script "nuxt start" inside the package.json file. I added a new script with the name "express-start": "cross-env NODE_ENV=production node api/index.js". Which runs the express server and nuxt static files.
I'm currently creating a template to make it easier for those who'll face this challenge.
Link to a boilerplate I created after solving the issue.
ExpressJs & NuxtJs Boilerplate

Related

Restart NodeJS app automatically after app crashes

I want to add code to my NodeJS (Express) app so that it will restart automatically after crashes with some error. I know about forever npm package, but I found only examples with running app in development, while my goal is to use it in production (app is already on production server). Should I add some code inside app.js (main file for my application) or in different files?
Here's my app.js code:
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const path = require("path");
const con = require("./databaseConnection");
const app = express();
/* Middleware */
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
/* Redirect http to https */
app.enable('trust proxy');
app.use (function (req, res, next) {
if (req.secure) {
// request was via https, so do no special handling
next();
} else {
// request was via http, so redirect to https
res.redirect('https://' + req.headers.host + req.url);
}
});
/* Routers */
const authRouter = require("./routers/authRouter");
const userRouter = require("./routers/userRouter");
app.use("/auth", authRouter);
app.use("/user", userRouter);
app.listen(5000);
I think the program you are looking for is pm2. https://pm2.keymetrics.io/docs/usage/quick-start/
You could listen for any unhandled exceptions/errors and handle them to stop the server crashing because of an uncaught error, but there are a bunch more problems that could happen with the process itself that would go unhandled such as memory leaks, which is why you need to use a process manager rather than something internal inside your express server.
It's better to use the pm2 daemon to manage the server processes for you, it also comes with a built-in dashboard, logging, and useful restarting configuration options such as
Restart app at a specified CRON time
Restart app when files have changed
Restart when app reach a memory threshold
Delay a start and automatic restart
Disable auto restart (app are always restarted with PM2) when crashing or exiting by default)
Restart application automatically at a specific exponential increasing time

how can I render the css files when i use express.js?

I am grouping my files like so:
node_modules
structures
{HTML Files}
styles
{CSS Files}
app.js
package-lock.json
package.json
I've already required those:
const express = require('express');
const app = express();
const path = require('path')
what do I do next?
I assume that you're somewhat of a beginner with Node/Express.
I recommend you learn more about how express works before deploying this into an actual app.
Let's get something straight: I believe that you only have a group of HTML files that you want to show to the user under the file names eg. example.com/about.html with the homepage HTML file being called index.html so that express knows what to show where.
This is the simplest way I could think i'd achieve this effect.
const express = require('express');
const app = express();
const path = require('path');
// This is the port where the application is running on
// Uses the server's enviroment variable named PORT if is defined else
// this will use port 5000
// the page can be seen locally at http://localhost:5000/
const PORT = process.env.PORT || 5000;
// This line makes the app created earlier use the middleware that express provides for "rendering" static files
// inside the express.static method we give a path to the static files
// to create that path we use the path.join method provided by the path module we imported earlier
// this method takes in all the paths that need to be joined.
// the __dirname is the directory the application was launced from (you can use process.cwd() to get the root)
// and ofcourse the structures is the folder which contains all your HTML files
app.use(express.static(path.join(__dirname, "structures")));
// Now we do the same thing we did before but we add the middleware for the styles under the "/styles" URI.
app.use("/styles", express.static(path.join(__dirname, "styles")));
// This will start the server at the PORT which we defined earlier.
app.listen(PORT);

Refresing a vue app gives: Cannot GET /path

I have a simple webpack template vue app, and let's say I have a page with
http://localhost:8080/profile
On my local page, I can go from any page to /profile and even once on /profile I can refresh/reload the page and I get no error.
But I deployed my app on heroku and even though I can navigate from any page to any other, but if I am for example on /profile page and I hit refresh i get
Cannot GET /statement
what could be the problem?
You trying to use history mode of router without backend.
For getting things working, you may use Express JS. Previous answer is not working for me and i write my own server script.
Here is the my server.js for running Vue app with history mode.
server.js (with Express):
const express = require('express');
const path = require('path');
const history = require('connect-history-api-fallback');
const app = express();
const staticFileMiddleware = express.static(path.join(__dirname + '/dist'));
app.use(staticFileMiddleware);
app.use(history({
disableDotRule: true,
verbose: true
}));
app.use(staticFileMiddleware);
app.get('/', function (req, res) {
res.render(path.join(__dirname + '/dist/index.html'));
});
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
Place this file in the root directory of your project (not src).
Run this script with Node: node server.js
Don't forget build your app for production ;)!
I think your vue-router is in HTML5 History Mode. https://router.vuejs.org/en/essentials/history-mode.html
In development mode, the webpack-dev-server handles the redirect for your but your need to configure your server used in production to redirect your routes.

create-react-app build service-worker.js and manifest.json not found

I have created an app with create-react-app. I have built it and I have written a simple express app for serving the react built app.
I have some problems with the static files and the files which are in the root folder of express app, (e.g. manifest.json, service-worker.js). Now I get 404 on both these files.
How can I treat this files in express? They must be in the static folder? I have to modify the react app?
I went to see the file generated by the react build, in which the file 'service-worker.js' is imported and the string starts with '/' (that is '/service-worker.js')
(I have not touch the files for the pwa since I created the project)
Here there's my root folder of my express app
I have only added the project.json and the index.js (and obviously the node_modules), the other files are those from the react build.
Here my express app:
const compression = require('compression');
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
app.use('/sketches', express.static('sketches'));
app.use('/static', express.static('static'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(compression());
app.get('/', (req, res) => res.sendFile(__dirname + '/index.html'))
app.listen(process.env.PORT || 3000, () => console.log('server listening!'))
Adding this line of code I get the service-worker.js but I can't get the files in the sketches folder.
app.use('/', express.static(__dirname));
I had a same problem i resolved it by following these steps.
warning: i am new to these technologies and i don't know much about web security. this maybe not the best way of doing it.
i get it work using ejs template engine and express but it should work in your case as well.
1) create-react-app
2) yarn build
3) copy static folder into public
4) copy service-worker.js inside static folder also
5) go inside main Ctrl + f
6) type /service-worker.js in search hit Enter
7) you will see somthing like that var e="/service-worker.js";
8) change into var e="/static/service-worker.js
9) finally open service-worker.js change /index.html to /
precacheConfig=[["/","d6be891ca003070326267be1d2185407"]

Getting an express app working online

I am new to expressjs and am trying to get my express application (done with the express generator) working on my website, I currently uploaded the directory which is is contained in like so..
http://www.example.com/express-app-here
so I could see it working online. However, when I navigate to where the App is, I seem to only get the directory structure, and express isn't routing me to the appropriate place like it is when I go to localhost:3000.
I take it this has something to do with the fact that express isn't executing my application? Locally,
npm start
needs to be run on the console in order to get it to run, is there some kind of log I need to execute this command in? Or something I need to change in the app.js or /bin directory?
As it was said in the comments, you need to have nodejs installed on your server. It's not as simple as just copying the node app directory over to the server.
You will have to install node and npm on the server, and then run your app from the server, probably using npm start like you were doing on your local machine.
From there, you will want to go into your app code and make sure a route exists for /express-app-here unless you want www.example.com:3000 to take you directly to the express app.
Basically do it like this:`
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
var port = process.env.PORT || config.webServer.port || 3000;
server.listen(port, function () {
console.log('server running');
console.log(port);
console.log(server);
});
exports.module = exports = app;
save it app.js
Go to path via cmd. Now run:-
1)npm install express
2)npm install http
3)node app.js
Will be enough to run express server

Categories