configure node express to serve static bower_components?
Javascriptnode.jsExpressBowerJavascript Problem Overview
I have a directory structure
projectName
| - bower_components/
| - public/
| - css
| - js
| - index.html
| - Gruntfile.js
| - package.json
| - bower.json
| - app.js
I would like to start my app and serve index.html
with node. So in app.js
I have:
var express = require('express');
var port = process.env.PORT || 3000;
var app = express();
app.configure(function(){
// Serve up content from public directory
app.use(express.static(__dirname + '/public'));
app.use(app.router);
app.use(express.logger());
});
app.listen(port, function(){
console.log('Express server listening on port ' + port);
});
At the bottom of index.html
I have:
<script src="../bower_components/jquery/jquery.js"></script>
<script src="../bower_components/d3/d3.js"></script>
<script src="../bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/spin.js/spin.js"></script>
<script src="bower_components/mustache/mustache.js"></script>
When I start the server, index.html
shows up but none of the above libraries load. I get the error (404):
GET http://localhost:3000/bower_components/jquery/jquery.js 404 (Not Found) localhost/:32
GET http://localhost:3000/bower_components/d3/d3.js 404 (Not Found) localhost/:33
GET http://localhost:3000/bower_components/bootstrap/dist/js/bootstrap.js 404 (Not Found) localhost/:34
GET http://localhost:3000/bower_components/spin.js/spin.js 404 (Not Found) localhost/:35
GET http://localhost:3000/bower_components/mustache/mustache.js 404 (Not Found)
How can I serve the files from bower_components?
Javascript Solutions
Solution 1 - Javascript
I use this setup:
app.use(express.static(__dirname + '/public'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
So any Bower components are loaded from HTML like this:
<script src="/bower_components/..."></script>
And any other client-side JS/CSS (in public/
) are loaded like this:
<script src="/js/..."></script>
Solution 2 - Javascript
You should use
app.use(express.static(path.join(__dirname, '/public')));
app.use('/bower_components', express.static( path.join(__dirname, '/bower_components')));
Note the usage of (path.join) which is different from @robertklep answer
Here is a note from Another SO questions which according to me captures it very well
> path.join will take care of unneccessary delimiters, that may occur if > the given pathes come from unknown sources (eg. user input, 3rd party > APIs etc.). > > So path.join('a/','b') path.join('a/','/b'), path.join('a','b') and > path.join('a','/b') will all give a/b. > > Without using it, you usually would make expectations about the start > and end of the pathes joined, knowing they only have no or one slash.
Solution 3 - Javascript
.bowerrc
file.
Bower can be configured using JSON in a Add an .bowerrc
file with the following contents at the root of your project with the contents.
{
"directory": "public/bower_components"
}
This will place the bower components your are refering to in the correct library and you will not need the extract static directory in express.
Solution 4 - Javascript
Change your directory structure to :
projectName
| - public/
| - bower_components/
| - css
| - js
| - index.html
| - Gruntfile.js
| - package.json
| - bower.json
| - app.js
And in index.html
do following changes:
<script src="../public/bower_components/jquery/jquery.js"></script>
<script src="../public/bower_components/d3/d3.js"></script>
<script src="../public/bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="public/bower_components/spin.js/spin.js"></script>
<script src="public/bower_components/mustache/mustache.js"></script>
Or another way is to turn your
bower_components
folder to severed as static content. (you can inject static middleware
multiple times for express)Add the following in app congfig to express. Then your config code looks like:
var express = require('express');
var port = process.env.PORT || 3000;
var app = express();
app.configure(function(){
// Serve up content from public directory
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/bower_components'));
app.use(app.router);
app.use(express.logger());
});
app.listen(port, function(){
console.log('Express server listening on port ' + port);
});
And in this case your directory structure remains the same. Hope this helps.
Happy coding.. :)
Solution 5 - Javascript
I'm using:
$ npm -version && node -v
2.11.3
v0.12.7
And my app.js
has this defining bower_components
as a static path:
app.use(express.static(path.join(__dirname, 'bower_components')));
In my Jade template, I reference jquery
and bootstrap
like so:
doctype html
html
head
title= title
link(href='bootstrap/dist/css/bootstrap.min.css', rel='stylesheet')
link(href='bootstrap/dist/css/bootstrap-theme.min.css', rel='stylesheet')
body
block content
script(type='text/javascript', src='jquery/dist/jquery.js')
script(type='text/javascript', src='bootstrap/dist/js/bootstrap.js')
I'm running Windows 7 (x64).
Hope this helps someone.
Solution 6 - Javascript
Had the same problem after moving bower_components into another folder. This has helped me to understand what was going on. The docs were useful: https://github.com/expressjs/serve-static
and I put this code into my node/express app.js file:
console.log('DIRNAME:', __dirname, 'JOINED:', path.join(__dirname, '../../bower_components'));
This is from index.html
<script src="/bower_components/jquery/dist/jquery.js"></script>
<script src="/bower_components/angular/angular.js"></script>
and in app.js
app.use('/bower_components', express.static(path.join(__dirname, '../../bower_components')))
which is a correct path in my case.
Solution 7 - Javascript
This also works for me:
app.use('/bower_components', express.static(__dirname + '/bower_components'));
Make sure you have reset your local server or make sure you are running nodemon for seeing your changes!