I just started using node and I'm trying to get it up and running with an express jade and stylus package. I think I have it set up correctly but the CSS files are not being compiled and I keep getting a 404 not found response when the request for the stylesheet is made.
Here is my server
/*
* Module dependencies
*/
var express = require('express'),
stylus = require('stylus'),
nib = require('nib');
var app = express();
function compile(str, path) {
return stylus(str)
.set('filename', path)
.use(nib());
}
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(stylus.middleware({
src: __dirname + '/public/stylesheets',
compile: compile
}));
app.use(express.static(__dirname + '/public'));
/* Routes */
app.get('/', function (req, res) {
res.render('index',
{ title : 'Home' }
)
})
/* Start the server */
app.listen(3000);
console.log('listening on port 3000');
and my layout.jade File
!!!5
html
head
title #{title} - My Site
link(rel='stylesheet', href='stylesheets/style.css')
body
header
h1 My Site
.container
.main-content
block content
.sidebar
block sidebar
footer
p Running on node with Express, Jade and Stylus
Figured it out
https://github.com/LearnBoost/stylus/issues/122
a request to /css/style.css interprets to /src/css/style.styl
Related
so I was trying to follow a tutorial to use node.js as the front end of a wordpress site
This one http://www.1001.io/improve-wordpress-with-nodejs/
Here is the code from server.js
var frnt = require('frnt');
var fs = require("fs");
var path = require("path");
var express = require('express');
var app = express();
var doT = require('express-dot');
// Define where the public files are, in this example ./public
app.use(express.static(path.join(__dirname, 'public')));
// Make sure this is set before the frnt middleware, otherwise you won't
// be able to create custom routes.
app.use(app.router);
// Setup the frnt middleware with the link to the internal server
app.use(frnt.init({
proxyUrl: "http://localhost:8888/frnt-example/wordpress", // The link to your wordpress site
layout: false // We simplify this example by not using layouts
}));
// define rendering engine
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'html' );
app.engine('html', doT.__express );
// respond with "Hello World!" on the homepage
app.get('/', function (req, res) {
res.send('./views/index.html');
});
app.listen(8080); // listen to port 8080
It keeps outputting the following
./views/index.html
Rather than rendering the html?
I've never used frnt, but res.send sends a string so that's no big surprise.
Look at res.sendfile which sends the contents of a file.
I prefer to use ejs , it's sems like html just edit index.html to index.ejs
1- install ejs module npm install ejs
2- add this in app.js
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
and render the index.ejs by using
app.get('/', function (req, res) {
res.render('index'); // or res.render('index.ejs');
});
res.send() // it send just a string not file
Hope it usefull !
I'm developing using node.js, and instead of writing css would like to write SCSS files that auto-compile whenever I refresh the page.
How can I get SASS files to autocompile when using NodeJS, Express and node-sass.
Update (7 Dec 2014)
The connect middleware from node-sass has been extracted into node-sass-middleware, see this answer
Install node-sass
In you project folder run:
$ npm install node-sass
Modify app.js
Assuming you have generated your app using
$ express my_app
Your app.js should look somewhat like this:
var express = require('express'),
routes = require('./routes');
var app = module.exports = express.createServer();
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
....
Here are the modifications:
var express = require('express'),
routes = require('./routes'),
sass = require('node-sass'), // We're adding the node-sass module
path = require('path'); // Also loading the path module
var app = module.exports = express.createServer();
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
// notice that the following line has been removed
// app.use(express.static(__dirname + '/public'));
// adding the sass middleware
app.use(
sass.middleware({
src: __dirname + '/sass',
dest: __dirname + '/public',
debug: true,
})
);
// The static middleware must come after the sass middleware
app.use(express.static( path.join( __dirname, 'public' ) ) );
});
It is important to note that
app.use( sass.middleware ... );
must come before
app.use( express.static ... )
The reason is that we first want sass to compile any sass files that has changed, only then serve them (which is done by express.static).
Restart your app
You'd have to restart your app in order for these changes to take place.
Include it somewhere so it compiles
We can now include app.scss in our /sass folder. But it won't compile just yet. The sass middleware will only compile files that are requested by your applications, so we must include the (to be rendered) css file somewhere, like in `/views/layout.jade':
doctype html
html(lang="en")
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel="stylesheet", href="app.css") < we've added this
body!= body `/views/layout.jade`
Notice that unlike style.css which is under the stylesheets sub-folder, the app.css is read from the root (in this case /public).
Fixing paths
With
app.use(
sass.middleware({
src: __dirname + '/sass',
dest: __dirname + '/public',
debug: true,
})
);
After the first compilation, the file and folder hierarchy will look like so:
Project folder
app.js
public
app.css < This is where the compiled file goes
sytlesheets
style.css
sass
app.scss < This is where the sass file is
You may want to have the compiled output in the stylesheets folder, rather than the public one; like so:
Project folder
app.js
public
sytlesheets
app.css
style.css
sass
app.scss
This way, the view will link to the css files like so:
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel="stylesheet", href="/stylesheets/app.css")
However, if you change the sass middleware configuration to
app.use(
sass.middleware({
src: __dirname + '/sass',
dest: __dirname + '/public/stylesheets',
debug: true,
})
);
things will go pear shape.
When linking to the css file like so:
link(rel="stylesheet", href="stylesheets/app.css")
the resultant request will be for stylesheets/app.css. But since we gave the sass middleware the following config:
src: __dirname + '/sass',
it will go and look for /sass/stylesheets/app.scss, and no such file exists.
One solution is to keep the config as is, but the put all sass files in the subfolder `/sass/stylesheets/. But there is a better solution.
If you define a prefix config like so:
app.use(
sass.middleware({
src: __dirname + '/sass',
dest: __dirname + '/public/stylesheets',
prefix: '/stylesheets', // We've added prefix
})
);
it will tell the sass compiler that request file will always be prefixed with /stylesheets and this prefix should be ignored, thus for a request for /stylesheets/app.css, the sass middleware will look for the file /sass/app.scss rather than /sass/stylesheets/app.scss.
Final code
app.js
var express = require('express'),
routes = require('./routes'),
sass = require('node-sass'),
path = require('path');
var app = module.exports = express.createServer();
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(
sass.middleware({
src: __dirname + '/sass',
dest: __dirname + '/public/stylesheets',
prefix: '/stylesheets',
debug: true,
})
);
app.use(express.static(path.join(__dirname, 'public')));
});
layout.jade
doctype html
html(lang="en")
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel="stylesheet", href="/stylesheets/app.css")
body!= body
Folders and files
Project folder
app.js
public
sytlesheets
app.css
style.css
sass
app.scss
The connect middleware from node-sass has been extracted into node-sass-middleware. Use as follows:
var fs = require('fs'),
path = require('path'),
express = require('express'),
sassMiddleware = require('node-sass-middleware')
var app = module.exports = express();
// adding the sass middleware
app.use(
sassMiddleware({
src: __dirname + '/sass',
dest: __dirname + '/src/css',
debug: true,
})
);
// The static middleware must come after the sass middleware
app.use(express.static(path.join(__dirname, 'public')));
I want to build a simple app using node.js that 'functions' like IIS/classic ASP where all the content (html, png, js, css, ejs) can be in one directory and the ejs file uses javascript vs. VBScript.
I've gathered the following from API's and other examples, but the ejs file arrives at the browser as a binary and gets saved....
My node.js file:
var express = require('express');
var app = express();
app.use(app.router);
app.use(express.static(__dirname + '/html'));
app.engine('.ejs', require('ejs').__express);
app.set('views', __dirname + '/html');
app.set('view engine', 'ejs');
app.get('*.ejs', function(req, res) {
res.render(__dirname + '/html' + req.url, function(err, result) {
res.end(result);
});
});
app.listen(8080);
My test.ejs file:
<!DOCTYPE html>
<html>
<head><title>A test</title></head>
<body>
My Test Page
<% if (1==1) { %>
Working
<%}%>
</body>
</html>
What am I missing or where can I find a working example?
I FIGURED IT OUT... SOLUTION ADDED ABOVE
express.js won't magically try to render static files, you have to explicitly call render somewhere.
I believe something like this would work:
var express = require('express')
var app = express()
app.engine('.ejs', require('ejs').__express)
app.set('views', __dirname + '/html')
app.set('view engine', 'ejs')
app.use(app.router) // only in express 3, remove that in express 4
app.get('/test.html', function(req, res, next) {
res.render('test.ejs')
})
app.use(express.static(__dirname + '/html'))
app.listen(8080)
I believe is not necessary to run render in every place, I use this example to render my static content by migrating express 2.3.7 to 4 and works fine with :
app.engine('.ejs', require('ejs').__express);
app.set('views', __dirname + '/public')
app.set('view engine', 'ejs')
app.use(express.static(__dirname + '/public'))
My static content is in 'public' directory.
I just want to add that express supports EJS out of the box these days:
https://expressjs.com/en/starter/generator.html
I have an existing coded frontend i.e views,javascripts,stylesheets (https://github.com/stdrunk/Taskr) and I intend to add this to the express framework so that i can link it to the db.
I added the contents to the public folder. The javascripts in the javascript folder, css in stylesheets, and images in images folder.
Then i changed the code of app.js according to this Render basic HTML view?
Now when run app.js and open the page in the browser i get a stripped version of my original page.
No error comes in the console.
This is my app.js
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
//app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/public'));
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
app.get('/home', function (req, res)
{
res.render('index.html');
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
You could put all those dirs under a 'public' dir, and then use:
app.use(express.static(__dirname + '/public'));
That way, express will always just send anything requested from those directories, and you won't need to worry about static files at all.
Although, I do recommend keeping something like Apache running on your server to serve static files. Images especially.
Ok, this is kind of wierd but here's the situation.
I'm playing about with Express and the Jade tempting system.
I have a fairly straightforward layout.jade file:
doctype 5
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
h1 Nav goes here!
body
block content
and a home.jade file:
extends layout
block content
h1= title
p Welcome to #{title}
The above combinations works fine.
But, i wanted to add a footer, so I created a foot.jade file:
extends layout
block foot
h1= me
And added include foot to my layout.jade file.
Now if I try to access the home page of my app, im getting a Maximum call stack size exceedederror :/
My app.js file is:
/**
* Module dependencies.
*/
var express = require('express')
, home = require('./routes/home')
, http = require('http')
, path = require('path');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', function(req, res) {
res.render('home', {title: 'Ninja Store'});
});
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
foot.jade uses extends layout, which loads layout.jade, which has an include for foot.jade, which uses extends layout, which loads layout.jade, ...
In other words: remove extends layout from foot.jade ;)