configure node express to serve static bower_components?

Javascriptnode.jsExpressBower

Javascript 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

Bower can be configured using JSON in a .bowerrc file.

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!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionConnor LeechView Question on Stackoverflow
Solution 1 - JavascriptrobertklepView Answer on Stackoverflow
Solution 2 - JavascriptAbhijit MazumderView Answer on Stackoverflow
Solution 3 - JavascriptArthur AndersonView Answer on Stackoverflow
Solution 4 - JavascriptAmol M KulkarniView Answer on Stackoverflow
Solution 5 - JavascriptFilmiHeroView Answer on Stackoverflow
Solution 6 - JavascriptMojoDBAView Answer on Stackoverflow
Solution 7 - JavascriptJavier Armero CiudadView Answer on Stackoverflow