I have two projects. First a single page app (without bundler) which is being started by the following server.js:
const express = require("express");
const morgan = require("morgan");
const path = require("path");
const DEFAULT_PORT = process.env.PORT || 8000;
// initialize express.
const app = express();
// Initialize variables.
let port = DEFAULT_PORT;
// Configure morgan module to log all requests.
app.use(morgan("dev"));
// Setup app folders.
app.use(express.static("app"));
// Set up a route for index.html
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname + "/index.html"));
});
// Start the server.
app.listen(port);
console.log(`Listening on port ${port}...`);
Secondly, I also have a separate Express application which handles authentication and has multiple routes and templates/views. However, I want one of those routes to contain the single page app instead of a simple view. I copied the whole repository of my first project into the Express applications src-directory and would now like to make it available under the route "/app".
Is that possible? How would I make sure that the static files of the single page app are being used properly?
router.js of the Express application
const getRoutes = (mainController, authProvider, router) => {
const authorizationMiddleware = require("./authorizationMiddleware");
// app routes
router.get("/", (req, res, next) => res.redirect("/home"));
router.get("/home", mainController.getHomePage);
router.get("/app", (req, res) => {
???
});
...
project structure:
-src
--first projects dir
--data
--msal-express-wrapper
--public
--utils
--views
--app.js
--authorizatonMiddleware.js
--controller.js
--router.js
-appSettings.js
-package.json
-...
Related
I have created a simple Express JS app. and it is working fine in localhost. when I visit localhost:8000 I see static files (index.html, style.css and frontend.js).
I have tried to deploy that app in a server using cPanel. and I have installed Node app and dependencies using package.json successfully. But when I visit the domain I just see a message (Node JS app is working, Node version is 10.24.1).
How to make my app to point and display the static folder (index.html) and run the app?
My app architecture:
server.js
package.json
public/index.html
public/style.css
public/frontend.js
And here is my server.js startup file:
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Dependencies */
const bodyParser = require('body-parser');
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('public'));
// Setup Server
const port = 8000;
const server = app.listen(port, function(){
console.log(`server running on localhost: ${port}`);
});
//POST Route to store data in the app endpoint, projectData object
app.post('/addData', addData);
function addData (req, res){
let data = req.body;
projectData = data;
console.log(projectData);
}
app.get('/getData', getData);
function getData(req, res) {
res.send(projectData);
}
The problem here is that you are not pointing a route to send the HTML file. Otherwise the client would have to point it to the correct path of the file, Like localhost:3000/index.html.
you need to send it from the server using app.get
app.get("/", (req, res) => {
res.sendFile(__dirname + "path to the file");
});
The problem was that I have created the app in a subfolder of my domain.
But when I have created subdomain and reinstalled the app inside it, the app is pointing to static folder successfully.
I am attempting to deploy a Vue.js, Node, Express, MongoDB (MEVN) stack application to Netlify. I successfully deployed the front end of the application to Netlify, and am now attempting to deploy the express server, based on the following serverless-http example: https://github.com/neverendingqs/netlify-express/blob/master/express/server.js
I configured my server to include the serverless-http package:
server.js
const express = require('express');
const app = express();
const serverless = require('serverless-http');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./DB.js');
const postRoute = require('./routes');
mongoose.connect(config.DB, { useNewUrlParser: true, useUnifiedTopology: true }).then(
() => { console.log('Database is connected') },
err => { console.log('Can not connect to the database'+ err)}
);
app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use('/messages', postRoute);
app.use('/.netlify/functions/server', router); // path must route to lambda
app.use('/', (req, res) => res.sendFile(path.join(__dirname, '../public/index.html')));
module.exports = app;
module.exports.handler = serverless(app);
routes.js
const express = require('express');
const postRoutes = express.Router();
// Require Post model in our routes module
let Post = require('./post.model');
// Defined store route
postRoutes.route('/add').post(function (req, res) {
let post = new Post(req.body);
post.save()
.then(() => {
res.status(200).json({'business': 'business in added successfully'});
})
.catch(() => {
res.status(400).send("unable to save to database");
});
});
// Defined get data(index or listing) route
postRoutes.route('/').get(function (req, res) {
Post.find(function(err, posts){
if(err){
res.json(err);
}
else {
res.json(posts);
}
});
});
module.exports = postRoutes;
I then re-deployed my application to Netlify, but the server does not seem to run in Netlify. This server is in a folder in project root of my vue.js app. Should I instead run the server as a separate site in Netlify? If not, what should I do in order to get the server to run when deployed in Netlify?
It's been a while, but here goes.
Netlify hosting is for the Jamstack, as they say, i.e. only static files, no processing on the server. The idea is to make use of other mechanisms to get your data dynamically, such as APIs hosted elsewhere, which you query straight from the browser, or when you build your site.
Most likely you actually had to deploy your express.js app as a Netlify Function, instead. Check Netlify's blog post on running express apps on their functions.
I had a similar issue, just that my server wouldn't connect to the routes locally, the major difference between my code and yours was that I had to do
const router = express.Router()
and then switched app.use() with router.use()
Like I said, that's for when the localhost says "cannot GET /* a defined path */"
P.S. As a side note, you don't need explicit bodyParser in recent express, express.json() works fine instead.
I am building an app with React and Express and want the routing to mainly go through Express instead of react-router.
After I built the react app and set Express to serve static files from the build folder, every path leads to only the React app. For example when visiting localhost:3000/test, I still only get the React app instead of "testing."
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, './client/build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, '/client/build', 'index.html'));
});
app.get('/test', function (req, res) {
res.send("testing");
});
app.listen(3000);
most likely you don't want such results because you want to have your server-side routes exposed to client and route which handle SPA file goes as the last route inside the application. But this code will work for you.
const express = require('express');
const path = require('path');
const fs = require('fs')
const app = express();
app.use(express.static(path.join(__dirname, './client/build')));
app.get('*', function (req, res) {
const file = fs.createReadStream(path.join(__dirname, '/client/build', 'index.html'));
return file.pipe(res);
});
app.get('/test', function (req, res) {
res.send("testing");
});
app.listen(3000);
I hope this will help, happy coding!
I'm trying to create 2 seperate files in my app,
one for API request, and second one for socket.io
The starting file is app.js which look like this:
const express = require('express');
const app = express();
app.get('/test', (req, res) => {
res.send('test');
});
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
module.exports = app;
and the second file for socket.io looks like this:
const app = require('./app');
const http = require('http').Server(app);
const io = require('socket.io')(http);
...
http.listen(port, function(){
console.log('listening on *: ',port);
});
When I run the app with my IDE (VSCODE) everything works perfect,
but when I'm trying to run on the terminal the app doesn't start and the page isn't available on the starting port.
I think that the problem is about the export for the socketIO file in app.js,
Any help would be appreciated.
I'm writing an API using Node.js and Express. My API has GET methods of the form:
/api/v1/doSomething
/api/v1/doSomethingElse
My code is looking something like this:
server.js:
var app = express();
...
var routes = require('./routes')
routes.attachHandlers(app, '/api/v1')
routes/index.js
...
module.exports.attachHandlers = function(app, context) {
//get a list of all the other .js files in routes
//for each route, require() it and call it myRoute
myRoute.attachHandlers(app, context)
}
routes/some-route.js
...
module.exports.attachHandlers = function(app, context) {
app.get(context + '/doSomething', doSomething)
app.get(context + '/doSomethingElse', doSomethingElse)
}
...
Effectively I'm passing the context path/mount point down through the app. If somebody were to write a route like the following, though, the context would be lost:
app.get('/doFoo', foo)
Rather than having that part of the API mounted on /api/v1/doFoo it's on /doFoo. I would like to avoid having to pass the context path around like this.
app.use supports mounting middleware on an optional mount path. I have seen references online to mounting an entire Express application on a mount path using app.use. This seems like the sort of thing I want to do, but I'm not sure how to do it or if it's the best solution for my particular use case.
To summarise - I want to mount my app.get() routes with a particular prefix by default. What's the best way of doing this?
With Express 4.0, the task is much cleaner with the Router. You can create as many routers as you need to nicely partition your app, and then attached them with app.use(). For example:
myapp.js
var express = require("express"),
router = express.Router(),
app = express(),
port = 4000;
// Here we declare our API which will be visible under prefix path
router.get('/', function (req, res) {
console.log("request to subspace hello");
res.send({ message: "Hi from subspace /api/v1/"});
});
// we attach our routes under /api/v1
app.use('/api/v1', router);
// here we have direct, root-level routing
app.get('/', function (req, res) {
console.log("request to rootspace hello");
res.send({message: "Hi from root /"});
});
app.listen(port);
console.log("App active on localhost:" + port);
Then run
node myapp.js
and visit
http://localhost:4000 and http://localhost:4000/api/v1
Here's a working example of mounting a route in Express 3:
./snipe3app.js
var express = require('express');
var app = module.exports = express();
app.get('/subapp', function (req, res) {
res.send('You are on the /sub/subapp page.');
});
./app.js
var express = require('express'),
http = require('http'),
subApp = require('./snipe3app'),
app = express();
app.use(express.favicon());
app.use(express.bodyParser());
app.use(app.router);
app.use('/sub', subApp);
app.get('/', function (req, res) {
res.send('You are on the root page');
});
http.createServer(app).listen(3000, function(){
console.log('Express server listening on port 3000. Point browser to route /secure');
});
You have to pay attention to the order in which the routes are handled when doing this.
I think express-namespace will work for this.