express.static does not deliver - node.js

I searched through all topics, but could not find a similar issue.
I have a server.js in the folder /build
// /build/server.js
import express from 'express';
const app = express();
app.use('/static', express.static(path.join(__dirname, 'build', 'static'), { maxAge: '30d' }));
and a css file in /build/static/css/my.css.
I start nodemon with build/server.js from the root folder /
I assume that I should get my file via localhost:8080/static/css/my.css
But it returns a 404 and "Cannot GET /static/css/my.css"
What could be the issue?
I tried a lot of different paths, but never got a successful response.
Thanks in advance.

I finally decided to go with __dirname to prevent errors caused by relative paths to the directory the server is started from.
The main problem was that __dirname always returned /.
I added the following lines to my webpack config:
target: 'node', // was already there
node: { // has been added
__filename: false,
__dirname: false
},
You can find a closer description of this behaviour of __dirname in webpack here: https://github.com/webpack/webpack/issues/2010#issuecomment-181256611

Related

Using TypeScript with Express and static files

I've created a simple Express application and I compile it to TypeScript using TypeScript compiler, then I run the JS compiled script. The problem is, when I tried to implement node-sass-middleware:
app.use(
sass({
src: join(__dirname, "..", "src", "style"),
dest: join(__dirname, "style"),
debug: true,
})
);
__dirname is equal to dist folder.
Styles files aren't compiling, and the debug output is:
[sass] skip: / nothing to do
[sass] skip: /common/index.js nothing to do
App folder structure is:
src
- common
index.ts
- style
index.scss
app.ts
index.ts
server.ts
dist
- common
index.js
app.js
index.ts
server.ts
Can someone explain how to properly use TypeScript with Express.js with TypeScript to static compilation and Sass usage? Pretty please.

Serving express static files issue

I am having issues w/ serving static files in my current Express app, although I've done a similar setup in a bunch of other apps.. My folder structure is as follows:
/rootfolder/
/app
package.json
/client
/dist
/static
index.html
/server
/src
index.js
Relevant part of my server/src/index.js:
app.use(express.static(path.join(__dirname, "client", "dist")));
Where __dirname = /rootfolder/app/server/src
And when the user hits the / endpoint:
app.get("/", (req, res) => {
res.sendFile(appRoot.path + "/client/dist/index.html");
});
Where appRoot.path = /rootfolder/app
When I hit the / endpoint, I get a status 200 with the following text:
/rootfolder/app/client/dist/index.html
From what I can tell, the files are coded relative to each other correctly.. Does anyone know what I might be doing wrong?
Thanks in advance!
You're using res.send() instead of res.sendFile()
Also I suggest resolving your path via the path module, instead of concatenating a string.
const path = require('path')
app.use(express.static(path.join(__dirname, 'client', 'dist', 'static')))
And for the response of /:
res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html')))
Try
app.use(express.static(path.join(__dirname,'client','dist')));
It basically gets the root directory and combines it with /client+ /dist + /static to give you the full route, without being relative path.
Now Let's call rootdirectory/client/dist X. That is the main directory for static files
If you have other files that are static but not in the same folder, you will have to give relative path from the X directory
Example:
app.get('/',function(req,res){
res.sendFile('/static/data.txt');
}
In the example above you indicate that the static file(data.txt) is located in the X/static directory.
Therefore => rootDirectory/client/dist/static/data.txt
2nd Example:
Let's say you have a folder in dist called images which you want to only store images.
when you are giving routes, you MUST use /images/filename.extention

Heroku ENOENT: no such file or directory due to faulty express.js routing

I seen other people running into the same issue but I am starting to believe that I have a deeper issue with my express file setup since other solutions are not fixing it.
The idea that I had was to have a main page and then add folders for each of my projects. This is my folder structure:
And the code in the index.js is simply this:
const express = require('express');
const app = express();
app.listen(process.env.PORT || 5000, function () {
console.log('Example app listening on port 5000!')
})
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
app.use(express.static('asteroid'));
app.get('/asteroid', function(req, res){
res.sendFile(__dirname + '/asteroid/');
});
Now like many other question out there, the issue that I see in the log is "Error: ENOENT: no such file or directory, stat '/app/asteroid/index.html'". The app tries to go to /app and it can't find my files on there. I seem to be missing something simple.
Any idea what can be causing this in my case? I tried { root: __dirname }, joining everything with path(), and placed __dirname everywhere with no luck.
Looks like the file listing shows Asteroid uppercase. Maybe try renaming it to be lowercase everywhere?
If you're using express static then you don't need routes for each file. So maybe just use static or just use routes.

Visual Studio Code - Node.js - Cannot find name '__dirname'

Just to preface I'm not a professional coder, but nonetheless I got roped into building a website for my boss after he found out I took "Web Design" in high school 10 years ago. Back then static sites were fine, and heck CSS was just starting to show it's potential, but I digress.
I'm working on a Node.js project on Visual Studio Code right now and have a weird exception. The code works fine, but I guess it's just curiosity at this point. Anyway, here's my code.
app.js
var express = require('express'),
app = express(),
bodyParser = require('body-parser'),
multer = require('multer'),
controller = require('./controllers');
//Sets the view engine to jade.
app.set('views', __dirname + '/frontend');
app.set('view engine', 'jade');
//sets up the development enviroment
if (app.get('env') === 'development') {
app.locals.pretty = true;
app.use(express.static(__dirname + '/build/public'))
var build = require(__dirname + '/build.js');
app.use('css/*', function(req, res, next){
build.style();
next();
});
}
//Sets up the public directory to serve static files - This will be depricated quite soon...
//app.use(express.static(__dirname + '/public'));
//Initalizes site-wide local variables
//app.set('title', 'Halvorson Homes');
//Sets up body-parser to be able to read RESTful requests
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(multer({dest: 'tmp'}).fields());
//Load Controllers
app.use( '/' , controller);
//makes the app listen on port 3000
app.listen(3000, function() {
console.log('Listening on port 3000...');
})
My folder structure is pretty much as follows
controllers
index.js
designs.js
models
designs.js
frontend
common
layout.jade
header.jade
footer.jade
client.js
style.less
index
index.jade
client.js
style.less
designs
index.jade
client.js
style.less
build
tmp
srv
app.js
build.js
package.json
According to VS Code's built in debugger there's exceptions on lines 8, 14, and 15. They're the only places I used __dirname in the entire project. This is an annoying to me, as I am too much of a perfectionist. Is it Node, VS Code, or something else?
The warning you are getting is from the eslint extension. While it may be valid in Node.JS, it's warning you about __dirname because it's not valid in all JavaScript environments such as in browsers.
To suppress the warning you will want to create an .eslintrc file in your project's root directly and indicate that the code will be running in node like so:
{
"env": {
"node": true
}
}
You can see the .eslint file used to configure eslint for the actual vscode codebase here https://github.com/microsoft/vscode/blob/main/.eslintrc.json
Late to the party, but just had the same issue. The fix for me was to add the node types so VSCode recognises them:
Go to the Terminal view, then enter the following:
npm install #types/node --save-dev
Then hit Cmd + Shift + P (for Mac at least) to bring up the VSCode command search dialogue, then select Reload Window.
When it reappears, that error and any other related to Node.JS stuff not being recognised should be gone.
Alternatively to creating a separate .eslintrc file, you can also add it to the package.json file.
The docs state:
To specify environments in a configuration file, use the env key and specify which environments you want to enable by setting each to true. For example, the following enables the browser and Node.js environments
{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"env": {
"browser": true,
"node": true
}
}
}

serving static files with restify (node.js)

I have the following code:
app.js
[...]
server.get(/\/docs\/public\/?.*/, restify.serveStatic({
directory: './public'
}));
server.listen(1337, function() {
console.log('%s listening at %s', server.name, server.url);
});
And I have the following file structure
app.js
public/
index.html
So I try browsing:
http://localhost:1337/docs/public/index.html
and I get
{
code: "ResourceNotFound",
message: "/docs/public/index.html"
}
I tried with several variations, but none of them seemed to work.
I'm sure it should be something pretty obvious I'm missing
restify will use the directory option as a prefix for the entire route path. In your case, it will look for ./public/docs/public/index.html.
The directory option is a prefix for your entire path.
Relative paths are not working correctly in later versions of Restify (I tested 2.6.0-3, 2.8.2-3 - and they all produce the NotAuthorized error)
The solution now becomes:
server.get(/\/docs\/public\/?.*/, restify.serveStatic({
directory: __dirname
}));
And then your static files will need to be in ./docs/public.
(__dirname is a global variable that contains the absolute path of the script you are running)
Based on #NdeeJim's answer, to anyone wondering how to serve ALL the static resources:
server.get(/\/?.*/, restify.plugins.serveStatic({
directory: __dirname,
default: 'index.html',
match: /^((?!app.js).)*$/ // we should deny access to the application source
}));

Resources