Some expressjs Static Files being served while others are not - javascript

I have an odd situation what is particularly troublesome is that I have done this many times before it has to be something simple I am missing.
Please help I feel like I am loosing my mind...
Problem/Symptoms
I can load any js files from the lib folders
I can load any of the png files in the folder root/public/art under the web location //art/foo/bar.png
Can't load anything from the CSS nor js no mater what I do it all gives me 404 errors this is driving me totally crazy.
Same behavior with line 13 commented out
Same with various forms of lines 14-16
Same with and without using router
Folder Structure
Root
server.ts
public
art
art in subfolders
css
canvas.css
js
js files in folders and not
Code
import * as express from "express";
import * as path from "path";
//const express = require("express")
//const path = require("path")
let app = express()
let port = 3000
let router = express.Router();
router.use('/lib/framework', express.static( path.join(__dirname, 'node_modules','framework')));
router.use('/lib/redactedLib2', express.static(path.join(__dirname, 'node_modules', 'redactedLib2')));
router.use('/lib/redactedLib3', express.static(path.join(__dirname, 'node_modules', 'redactedLib3')));
router.get('/', (req, res) => res.sendFile(path.join(__dirname, 'index.html')))
//app.use('/art/*', express.static(path.join(__dirname, 'public', 'art')));
//app.use('/css/*', express.static(path.join(__dirname, 'public', 'css')));
//app.use('/js/*', express.static(path.join(__dirname, 'public', 'js')));
router.use('/', express.static('public'))
app.use('/', router)
app.listen(port, () => console.log(`Go to http://localhost:${port} to view.`))
Solution (Edit)
Incase anyone finds this later I was fixing it the whole time I just needed to do an empty cache and reload... If you are in chrome open dev tools F12 then click and hold on refresh and select it.

I see two issues, based on what you're showing here. First is your directory structure. Is that accurate to what your structure actually is? Because in your application you're telling Node to translate /art/* to the /public/art/ directory, but that directory is actually at /art.
Second, it's the formatting of your virtual path prefix. Drop the /*; there's no need to declare a wildcard value. It'll just mess up the pathing. The trailing / is unnessary too, though it shouldn't cause a problem. Either way, restructuring your routes to:
router.use('/lib/framework', express.static( path.join(__dirname, 'node_modules','framework')));
router.use('/lib/redactedLib2', express.static(path.join(__dirname, 'node_modules', 'redactedLib2')));
router.use('/lib/redactedLib3', express.static(path.join(__dirname, 'node_modules', 'redactedLib3')));
app.use('/art', express.static(path.join(__dirname, 'public', 'art')));
app.use('/css', express.static(path.join(__dirname, 'public', 'css')));
app.use('/js', express.static(path.join(__dirname, 'public', 'js')));
router.get('/', (req, res) => res.sendFile(path.join(__dirname, 'index.html')));
And either fixing the path joins in the app, or fixing the physical file structure, will solve the issue of loading resources that don't actually exist.

Related

Serving static files via Express - endpoint specific?

Beginner here, please point me in the right direction! So, I used express static and can see all my static files correctly in "sources" and the CSS applies via localhost:5050. However, when I directly open my endpoint e.g. http://localhost:5500/users, I cannot see the files anymore and no more CSS is applied. I wrote requests for each specific endpoint too, of course. Does this have anything to do with the way I serve static files in my code? I can't for the life of me figure out why there are no errors in the console and network tab but the styles do not apply and the classes set in my script also do not show up via the elements page in the dev tools when I open any of my endpoints. What could be the problem if everything is working via index? Do I need to configure static files for each API endpoint somehow too?
note: I also console.logged the path and could see the path is correct - / also serves the static files correctly so I assume the issue lies somewhere else? I also tried app.use('/users',express.static(path.join(__dirname, '..', '..', 'public')));
and could then see all static files via that endpoint but the whole endpoint functionality I set later in the code broke & app.use(express.static(path.join(__dirname, '..', '..', 'public'))); should normally allow public folder access from all endpoints, right?
HTML tags:
<link rel="stylesheet" href="/css/style.css" type="text/css">
<script src="./js/bundle.js"></script>
--> also tried with js/bundle.js & other paths.
server.js:
import express from 'express';
import path from 'path';
import axios from 'axios';
const __dirname = path.dirname(new URL(import.meta.url).pathname);
const app = express();
const port = 5500;
// Serve static files from the public folder
app.use(express.static(path.join(__dirname, '..', '..', 'public')));
// Route for serving the index.html file
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '..', '..', 'public', 'index.html'));
});
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
This is my folder structure:
public/
index.html
css/
style.css
js/
bundle.js
src/
client/
script.js
server/
proxy.js
server.js
When you use code like this:
app.use(express.static(path.join(__dirname, '..', '..', 'public')));
Means that every request goes through express.static middleware.
Static middleware get path from the URL and tries to match a static file in public directory to this path. Let's consider several examples:
GET https://localhost:5500/foo/bar.html -> would be converted to /public/foo/bar.html
GET https://localhost:5500/ -> public/index.html
GET https://localhost:5500/users/ -> public/users/index.html
If you replace app.use(express.static(...)) on app.use('/users', express.static(...)) then express.static would be called only on /users/... requests:
GET https://localhost:5500/foo/bar.html -> not called
GET https://localhost:5500/users/ -> public/index.html. Note, /users prefix is removed when express.static convert URL's path to file path.
So this should explain:
I also tried app.use('/users',express.static(path.join(__dirname, '..', '..', 'public'))); and could then see all static files via that endpoint
Goes next:
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '..', '..', 'public', 'index.html'));
});
applies only on / request, so if you make request on /users express returns 404. If you want fallback on index.html every request that didn't match any previous middleware you should use:
app.use((req, res) => {
res.sendFile(path.join(__dirname, '..', '..', 'public', 'index.html'));
});
And the last ./js/bundle.js:
<script src="./js/bundle.js"></script>
this is relative URL it means if you open page /users/index.html and render such HTML then browser will make request on /users/js/bundle.js. In you case I guess you want to make request always on /js/bundle.js so you should replace it on absolute path /js/bundle.js like you did for CSS

Basic Node and Express: Serve Static Assets

let express = require('express');
let app = express();
app.use(express.static('public'));
I am trying to solve freecodecamp's "Basic Node and Express: Serve Static Assets" challenge but it keep says "not working. Could someone help me? Thanks.
This is the path folder The main files in my directory
If your public folder is whithin the same directory of your main.js file, you can use:
const path = require('path');
app.use(express.static(path.join(__dirname, "public")))
As described in express documentation:
If you run the express app from another directory, it’s safer to use the absolute path of the directory that you want to serve:
const path = require('path')
app.use('/static', express.static(path.join(__dirname, 'public')))

Express.js just won't serve static files

I am trying desperately to get it working that my express server serves statics files but I just can't get it to work... I already tried multiple attempts at solving it but none of it worked.
So my folder structure is the following:
App
- Web
-- public
--- images
--- css
-- Server.js
The code from my server is the following
const express = require('express');
const app = express();
app.use('/static', express.static('./public'));
const server = app.listen(80, function() {
const host = server.address().address;
const port = server.address().port;
console.log(`Server is running on ${host}:${port}`);
});
It just won't serve the files..
No matter how I change the usage of the public folder. I already tried with path.join and __dirname but none of it worked. I only get the express error Cannot GET /static ...
This can happen when the current working directory is not what you think it is and hence ./public doesn't resolve to the right path. The safer way to do this is to use __dirname, the directory of the current file:
app.use('/static', express.static(path.join(__dirname, 'public')));

How to route HTML Node js Express js

I am trying to route multiple HTML pages. It loads index.html file, but when I want to load raw.html, it says
Error: Failed to lookup view "error" in views directory
app.js
var routes = require('./routes/index');
var users = require('./routes/users');
var raw = require('./routes/raw');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/raw', raw);
/routes/index.js
var express = require('express');
var router = express.Router();
var path = require('path');
router.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/public/index.html'));
});
module.exports = router;
/routes/raw.js
var express = require('express');
var router = express.Router();
var path = require('path');
router.get('/raw', function(req, res) {
res.sendFile(path.join(__dirname + '/public/raw.html'));
});
module.exports = router;
You are configuring express to use the pug (formerly known as jade) template engine.
A template engine enables you to use static template files in your
application. At runtime, the template engine replaces variables in a
template file with actual values, and transforms the template into an
HTML file sent to the client. This approach makes it easier to design
an HTML page.
The error you mention above is because you do not have a template file named error.pug in the views directory. The template engine catches the first error, which is:
Error: ENOENT: no such file or directory,
and then tries to render the error template.
res.sendFile(path.join(__dirname + '/public/index.html'));
The line above in your file routes/index.js will try to send routes/public/index.html and that file do not exists.
You can fix your express configuration using a correct path in your request handlers, i.e:
router.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/../public/index.html'));
});
You should also remove the template engine configuration, since you do not seem use it.
You mentioned in the comments that you want to use Angular, so...
You dont need a view engine if you want to use Angular.
When using Angular, the "main" part of your website is located on the clients' side, in the index.html file (this is not 100% correct, just an example).
That part (in the users browser) has JS code (Angular) that sends http request to the server - $http.
The server part basicaly just operates these requests and sends back data to Angular on the clients side, and then you do what ever you want with that data on the clients side.
You can respond to these requests with Node, PHP and etc.
This is similar to the idea behind AJAX, when only small parts of the page are changed without reloading the whole page.
On the other hand, if you are using view-engines, when the server gets a request, for example:
app.get('/',.routes.views.home);
The server renders an entire html page and sends it to the client, as it works with PHP.

Deploy Nodejs on Heroku fails serving static files

Im trying to do two things that i read, but its not working. The statics files dont found.
This not working:
process.env.PWD = process.cwd()
app.set('views', path.join(process.env.PWD, 'public'));
And this not working:
enter code hereapp.set('views', path.join(__dirname, 'public'));
Heroku for some reason doesnt work with __dirname, so try to this:
process.env.PWD = process.cwd();
app.set('views', path.join(process.env.PWD, 'public'));
app.use(express.static(path.join(process.env.PWD, 'public')));
This is what work for me when i have this problem.
This is because, Views are express partials which should be inside "views" folder like this
app.set('views', path.join(__dirname, 'views'));
For static files (HTML,CSS, JS) they should be inside the public folder, so to server files from public folder you need
app.use(express.static(path.join(__dirname, 'public')));
Thanks

Categories