Express.js server not working all of a sudden - Cannot GET / - javascript

My extremely simple express server using node.js suddenly stopped working. It was working fine (only testing it on my local machine for now), then I tried using browserify (which didn't work and I ended up deleting it) and when I went back to the site I was getting a Cannot GET / error.
I've tried uninstalling browserify, re-installing it, uninstalling and re-installing the two npm packages I'm using, even deleting all of my folders and starting from scratch (just pasting in the code on a couple of files). No matter what I still get the same error and I have no idea why. If I open index.html it still opens perfectly, while when I run my server (index.js) it doesn't throw any errors and seems to be listening as it's supposed to.
The server at the moment:
var path = require('path');
var express = require('express');
var app = express();
var dir = path.join(__dirname, 'public');
app.use(express.static(dir));
app.listen(3000, function () {
console.log('Listening on http://localhost:3000/');
});
My files are currently structured like this:
public
assets (just has some images)
node_modules
index.html
index.js
package-lock.json
styles.css

Your index.html file should be in public folder and then it will work. At the moment, you have set the static path to public folder which doesn't contain any file.

Since your server's path is /public/index.js, path.join(__dirname, 'public') is resolving to /Users/.../your_directory/public/public. Express cannot find such a directory, so it proceeds down its pipeline. Since you did not define a GET / route, Express throws the error.
I would recommend removing your server file from /public.
Here's what your new directory tree would look like:
my_directory
node_modules
public
assets
index.html
styles.css
server
server.js (index.js in your case)
After you set up your directory tree as such, you can change the following:
var dir = path.join(__dirname, 'public');
// becomes
var dir = path.join(__dirname, '..', 'public');
// The '..' is used to move one directory level up.
Then, you should be able to see index.html when going to http://localhost:3000.

Related

Is html-webpack-plugin hijacking my express server?

I've been working through the tutorials at https://webpack.js.org/guides/output-management/ and they've solidified my understanding of how webpack typically bundles your whole frontend into a script that is run by a barebones HTML page like this:
<html>
<head>
<title>Output Management</title>
</head>
<body>
<script src="./app.bundle.js"></script>
</body>
</html>
This file is in a src directory, which sits in the project root.
I've modified the tutorials slightly by serving that HTML page from an Express server, which looks like this:
const express = require("express");
var path = require("path");
const server = express();
server.use(express.static(path.join(__dirname, "../dist")));
server.use(express.urlencoded({ extended: true }));
var indexPath = path.join(__dirname, "../src/index.html");
//create a server object:
server
.get("/", function(req, res) {
res.status(200)
res.sendFile(indexPath);
//res.send('<h1>I am not the webpack script!</h1>')
})
module.exports = server
So far everything makes sense. This server serves my index.html, which runs the webpack script, and that script causes the HTML page to show some text, images, and CSS. If I uncomment the res.send line, the server serves a one-line website instead.
However, the linked tutorial recommends trying HTML-webpack plugin, and when that comes in I get confused. I understand that the plugin creates an index.html file in the same directory as the bundled scripts (in my case /dist) that incorporates any and all scripts created by webpack. Sure, makes sense. But nothing is explicitly serving that HTML file. However, if I add the plugin to my webpack config:
entry: {
app: "./src/index.js",
print: "./src/print.js"
},
+ plugins: [
+ new HtmlWebpackPlugin({
+ title: 'Output Management',
+ }),
+ ],
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist")
},
then navigate to localhost:3000 in the browser, it displays the /dist/index.html file, NOT the /src/index.html file. Nothing I do to modify the server.js file changes what is displayed in the browser, but if I stop that server from being listened to I see nothing, so apparently webpack-html-plugin is not creating a server of its own.
So seemingly what is happening is that webpack-html-plugin is not just dynamically creating an HTML file to run bundled scripts, it is also changing the behavior of my server in a way that I am not explicitly instructing it to and seemingly cannot modify.
TLDR: Specifically, something in webpack-html-plugin is causing the root route of my express server to serve /dist/index.html, not /src/index.html as I am explicitly instructing it to. Why?
The repo is at https://github.com/CliffRobinson/webpack-tutorial-sandbox and you can (probably) have a look at codesandbox here to see if you can replicate this odd behavior.
What is happening is that you are serving all the files inside the dist directory as static files where your index.html is generated by html-webpack-plugin. I'm not sure how paths are handled in express but it seems that static files take precedence over any route defined that is why dist/index.html is overriding / path.

Node.js works when run with node command but not with forever

I have a Node.js app that I can run fine with this command: node app.js. It starts up and I can go to my server address and see it the app working. However, when I try to run the app with forever (to keep the app running on my server even when I'm not logged in), using this command: ./forever start ../../../app.js I get the following error in the log file:
Error: Failed to lookup view "home" in views directory "/root/ExerciseApp/node_modules/forever/bin/views"
Here's my directory structure:
ExerciseApp
/nbproject
project.properties
project.xml
/public
/css
style.css
/scripts
buttons.js
/views
/layouts
main.handlebars
home.handlebars
update.handlebars
app.js
.gitignore
dbcon.js
package.json
Here's the relevant parts of app.js:
//*****Express stuff*********
var express = require('express');
var app = express();
app.use(express.static('public'));
//*****BodyParser stuff*******
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//*****Handlebars stuff******
//Create instance of handlebars let it know default layout is 'main'
//Default layout is the area all the other contents will be inserted
var handlebars = require('express-handlebars').create({defaultLayout:'main'});
//.handlebars extensions are managed by handlebars
app.engine('handlebars', handlebars.engine);
//Lets us ignore .handlebars extensions
app.set('view engine', 'handlebars');
var helpers = require('handlebars-helpers')();
var moment = require('moment');
//*****MySQL stuff******
var mysql = require('./dbcon.js');
app.set('port', 3645);
If I do the command ./forever list, I can see that the app is running but visiting the page doesn't work.
EDIT: I'm running this on Debian Linux
Unless you provide more data, and assuming the operating system is Linux and forever is installed with npm install forever -g, what you should do is forever start [../path/to/filename], not ./forever (which would try to run a binary called 'forever' inside the directory where you are at.
You have two choices:
a) run forever from the main directory the way I told you
b) use absolute paths in your app.js, or relative paths to ../../../../node_modules/forever
I recommend a).
Try to use dirname so that your paths are the same regardless of how your app is run.
So you would have something like these statements
app.set('views', __dirname + '/views');
and
app.use(express.static(__dirname + 'public'));
Try that and see if it works!
Your working directory is all out of wack when you run forever from node_modules. Instead add a "start" script to your package.json:
scripts: [
"start": "forever start app.js"
]
This approach uses the version of forever you have specified in package.json and doesn't require anything to be installed with -g. Also the working directory will be the same folder that has app.js and everything should work fine.
Now, any user on any system should be able to run npm install then npm start and have your app up and running in no time.

Sending whole folder content to client with express

I made an html5 game (using GameMaker), which is constituted of an index.html and a folder "html5game" that contains the dependencies of the game - the javascript code and the resources. The problem is the resources are quite numerous and diverse (sounds, sprites, etc.) and The client needs them all to play.
I am looking for a way to send them all without naming them specifically.
I tried the glob module :
var glob = require( 'glob' );
var files = glob.sync( './html5game/**' ).forEach( function( file ) {
require( path.resolve( file ) );
});
but I can't figure a way to send the files using res.sendFile() once I did that.
I tried
var express = require('express');
var app = express();
[...]
app.get('/aeronavale/jeu', function(req, res){
res.sendFile(__dirname + '/aeronavale/index.html');
res.sendFile(files)
});
[...]
app.listen(3000, function(){
console.log('app started on port 3000, yeah !')
})
but it gives me the error :
TypeError: path argument is required to res.sendFile
If you have an other solution, I a also interested. Thanks for your answers !
You will not be able to send multiple file like that with res.sendFile. The most straightforward thing that you can do here would be this:
Put your index.html file and your html5game directory into some common directory, e.g. called html and put it where you have your Node.js program. An example directory layout would be:
/home/you/yourapp:
- app.js (your node program)
- package.json (your package.json etc)
- html (a new directory)
- index.html (your main html to serve)
- html5game (the directory with other files)
- (other files)
Now, in your Node program you can use something like this:
var path = require('path');
var express = require('express');
var app = express();
var htmlPath = path.join(__dirname, 'html');
app.use(express.static(htmlPath));
var server = app.listen(3000, function () {
var host = 'localhost';
var port = server.address().port;
console.log('listening on http://'+host+':'+port+'/');
});
This will serve all of your files (including index.html) on addresses like:
http://localhost:3000/ (your index.html)
http://localhost:3000/html5game/xxx.js (your assets)
Of course you still need to make sure that you refer to your assets in your index.html file correctly, for example with:
<script src="/html5game/xxx.js"></script>
in the case of the example layout above.
The top level directory with your static assets (where you have your index.html) is usually called static, public or html but you can call it whatever you like, as long as you use the correct path in your call to express.static().
If you want to have your game available in some path other than the root path then you can specify it to app.use. For example if you change this:
app.use(express.static(htmlPath));
to this:
app.use('/game', express.static(htmlPath));
Then instead of those URLs:
http://localhost:3000/ (your index.html)
http://localhost:3000/html5game/xxx.js (your assets)
those URLs will be available instead:
http://localhost:3000/game/ (your index.html)
http://localhost:3000/game/html5game/xxx.js (your assets)
A lot of questions here are related to serving static files with Express so I made a working example and posted it on GitHub so that people could have a working starting point and go from there:
https://github.com/rsp/node-express-static-example
See also some other answers where I talk about it in more detail:
How to serve an image using nodejs
Failed to load resource from same directory when redirecting Javascript
onload js call not working with node
Loading partials fails on the server JS
Node JS not serving the static image
The workaround for this is to compress the directory using the archiver library and uncompress it on the front end.

Files won't load if in root directory?

I have a weird problem with my file structure. For some reason, after creating the server and running it, I can't get the index.html to run unless it is in a folder. The browser just shows "Cannot GET /". The same can be said for my JS files that are being used in the index.html. Unless they are in folders and not in the root directory itself, they will not load into index.html. Is this normal or is this because of how I have my server.js file set up?
Here's the code:
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, './views')));
app.listen(8000, function() {
console.log("Listening on Port 8000");
})
The folder/file structure is:
Root Directory
- node_modules
- views
-js
-script.js
- pages
-about.html
-contact.html
-home.html
- index.html
- server.js
The problem is when the file structure is:
Root Directory
- node_modules
- pages
-about.html
-contact.html
-home.html
- index.html
- script.js
- server.js
The express.static is also pointing to pages instead of views.
Any suggestions on why this is the case? Thanks in advance.
simply, express.static(path.join(__dirname, './views')) will serve all files in folder views
if you go to /pages/index.html . this will check folder view for /page/index.html if exist index.html, it will serve you this file else it will check if you have any handle route logic
You can set multi serve-static.

NODEJS and HEROKU : I can't serve the static files once the server is deployed

ok, I have the simple server which is the following setup:
var port = process.env.PORT || 8080;
var server = http.createServer(app).listen(port);
process.env.PWD = process.cwd();
app.use(express.static(process.env.PWD+'/Public'));
app.get('/',function(req,res) {
res.sendfile(process.env.PWD+ '/index.html');
res.end;
});
I create a git in the folder and I successfully push it to heroku, but when I open it I get this result:
https://leoforio.herokuapp.com/
If you open the console log you will see that it fails to load css and js static files which can't be found,although when I test my app locally this setup works and the files are served as planned.
What am I doing wrong?
P.S. I don't think it a problem with heroku,I believe the problem is within nodejs and uploading the app.
I'm going to guess that the problem lies in how you're specifying the directory for static files.
What I normally see -- and prefer -- is setting up static this way:
app.use(express.static(__dirname + '/public'));
That means Express will look for the static files in the public subdirectory of the same directory that your application file is in. Let's imagine you have two apps, app1.js and app2.js. app1.js is configured the way you have it, using process.cwd() (current working directory), and app2.js is using __dirname as its base. Both of these apps are in /home/drizo/app.
If you do this, both will work correctly:
cd /home/drizo/app
node app1.js # uses cwd + /public = /home/drizo/app/public
node app2.js # uses __dirname + /public = /home/drizo/app/public
However, if you do it like this:
cd /home/drizo # or ANY directory that's not /home/drizo/app
node app/app1.js # uses cwd + /public = /home/drizo/public - WRONG
node app/app2.js # uses __dirname + /public = /home/drizo/app/public
As you can see, app1.js is using the directory that the app was started from. I'm not sure how Heroku starts/restarts apps, but I'm guessing it isn't doing it from the directory you expect.

Categories