This question already has an answer here:
I have a simple node.js application which uses socket.io and express. At the moment all of the javascript is in the HTML file but I would like to try and separate it out into a .js file.
In my main node application I have this:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
This works fine until I move my javascript from index.html to a .js file then try to reference it from my HTML file like this:
<script src="functions.js"></script>
I think that express is not serving the static file so I have tried this:
app.get('/', function (req, res) {
res.sendFile(__dirname + '/functions.js');
});
Can anyone tell me what I am doing wrong?
The solution is very simple: utilise
express.static
built-in middleware function in express.For example, you can add this into your main node application:
app.use("/js", static(__dirname + '/js'));
For more details, read this: https://expressjs.com/en/starter/static-files.html
nodejs and express do not serve ANY files by default. So, when you created your first route:
That successfully allowed a browser request for
/
to see your index.html file. The browser will then receive that HTML file and parse it. If it finds<script>
tags inside that file, it will then make a new web request to your server. So, if that file has this in it:The browser, will then ask your server for
/functions.js
. Since you had no route for that request, your server will return a 404 error and the browser will not get your script file.So, you have to make a route that will properly serve
/functions.js
when the browser asked for it, while still keeping your existing route that serves the index.html file.You can either make a specific route for
/functions.js
just like you did for/
. Or, for static files, you can useexpress.static()
to create a smart route that can serve many static files.To use
express.static()
you create a directory on your server (it can be anywhere), but folks often put it below the directory where your server files are. I generally choose to name itpublic
so it's obvious to everyone that these files are publicly available. Then, you can create a smart route using express.static like this:This line of middleware tells express that if any requests come in that start with
/js
, then look for a matching file in the__dirname + "/public"
directory. So, if a request comes in for/js/functions.js
, then look for a file named__dirname + "/public/functions.js"
. If that file is found, then serve it automatically. To make this work properly in your index.html file, you would make the<script>
tag be this:The
/js/
prefix I've used here is purely up to you. You don't even have to use a prefix and it can be named anything you want. You just have to make sure that the prefix you use in the<script>
tag matches the prefix you use in the first argument passed toexpress.static()
. I like to use a prefix for my static JS and CSS files so they are stored and looked for in a location that is different than my core HTML files (that's just a personal preference of mine, but down the road it might also make caching simpler or make using something like NGINX to improve performance simpler too).To use
express.static()
you have to save a reference to theexpress
module by changing this:to this:
Or, in any recent version of nodejs, I prefer to use
const
for variables that should not be reassigned: