How can I link my express server to generated 'dist' directory? - express

I am getting this error, "TypeError: path must be absolute or specify root to res.sendFile"
root
-dist
|--index.html
|--index_bundle.js
-src
|-server
|-server.js
//server.js
var path = require('path')
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const app = express()
let dataStorage = {};
app.use(cors())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use(express.static('dist'))
app.listen(8081, function(){
console.log('Server running on port 8081!')
})
app.get('/', function (req, res) {
res.sendFile('../dist/index.html') //need help setting this up
})
app.post('/formHandler', function(req, res){
//post to dataStorage here
})
I am trying to run an express server while also using webpack-dev-server for hot reloading.
I am having trouble with setting up the path to generated 'dist' file.
I am able to just run the webpack-dev-server without express and the file is working then.
Thank you

You can have access to it by serving It's content as express static.
const path = require('path');
app.use(express.static(path.resolve(__dirname, '../../dist'));
You can also define the path at which statics assets can be accessible like this
app.use('/', express.static(path.resolve(__dirname, '../../dist'));
As in your dist folder there are already an index.html file it will be rendered by default when visiting the / path in your browser. No need to specify the index.html file in you request URL

Related

VueJS 3 project: "Cannot get" message with all paths but root

I have been trying for the past hour and a half to debug a project of mine.
The project works fine locally. Routes are systematically not working remotely except for one, the root of the project. I get a Cannot GET message in the browser elsewhere (all other paths).
From what I understand from my readings, this might have something to do with vue-router and might be caused by the server.js file I created in the root folder. The problem might have to do with the fact that my routes are dynamic.
const express = require('express');
const serveStatic = require("serve-static")
const path = require('path');
app = express();
app.use(serveStatic(path.join(__dirname, 'dist')));
const port = process.env.PORT || 3000;
app.listen(port);
This might also be caused by the fact I did not create the project with the history mode (although I'm pretty sure I did). I understand that I might have to go to my webpack config file to solve this, but I don't think I have one.
EDIT: By the way, my VueJS application is just a front-end to the PokéAPI back-end. I didn't build the back-end myself.
Simply creating the project with history mode is not enough. Your browser is trying sending text/html GET requests to the path you navigate to. But your app is a single page application which only has one index.html in /public, so you get 404 errors. Its in the vue-router docs:
To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same index.html page that your app lives in.
For Node.js+express setup, you can use connect-history-api-fallback package.
npm install --save connect-history-api-fallback
Then change your server.js file to this:
const express = require('express');
var history = require('connect-history-api-fallback');
const serveStatic = require("serve-static")
const path = require('path');
app = express();
app.use(history());
app.use(serveStatic(path.join(__dirname, 'dist')));
const port = process.env.PORT || 3000;
app.listen(port);
In case you don't want to use third-party package you might be able to simply do this:
const express = require('express');
const serveStatic = require("serve-static")
const path = require('path');
app = express();
app.use(serveStatic(path.join(__dirname, 'dist')));
app.get(/.*/, function (req, res) {
res.sendFile(__dirname + "/dist/index.html");
});
const port = process.env.PORT || 3000;
app.listen(port);
But I'd recommend using the package as it handles some edge-cases

Simple test route is not responding to simple Postman request

I tried to create the simplest test route to test on my localhost as follows.
Verified localhost:3000 is up. Wrote a simple test file.
const express = require('express');
const router = express.Router();
router.route('/test').get((req, res) => {
console.log('route found');
});
module.exports = router;
My routes are split up as follows in my index routing file in the routes directory.
module.exports.api = require('./api');
module.exports.auth = require('./auth');
module.exports.root = require('./root');
module.exports.articles = require('./articles');
module.exports.test = require('./test');
I use the route as follows in my index.js for the server:
const routes = require(__dirname + '/routes');
app.use('/test', routes.test);
Tested it using Postman.
Sent request to localhost:3000/test/test.
No response. How can I troubleshoot further?
You are not getting any response because you are not sending any response from the server. You need to send some response back otherwise the client will keep waiting for the response until request times out.
router.route('/test').get((req, res) => {
res.send('route not found');
});
Edit
app.use('/test', routes.test); won't work with the way your route is defined. For it to work, request url should be /test/test. If you want request url to be just /test, change
app.use('/test', routes.test);
to
app.use(routes.test);
Here's a working version of what you want to do
const express = require('express');
const router = express.Router();
router.get('/test', (req, res) => {
res.send("hey");
console.log('route found');
});
module.exports = router;
Now in your main module, you need to check that you're listening to the right port, and that your express app is actually using the exported router!
const express = require('express');
const app = express();
const router = require('path/to/router/module');
app.use(router)
app.listen(8080, () => console.log("listening to port 8080"));
EDIT:
You mentioned that
My routes are split up as follows in my index routing file in the routes directory.
And, I can see that in the main module, you are requiring the directory itself, and not the routes module
const routes = require(__dirname + '/routes');
while what you should require is a module and not a directory!
const routes = require(__dirname + '/routes/yourRouteModuleName');
The solution I just gave assumes the following project's structure:
├── index.js
├── routes
│ ├── test.js
│ ├── routeModuleOrWhatever.js
│

Multiple Errors serving HTML pages with Express

I'm trying to route pages using Express, but I can't seem to route from my main page. I'm using HTML as the view engine and I feel like everything is set up properly, but I'm seeing the error:
"TypeError: path must be absolute or specify root to res.sendFile"
Here is my file structure:
root
-public
--images
--index.html
--main.css
--sponsors.html
--team.html
app.js
I've tried multiple file routes, res.render versus res.sendFile.
var express = require("express")
var app = express()
const port = 3000
var http = require("http")
const path = require('path')
app.set("view engine", "html")
app.listen(port, () => console.log(`Example app listening on port
${port}!`))
app.use(express.static(__dirname + '/public'));
app.get('/sponsors', function(req, res) {
res.sendFile('sponsors')
})
app.get('/', function(req, res) {
res.sendFile('index')
})
app.get('/team', function(req, res) {
res.sendFile('team')
})
To render from a view engine, use res.render(), not res.sendFile().
And, your view engine will need to be able to find a file with that name and an appropriate file extension in the path for the view engine.
If you want to use res.sendFile() without the view engine, then you must specify an actual filename or include the root option that tells it where to look. You must also use the actual file extension on the filename.
Remove the following route method.
// remove the following code
app.get('/', function(req, res) {
res.sendFile('index')
});
Update the default path to the static method you had already written.
app.use('/', express.static(__dirname + '/public'));

Unable to find module 'server', added express to Ember-Cli app

I've added an expressJS app inside my ember app so I can provide a backend API for my ember app.
My process:
npm install express --save
I created a folder called "server" in the route of my ember application and inside that a file called "server.js".
Yesterday I had it working fine, I already had my ember app running via ember s and tested out the express app using nodemon server/server.js and checking the endpoints I created with Postman.
However this morning when I've tried to run ember s I'm given the following error:
C:\Sandbox\tsodash>ember s
version: 2.3.0-beta.2
Cannot find module 'C:\Sandbox\tsodash\server'
Error: Cannot find module 'C:\Sandbox\tsodash\server'
at Function.Module._resolveFilename (module.js:339:15)
at Function.Module._load (module.js:290:25)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Project.require (C:\Sandbox\tsodash\node_modules\ember-cli\lib\models\project.js:281:12)
at Class.module.exports.Task.extend.processAppMiddlewares (C:\Sandbox\tsodash\node_modules\ember-cli\lib\tasks\server\express-server.js:115:33)
at Class.<anonymous> (C:\Sandbox\tsodash\node_modules\ember-cli\lib\tasks\server\express-server.js:220:21)
at lib$rsvp$$internal$$tryCatch (C:\Sandbox\tsodash\node_modules\ember-cli\node_modules\rsvp\dist\rsvp.js:1036:16)
at lib$rsvp$$internal$$invokeCallback (C:\Sandbox\tsodash\node_modules\ember-cli\node_modules\rsvp\dist\rsvp.js:1048:17)
at C:\Sandbox\tsodash\node_modules\ember-cli\node_modules\rsvp\dist\rsvp.js:331:11
Naturally I assumed I just needed to use modules.exports = function(){ //..expressjs code}
Full Code
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var request = require('request');
var btoa = require('btoa');
var config = require('./config');
var _ = require('lodash');
module.exports = function(){
var endPoints = config.endPoints;
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
var port = process.env.PORT || 4200;
var router = express.Router();
// middleware to use for all requests
router.use(function (req, res, next) {
// do logging
console.log('Something is happening.');
next(); // make sure we go to the next routes and don't stop here
});
router.get('/', function (req, res) {
res.json({
message: 'TSO Git Dash'
});
});
// ..
app.use('/api', router);
app.listen(port);
console.log('Magic happens on port: ' + port);
}
Still no avail.
Folder structure:
Any ideas? I'm assuming it's something simple that I've missed. But I'm stumped.
As #locks suggested in the comments, there is an express server used in mocks and fixtures. The fix was simple, I renamed the folder and the JS file to "api" and ran ember s and it worked perfectly. It seems to have been a naming conflict.

Setting up default view path in Express.js

Source Code
app.js
var express = require('express');
var app = express();
var path = require('path');
var viewPath = path.join(__dirname, 'app/views');
app.set('views', viewPath);
app.set('view engine', 'jade');
app.get('/', function(req, res) {
res.render('index', { title: 'Home Page' } );
});
app.listen(3000);
Folder Structure
app
└───views
│ └───index.jade
└───app.js
Error in Browser
Error: Failed to lookup view index in views directory d:\Users\Admin\Documents\...\project\views
Question
I would like to structure my app by placing the view files in app/views/*.jade, but I cannot get it working so far, using app.set('views', ...) should work but it doesn't
console.log(viewPath) shows d:\Users\Admin\Documents\...\project\app\views
I also tried e.g. app.set('views', 'xxx') but the error still get stucked on the same path, it seems like app.set() has never been called, what's wrong here ?, please guide.
Thanks
Edit
It doesn't matter what I set using app.set('views', 'xxx') the error will always be Error: Failed to lookup view index in views directory d:\Users\Admin\Documents\...\project\views (always keep saying the same path)
I'm so sorry about router.get('/', ...), My actually project's files are different, so I was making mistake here
Try using
app.set('views', path.join(__dirname, 'views'));
Your app.js is in your app folder so I think
var viewPath = path.join(__dirname, 'app/views');
app.set('views', viewPath);
will look into app/app/views/ instead of app/views/ because of __dirname
__dirname is the directory in which the currently executing script resides.
I know it's too late, but might help someone who has the same problem. If you placed the rendering code in a separate file, then you need to use express.Router instead of app.get. For example,
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index', {title: 'Hey', message: 'Hello there!'});
});
module.exports = router;
Then in your app.js,
const router = require('./app/routes/routerName');
app.use('/', router);
I actually have separated files in my project, so I have app.get('/', ...) in the separated route file, then require it to use with app.use()
I really have no ideas but after moving only the app.get('/', ...) to the app.js, the problem has been solved
Thanks everyone
As mentioned by Roxinagi, you should be using app.get().
Everything else seems fine
app.get('/', function(req, res) {
res.render('index', { title: 'Home Page' } );
});
const path = require('path')
app.set('views', path.join(__dirname, 'app/views/'))
app.set('view engine','jade');