I am using Express v3.0.0rc1 with Node v0.8.1 and I am trying to create a webserver that works off of a modular system for displaying routes and views.
Is there a way to display stylesheets and client-side javascript files from within the ./modules/foo/ directory instead of ./public when display requests from within the foo module routes?
My approach would be to set up an additional static middleware layer. This has the limitation that the static files used by your modules must have different names since any name conflicts will result in only the resource from ./public being served. According to this SO Setting up two different static directories in node.js Express framework, this may be the best you can do.
var express = require('express');
var http = require('http');
var app = express(); // Express 3+
var server = http.createServer(app);
app.configure(function(){
app.use(express.bodyParser()); // Parses incoming request date.
app.use(app.router); // Mount application routes
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/module/foo'));
});
app.get('/', function(req, res) {
res.send("Hello World!");
});
server.listen(3000, 'localhost');
});
Related
I have a super simple NodeJS Express site setup with the following Folder Structure:
Views just contains a singe file index.ejs and public just a few .css and .js files required to make my site work (bootstrap, jquery etc.).
Using this on my local machine works great, however, the moment I put it on my live server (Shared Hosting on A2 Hosting), trying to open the page gives me Error 403, any ideas of what I'm missing?
Here is my servers.js file:
var express = require('express'),
path = require('path'),
nodeMailer = require('nodemailer'),
bodyParser = require('body-parser');
var app = express();
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.get('/', function (req, res) {
res.render('index');
});
Have you tried all steps in their tutorial?
https://www.a2hosting.com/kb/installable-applications/manual-installations/installing-node-js-on-managed-hosting-accounts
Found it on StackOverflow:
https://stackoverflow.com/a/32535632
PS: I would prefer to write this as a comment, but I don't have enough reputation yet.
I'm fairly new at web development and I've been having an issue with requiring certain node modules in my Express application. I need to access certain code, but I'm having difficulty with the the intricacies of Node, and can't for the life of me access node_modules where I need to.
What I'm attempting to do is utilize the Cloudinary video-player from the node_modules that I've installed. I've included path links in the index.html file which is served from htmlRoutes.js, and I've explicitly directed express to statically load these files within the document, but the application does not recognize these paths as valid. I've tried requiring these modules in separate JS files served up from the public folder, but that's also invalid. From what I understand it might be my own confusion of client-side vs server-side programming, but I don't know how to resolve this, nor what resources I should be reading in order to do so.
Any help would be appreciated. Here's what my server looks like:
const express = require("express");
const path = require('path');
const bodyParser = require('body-parser');
const baguetteBox = require('baguettebox.js');
const cloudinary = require('cloudinary');
const axios = require("axios");
const app = express();
// Define a port to listen for incoming requests
// Sets an initial port. We"ll use this later in our listener
const PORT = process.env.PORT || 8181;
app.use(express.static('public'));
//static routes that attempts to fetch scripts from node_modules without revealing inner directory structure
app.use(express.static(__dirname + '/node_modules/lodash'));
app.use(express.static(__dirname + '/node_modules/cloudinary'));
app.use(express.static(__dirname + '/node_modules/cloudinary-core'));
app.use(express.static(__dirname + '/node_modules/cloudinary-video-player'));
// Sets up the Express app to handle data parsing
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//routes
require("./routes/htmlRoutes.js")(app);
// require("./routes/apiRoutes.js")(app);
//configure cloudinary api calls
// cloudinary.config({
// cloud_name: 'name',
// api_key: 'key',
// api_secret: 'secret',
// secure: true
// })
// Start our server so that it can begin listening to client requests.
app.listen(PORT, function() {
// Log (server-side) when our server has started
console.log("App listening on: http://localhost:" + PORT);
});
I have never seen node_modules packages served as static files directly, having said that, I will be agnostic with that working.
An alternative way to deal with this issue is to use a bundler such as Webpack and serve it with Express.js
The reason for this is that even being JavaScript, Webpack will compile the code into something interpretable by the browser, something that in many cases you do not find in a package of Node.js
If you need for example lodash, you dont have to access to node_modules/lodash. Just import lodash by declaring:
const lodash = require('lodash');
And you can now use lodash in the file you declaring lodash.
I am using the below code to serve statics files(js, images, css):
app.use(express.static(path.join(__dirname, 'public')));
But now the images have been moved to some different location in the project i.e. outside the public directory (lets say. images).
So how do I differentiate between images and js,css files and serve them from different locations?
EDIT
I guess I have to read the request headers and then decide where to route the request. But looks a little dirty to me.
Try with two separate endpoints:
import express from "express";
import {join} from 'path';
const app = express();
const publicPath = express.static(join(__dirname, '../public/'));
const publicImages = express.static(join(__dirname, '../images/'));
app.use('/public', publicPath);
app.use('/images', publicImages);
app.listen(3400, function() {
console.log("Express server listening on port 3400");
});
Then you use it like this: http://localhost:3400/images/ and http://localhost:3400/public/
In that case you just need to add one more static file configuration
app.use(express.static(path.join(__dirname, 'images')));
And it will be served as
http://example.com/files-from-images-folder
This is the code that I see everywhere for a simple static web server using node.js and express:
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(8080);
My question is how does express know when the request is for a static page vs. a dynamic page? For example, why would /index.html be served from the public folder and not from dynamic templates?
Thanks.
You can think of the routes you define as a chain of checks on the path defined in the URL. Express iterates one by one through each check looking for a match; once it finds one, it executes that callback.
In this case, express.static is defining a bunch of path checks for each file in the public directory. If you app.use(express.static(__dirname + '/public')); before your app.get('/index.html', function(req, res) { ... code, and there is an index.html file in there, it will use the static file over the dynamic one.
That's basically it.
Trying to set up connect's vhost middleware. Would love some help.
I've got my normal express.js app, with node_modules, public, views and routes directories. I've added another directory next to those which holds another express.js app.
I've added this line to my top level app (tedxgramercy):
app.use(express.vhost('chatter.tedxgramercy.com', require('./chatter/app.js').app));
And this line to my chatter app:
var app = exports.app = express();
The chatter app calls listen on port 8000, the main (top level) app calls listen on port 3000. I don't know if that's right.
When I launch my app (node app) it runs fine and I can access both apps on localhost:3000 and localhost:8000 respectively, but when I deploy to my server, the subdomain http://chatter.tedxgramercy.com doesn't work.
Any pointers? Do I have to change my DNS to point to the other port or something?
It's a simple, but somewhat tricky setup.
First, the main app.js:
var vhost = require('vhost');
app.use(vhost('chatter.tedxgramercy.com', require('./chatter/app').app))
app.use(router);
I included the router to make it clear that it is critical for it to be used after configuring virtual hosts.
Then, in chatter/app.js:
var express = require('express');
var app = express();
var path = require('path');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index');
});
app.use(router);
exports.app = app;
This is the bare minimum setup to render a Jade template in a sub app. Notice that app is exported, but no server is actually started since the main app is the server.