Express serve static files inside Router - javascript

I am currently working on a nodejs project, and I have a simple question. I want to serve some libraries from my node_modules folder statically to the client (maybe stupid, but not relevant to the question), but I dont want to trash my main server JS file with all these statically served files like this:
const express = require('express');
const app = express();
// Imports here
app.use('/assets/lib/bootstrap', './node_modules/bootstrap/dist');
app.use('/assets/lib/axios', './node_modules/axios/dist');
app.use('/assets/lib/aos', './node_modules/aos/dist');
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
If I have 10+ imports, this would trash up my Server JS file, which I like to keep as clean as possible. I was wondering why this option wouldn't work:
./routes/route1.js :
const express = require('express');
const router = express.Router();
const path = require('path');
// Imports here
router.use('/bootstrap', path.resolve(__dirname, 'node_modules/aos/dist'));
router.use('/axios', path.resolve(__dirname, 'node_modules/aos/dist'));
router.use('/aos', path.resolve(__dirname, 'node_modules/aos/dist'));
// path to node_modules file is not the problem here
module.exports = router
And in my main Server JS file:
const express = require('express');
const app = express();
const route1 = require('./routes/route1');
// Imports here
app.use('/assets/lib', route1);
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
But this gives me an error. The file is not statically served to the client. Is this because an express Router can't serve static files? Maybe this is a rookie mistake, but any help is appreciated. The first code snippet does work, but I'm trying to keep my code organized.

Use the express.static middleware in your route1.js file instead of simply passing the folder path string to the route.

Related

React | React is not rendering anything in my project [duplicate]

I want to serve index.html and /media subdirectory as static files. The index file should be served both at /index.html and / URLs.
I have
web_server.use("/media", express.static(__dirname + '/media'));
web_server.use("/", express.static(__dirname));
but the second line apparently serves the entire __dirname, including all files in it (not just index.html and media), which I don't want.
I also tried
web_server.use("/", express.static(__dirname + '/index.html'));
but accessing the base URL / then leads to a request to web_server/index.html/index.html (double index.html component), which of course fails.
Any ideas?
By the way, I could find absolutely no documentation in Express on this topic (static() + its params)... frustrating. A doc link is also welcome.
If you have this setup
/app
/public/index.html
/media
Then this should get what you wanted
var express = require('express');
//var server = express.createServer();
// express.createServer() is deprecated.
var server = express(); // better instead
server.configure(function(){
server.use('/media', express.static(__dirname + '/media'));
server.use(express.static(__dirname + '/public'));
});
server.listen(3000);
The trick is leaving this line as last fallback
server.use(express.static(__dirname + '/public'));
As for documentation, since Express uses connect middleware, I found it easier to just look at the connect source code directly.
For example this line shows that index.html is supported
https://github.com/senchalabs/connect/blob/2.3.3/lib/middleware/static.js#L140
In the newest version of express the "createServer" is deprecated. This example works for me:
var express = require('express');
var app = express();
var path = require('path');
//app.use(express.static(__dirname)); // Current directory is root
app.use(express.static(path.join(__dirname, 'public'))); // "public" off of current is root
app.listen(80);
console.log('Listening on port 80');
express.static() expects the first parameter to be a path of a directory, not a filename. I would suggest creating another subdirectory to contain your index.html and use that.
Serving static files in Express documentation, or more detailed serve-static documentation, including the default behavior of serving index.html:
By default this module will send “index.html” files in response to a request on a directory. To disable this set false or to supply a new index pass a string or an array in preferred order.
res.sendFile & express.static both will work for this
var express = require('express');
var app = express();
var path = require('path');
var public = path.join(__dirname, 'public');
// viewed at http://localhost:8080
app.get('/', function(req, res) {
res.sendFile(path.join(public, 'index.html'));
});
app.use('/', express.static(public));
app.listen(8080);
Where public is the folder in which the client side code is
As suggested by #ATOzTOA and clarified by #Vozzie, path.join takes the paths to join as arguments, the + passes a single argument to path.
const path = require('path');
const express = require('express');
const app = new express();
app.use(express.static('/media'));
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, 'media/page/', 'index.html'));
});
app.listen(4000, () => {
console.log('App listening on port 4000')
})
If you have a complicated folder structure, such as
- application
- assets
- images
- profile.jpg
- web
- server
- index.js
If you want to serve assets/images from index.js
app.use('/images', express.static(path.join(__dirname, '..', 'assets', 'images')))
To view from your browser
http://localhost:4000/images/profile.jpg
If you need more clarification comment, I'll elaborate.
use below inside your app.js
app.use(express.static('folderName'));
(folderName is folder which has files) - remember these assets are accessed direct through server path (i.e. http://localhost:3000/abc.png (where as abc.png is inside folderName folder)
npm install serve-index
var express = require('express')
var serveIndex = require('serve-index')
var path = require('path')
var serveStatic = require('serve-static')
var app = express()
var port = process.env.PORT || 3000;
/**for files */
app.use(serveStatic(path.join(__dirname, 'public')));
/**for directory */
app.use('/', express.static('public'), serveIndex('public', {'icons': true}))
// Listen
app.listen(port, function () {
console.log('listening on port:',+ port );
})
I would add something that is on the express docs, and it's sometimes misread in tutorials or others.
app.use(mountpoint, middleware)
mountpoint is a virtual path, it is not in the filesystem (even if it actually exists). The mountpoint for the middleware is the app.js folder.
Now
app.use('/static', express.static('public')`
will send files with path /static/hell/meow/a.js to /public/hell/meow/a.js
This is the error in my case when I provide links to HTML files.
before:
<link rel="stylesheet" href="/public/style.css">
After:
<link rel="stylesheet" href="/style.css">
I just removed the static directory path from the link and the error is gone. This solves my error one thing more don't forget to put this line where you are creating the server.
var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public')));
You can achieve this by just passing the second parameter express.static() method to specify index files in the folder
const express = require('express');
const app = new express();
app.use(express.static('/media'), { index: 'whatever.html' })

How to serve static files in ExpressJS on some paths and not others

How can I serve static files with ExpressJS only from some of paths, while not for others?
To be more specific, I want to serve static files from all paths except /files (in case of request to this path, I want only to edit some file on the server).
I have this piece of code:
var express = require('express');
var app = express();
express.static(__dirname);
app.use(redirectUnmatched);
function redirectUnmatched(req, res) {
//Do something on server
console.log("req.url:"+req.url+"<br>"+__dirname);
}
let port = 80;
var server = app.listen(port);
But I really don't know, how to edit my code to do that...
Can anyone help me?
Thanks!
Just defining the /files route before serving the static files might work:
// Define `/files` route first
app.use("/files", function (req, res) {
return res.send("I will be served instead of a files directory");
});
// Static
app.use("/", express.static(__dirname));
const express = require('express');
const path = require('path');
const app = express();
app.use('/public',express.static(path.join(__dirname,'static')));
app.get('/',(req,res)=> {
res.sendFile(path.join(__dirname,'static','index.html');
});
app.listen(3000);

Why is my Node.js website not finding pages in public folder?

I am quite new to web development with node.js. I have an issue where loading one of my pages is giving the following error in my browser:
Cannot GET /public/pages/terms-and-conditions.html
The file structure looks like the following:
index.html
index.js
public/
pages/
terms-and-conditions.html
My index.js file looks like:
const express = require('express');
var path = require('path')
const app = new express();
var port = process.env.PORT || 3000;
app.get('/', function(request, response){
response.sendFile('./index.html',{ root: __dirname });
});
app.use(express.static(path.join(__dirname, 'public')));
app.listen(port, () => console.log(`listening on port 3000!`));
My button that directs them to terms-and-conditions is located in the index.html file and does the following:
<li>Terms & Conditions</li>
I have tried a many different paths to my file but must be missing something obvious.
SOLVED:
I needed to keep the path like follows:
<li>Terms & Conditions</li>
The "/public/pages/terms-and-conditions.html" is indicating that this is an absolute path.
Try "./public/pages/terms-and-conditions.html".

No default engine was specified and no extension was provided express

I'm trying to only use html and render pages from my express server. I keep getting the error
No default engine was specified and no extension was provided.
I have specified the dirname in app.js and I am telling the server to render by using the dirname in my router. I'm not really sure what's holding me up? Can someone provide some insight?
app.js ( I have removed import statements that aren't relevant)
var app = express();
app.use(express.static(__dirname + '/public')); //setting static file directory
//Store all HTML files in view folder.
module.exports = app;
here's my index router where I am calling render on the pages
var express = require('express');
var router = express.Router();
const path = require('path');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('main', { title: 'Express' });
});
/* GET styles page. */
router.get('/style', function(req, res, next) {
res.render('styles', { title: 'styles' });
});
/* GET styles page. */
router.get('/style',function(req,res){
res.sendFile(path.join(__dirname+'/style.html'));
});
module.exports = router;
If you don't have a renderer like Handlebars, you can't call res.render as far as I know. If you are serving static views you don't need a renderer anyways, you just specify the folder where the static files are located at.
This means after you have specified your static folder, you will be able to access the files by having their filename in the route. Express' documentation on static files. You don't need routes to send the files.
Example
CodeSandbox Example
src
|- view
| |- hello.html
|- index.js
index.js
const express = require("express");
//create a server object:
const app = express();
//Serve all files inside the view directory, path relative to where you started node
app.use(express.static("src/view/"));
app.listen(8080, function() {
console.log("server running on 8080");
}); //the server object listens on port 8080
module.exports = app;
You will now see hello.html on the /hello.html route. Any other file will also be visible under its name.

How to add Express route endpoints from another .js file?

I have an Express app whose server.js file has maybe 30 GET and POST endpoints, like this:
const express = require('express');
const app = express();
const http_port = 8000;
app.listen(http_port,()=>{
console.log(`app listening on port ${http_port}`);
});
app.get('/create_something',function(req,res){
createSomething();
res.send('create');
});
app.post('/update_something',function(req,res){
updateSomething();
res.send('update');
});
//and so on for 30 more endpoints
For ease of maintenance, I want to break this set of endpoints up into different files, e.g. video.js and audio.js.
Thinking this solution might help, I created another file other_route.js:
var express=require('express');
var router=express.Router();
router.get('/other_route_endpoint',function(req,res){
res.send('other_route_endpoint');
});
module.exports.router=router;
and then including this in server.js by changing my initial declarations to:
const express = require('express');
const app = express();
const http_port = 8000;
var router=express.Router();
router.use('/other_route',require('./other_route').router);
But when I visit myserver.com:8000/other_route_endpoint, I get this error:
Cannot GET /other_route_endpoint
How can I add in endpoints from other files into server.js, so I can move some of its many endpoints into these subfiles?
First, your main file should not be using a router. Change the line to app.use('/other_route',require('./other_route').router);.
Second: each path you set with router.use in the routing file will be relative to the path specified in app.use. See https://expressjs.com/en/guide/routing.html#express-router
For example, if you have this in your main file
app.use('/foo', require('./bar.js'));
And this in bar.js
router.get('/bar', /* do something */);
Then the corresponding endpoint would be /foo/bar.

Categories

Resources