Serving different static content in NodeJS depending on route - node.js

I should preface this by the fact I am new to NodeJS, and more generally to all the coding your own web server business, so please bear with me.
What I'm trying to achieve basically is replicating Apache's alias mechanism. I should simply be able to configure a list of aliases and their corresponding path in a configuration file, then have Node serve the right resource depending on the request.
To achieve this I singled out two middleware to use on top of Connect: static and route. Route is mostly working as intended, but I have a problem grasping how static works. Specifically, my question right now would be : Is it possible to define multiple "statics" to use with connect and then choose which one you want to actually serve files through after receiving a request?
Thanks

You can define multiple static to use with connect.
app.use(express.static(__dirname + '/public1'));
app.use(express.static(__dirname + '/public2'));
The connect middleware will check if the file exists in the first directory and if not found it will check the next one.
But static means static you shouldn't use with req.
If you wish to serve files based on the req then you should set-up a dynamic route that can serve content based on the request.

Related

Is Create-React-App a Server Of It's Own?

I am pretty experienced with NodeJs and Express, but I'm a beginner in ReactJS.
I usually use ejs and deploy my server on Express like this and route server-side.
app.get("/", (req, res) => res.render("index.ejs");
app.get("/contact", (req, res) => res.render("contact.ejs", { data: data });
Something like this.
However, working with React (create react app), I find myself not using express at all for routing and only serve an API.
Create React App apparently already has a server (localhost:3000 by default) and I can perform client side routing directly there.
Should I deploy my server on a client-side framework, React?
I don't even need to serve static files on express.
Hope you understood me, thank you for your help :)
First of all react is a library and second of all, when you say that it has a server that means it's a development server, for reviewing the results while you're working on it locally (means when you are building your application, you need to see how it looks in real-time). It's not for production use or included in the build output. Now let's say your application is ready and you want to deploy it, then you run a build command which does the following for you
transpiles JS code
bundles code and assets
uses cache busting techniques for assets
removes dead code
and you will deploy your application on a server, so that it can be accessible to clients
I don't need to serve static files on express, explanation below
In modern-day websites, we don't have to use views because react comes into the picture and takes care of the clientside-UI that the user interacts with, so you are right that we don't have to use static files in express anymore but if you have a use case where you have to use it then you can use it, no one is stopping your from doing that
and lastly you can have your own node js server as well which your front end will be talking too, not for views but for data that is stored in database that you want to fetch and display it to the user
React by itself just create static html-css-js files, but for testing purposes, they have also included this handy way (localhost:3000 pipeline) to view the built files. Technically you don't need to use it, just use the build script, then set up an express server to serve the files from "build" folder, and it does the same thing.
About client side routing, basically what happens is the entire page gets downloaded client-side, and it uses the value in url box to show or switch to certain screens. This is why its called "Single Page Application", you are serving a single page to the client upfront with all the static code. Compare this to express-ejs where you serve static code conditionally, depending on the address.
Take a look at CRA's docs for more info about deployment.

Is there a way to know how many times a static file is served or it has been served or not at all in Node.js?

I'm using express to serve static files.
app.use('/downloads', express.static('downloads'));
The code that runs behind the scenes to serve static files in Express is quite simple (in fact, it's a single file!) - it doesn't deal with anything like logging or analytics.
If you want to add stuff like that, you will have to add a middleware to the chain that provides that functionality, either by using a third-party library or by writing your own.

Express Router Handling

I'm currently using express to handle client request. At one point I need to handle get request if user loads any page of my app. So, I want all the routes to be configured at some place.
For example:
"/about"
"/contact"
"/listing"
"/product"
Above there are multiple routes and for each route I need to write app.get('/about', handler)..like this. So rather then writing multiple get handlers I want to use these path dynamically.
Is there a best way which I can use to store all the route path at one place (not DB) and can read from there only. Currently I am thinking to use JSON where I will store all the path with method type, params etc.
Also please validate is this a correct approach to handle such things or any better way or any node module.
It's common practice to write different methods for each route.
This makes sense since you'll want to return something different for /about than for /contact.
To organise this in a scalable manner you should create different files for each route. You can look at this official Express.js example.

Jade+Express: Where does my client side Javascript go?

Where do I put my client side Javascript? I tried including it in my jade template like so:
script(type="type/javascript",src="../typeahead.js")
It returned this Cannot GET /typeahead.js
I also tried require('../typeahead.js') which unsurprisingly did not work. Just to clarify since I am new to Node.js, require is for server side code correct?
It can go wherever you want. You must write code to serve it.
Since you're using Express, there is a "static" module built-in for serving files on disk. Use it like this:
app.use(express.static(__dirname + '/public')); // 'public'; is your directory for static files
Remember that with Node.js, you're generally writing the server. There are not set ways of doing things for web apps... there is no requirement that you're even building a web app. Everything it up to you. There are common modules for common tasks (such as Express/Connect) but in the end it's up to you.
require is part of the Node.js API and doesn't work in a browser. However, there is always Require.js and Browserify.

Mostly static express app with one server side route

I have an application that I'm developing using express that is almost a purely static site, with the exception of two forms that are posted to the server (a contact form and a request form). The site has roughly 10 static pages and two server side routes to accept the form submission.
I started developing the front end of the application with jade, stylus, and coffeescript, using grunt as both a development server and a build tool to output a production ready version (concat, min, etc..) of all these static assets.
Now onto the two server side routes. I'm curious what peoples thoughts are on this situation, where the app contains 90% static HTML, with only one or two server side routes.
So far I've considered three options:
Option #1: Purely static HTML and "outsource" the two forms to someone like Wufoo
This would eliminate the need for express altogether in production. I could continue to use grunt to build the application. However, I don't like this approach since I wouldn't have total control over the form submission. Not to mention, the number of form submissions with a free account is limited.
Option #2: Purely server-side using express and Jade
I don't like this approach either since I would define 10 or so server side routes, all of which simply render a jade template. Isn't that overkill? My routes would be littered with app.get() calls that contain a single res.render() in the callback. Also, even though we're probably talking milliseconds, why include middleware on pages that don't require it?
Option #3: Mix of #1 and #2, using the express.static() middleware
For this option, I would use something like grunt-express. This is my favorite option, however it seems a little "dirty" to mix client and server side jade templates. What I mean by this is that the express app would have (two) server side routes that are responsible for rendering a jade template. Mixing this with a call to express.static() that points to a directory that contains static HTML files that have been compiled from jade seems a little "dirty" to me. I'm not sure why.
If I choose option #3, how would my grunt build script work? Preferably, I would like the build to output a dist/ folder which contained a production ready express app, including my tiny little app.js file.
Any thoughts are greatly appreciated!
Option #2
res.render(...) is very smart
It will not generate HTML again (if you do not change res.locals)
Beside that render has smart cache control, it will send "304 Not Modified" to browsers, instead of whole body.
Just use Option #2, and make sure browsers get 304 for static content. If you just a newbie to nodejs, make sure you start your node in 'production' mode, because jade is slow in 'development'.
You can render all the server side templates with something like
app.get('/:template', function (req, res) {
res.render(req.params.template);
});

Resources