Node.js Express/less-middleware & Bootstrap 3 - javascript

I've recently started learning Node.js and I am trying to set up an express install with less-middleware and want to use Bootstrap 3 less files. I've had a look around but can only find tutorials for Bootstrap 2.
This is my code so far:
/**
* 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.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(require('less-middleware')({
dest: __dirname + '/public/stylesheets',
src: __dirname + '/public/stylesheets/less',
prefix: '/stylesheets',
compress: true,
debug: true,
force: true
}));
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);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
When I run the server, I get the following:
GET / 200 190ms - 180b
source : /home/user/www/website.com/public/stylesheets/less/bootstrap.less
dest : /home/user/www/website.com/public/stylesheets/bootstrap.css
read : /home/user/www/website.com/public/stylesheets/less/bootstrap.less
render : /home/user/www/website.com/public/stylesheets/less/bootstrap.less
GET /stylesheets/bootstrap.css 200 565ms - 97.43kb
But the styles I have changed don't seem to take effect. Could someone tell me where I'm going wrong please?
Thanks

Used this instead from the less-middleware github page and it's working fine now.
var less = require('less-middleware');
app.configure(function(){
// ...
var bootstrapPath = path.join(__dirname, 'node_modules', 'bootstrap');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use('/img', express['static'](path.join(bootstrapPath, 'img')));
app.use(app.router);
app.use(less({
src : path.join(__dirname, 'public/stylesheets', 'less'),
paths : [path.join(bootstrapPath, 'less')],
dest : path.join(__dirname, 'public', 'stylesheets'),
prefix : '/stylesheets',
debug: true
}));
app.use(express['static'](path.join(__dirname, 'public')));
// ...
});

Related

Using Socket.io with Node.js, Express and Jade

I have some trouble to use Socket.io even just to test if a client is connected. I've tried many things and I think that my mistake is, maybe, when I do the app.get function. I have also tried to do this in an route js file but it wasn't conclusive neither. So here are my different codes :
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 mongo = require('mongodb');
var monk = require('monk');
var db = monk('mongodb://xxxxx:xxxxx#ds051067.mongolab.com:51067/jdo');
var app = express(),
server = http.createServer(app) ,
io = require('socket.io').listen(server);
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('This is secret'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
io.sockets.on('connection', function (socket) {
console.log('Un client est connecté !');
});
// app.get('/', routes.index);
app.get('/users', user.list);
app.get('/deplacement',routes.deplacement);
app.get('/monCompte', routes.compte);
app.get('/connexion', routes.connexion);
app.get('/', function(req, res) {
res.render('index.jade');
});
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Index.jade
extends layout
block content
script(src="/socket.io/socket.io.js").
var socket = io.connect('http://localhost:3000');
});
PS : Sorry if my english is bad ^^
You can't use inline javascript in the same script tag as an included script.
extends layout
block content
script(src="/socket.io/socket.io.js")
script.
var socket = io.connect('http://localhost:3000');

compile scss with nodemon and node-sass

I'm playing around with node.js, express and node-sass and watching for file changes with nodemon.
I added this bit to the app.js to compile the scss (according to the node-sass docs) but it's not doing anything. I would like for the sass to compile when nodemon runs app.js every time I make changes to the project.
I'm not sure if it will even work with nodemon like this but just running node app.js in the console without nodemon does nothing so it must be something I'm doing wrong.
APP.JS FILE
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var sass = require('node-sass')
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon(__dirname + '/public/favicon.ico'));
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')));
app.use(sass.middleware({
src: __dirname + '/public/scss',
dest: __dirname + '/public/css',
debug: true,
outputStyle: 'compressed'
}));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
thanks for any help.

app..get() does not seem to work in the Node.js Express application

Here is the app.js file:
var express = require('express'),
routes = require('./routes'),
api = require('./routes/api.js'),
http = require('http'),
path = require('path');
var app= module.exports = express();
/**
* Configuration
*/
// all environments
app.set('port', process.env.PORT || 3001);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
// development only
if (app.get('env') === 'development') {
app.use(express.errorHandler());
}
// production only
if (app.get('env') === 'production') {
// TODO
};
/**
* Routes
*/
// serve index and view partials
app.get('/', routes.index);
// redirect all others to the index (HTML5 history)
app.get('*', routes.index);
api(app);
/**
* Start Server
*/
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
Here is the routes/api.js file:
var queryObj = {
retrieve:{
api_path:'/api/test/list',
var_name:''
}
};
// All supporting functions used below are defined here !
module.exports = function(app) {
_.each(queryObj, function(obj) {
console.log("Check point 1");
var args = [obj.api_path, function(req, res){
var search_term = obj.var_name ? req.params[obj.var_name] : '';
get(search_term,res);
}];
console.log("Check point 2");
console.log("args:" + args);
app.get.apply(app,args);
});
};
Here is the routes/index.js file:
/*
* GET home page.
*/
exports.index = function(req, res){
console.log("Default view");
res.render('index');
};
So when i run this application and type localhost:3001/api/test/list in the browser, i get follwing output on the console:
Check point 1
Check point 2
`args: args:/api/alarms/list,function (req, res){
var search_term = obj.var_name ? req.params[obj.var_name] : '';
get(search_term,res);
}`
Express server listening on port 3001
Default view
My question is: why is app.get.apply() not working? Instead the default route configured in app.js is taken up!
I think you need to change the order of your route definitions: from most specific (in this case api/test/list to less specific *:
// defined api
api(app);
// serve index and view partials
app.get('/', routes.index);
// redirect all others to the index (HTML5 history)
app.get('*', routes.index);

Node.js spawns multiple processes

I got a little bit confused about my node.js application. As far as I thought, node.js runs in a single process. However if I start my application by invoking node app.jsand monitor it with htop, I can see 4 sub-processes running, where I'd expect only one to be.
app.js
var express = require('express'),
routes = require('./routes'),
objects = require('./objects'),
http = require('http'),
path = require('path'),
pinLayout = objects.pinlayout,
// utils
util = require('util'),
wiringPi = require('wiring-pi'),
winston = require('winston'),
async = require('async');
// Logger - winston
var log = new(winston.Logger)({
transports: [
new(winston.transports.Console)({
colorize: true,
timestamp: true
}),
new(winston.transports.File)({
filename: './log/app.log'
})
]
});
// WiringPi
wiringPi.setup('gpio');
var app = express();
// all environments
app.set('port', process.env.PORT || 3001);
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(require('less-middleware')({
src: __dirname + '/public',
force: true,
compress: true
}));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// 404 Page
app.use(function(req, res, next) {
res.render('404.jade', {
title: "404 - Page Not Found",
showFullNav: false,
status: 404,
url: req.url
});
});
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
}
Although your code runs in a single thread, node.js uses a thread pool (mostly) for file system operations. This is needed because there are no async APIs for fs.
For example, when you call file.readFile, you will go through Read(), which will call:
ASYNC_CALL(read, cb, fd, buf, len, pos);
read is the blocking unix read(2). This will run in a thread until it completes. These are the threads you are seeing.

ExpressJS - LESS compiling error on my layout in jade

I had set up compiling LESS on server side in Express, and it worked right in jade without putting less in layout.
my terminal:
if(err) throw err;
^
Error: ENOENT, open '/Users/lijung/Documents/Project/clubond/public/stylesheets/left_navigator.less'
app.js:
/**
* Module dependencies.
*/
var express = require('express')
, path = require('path')
, club = require('./routes/club')
, less = require('less')
, fs = require('fs');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
var RedisStore = require('connect-redis')(express);
app.use(express.cookieParser());
app.use(express.session({ secret: "william", store: new RedisStore }));
app.use(express.logger());
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.set('view options', { layout: false });
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
//index-in-layout
app.get('/club/:id', club.chkExist, club.getDataById, site.clubPage);
//compile less
app.get("*.less", function(req, res) {
var path = __dirname + req.url;
fs.readFile(path, "utf8", function(err, data) {
if(err) throw err;
less.render(data, function(err, css) {
if (err) throw err;
res.header("Content-type", "text/css");
res.send(css);
});
});
});
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
I put my layout in views named index_in_layout:
!!! 5
html
head
title= title
script(src='/javascripts/jquery.min.js')
link(rel="stylesheet", href="/stylesheets/index.css")
link(rel="stylesheet",type='text/css', href="/public/stylesheets/left_navigator.less")
script(src='/javascripts/index_in.js')
block script
body
index.jade:
extends ./index_in_layout
block script
script(src='/javascripts/new_club.js')
script(src='/javascripts/new_bond.js')
script(src='/javascripts/new_event.js')
script(src='/javascripts/popup.js')
script(src='/javascripts/list_clubs.js')
script(src='/javascripts/list_bonds.js')
script(src='/javascripts/list_events.js')
link(rel='stylesheet', type='text/css', href='/public/stylesheets/test.less')
block body
Terminal keeps telling me Error: ENOENT that my left_navigator.less can't open. I put test.less and navigator.less in the same directory, it makes no sense.
LESS on server side driving me crazy. Can someone help me out please. Thanks
Unless I'm missing something, you really don't need to go through these heroics to get less working :-) Generally you just need to add one line to your app.configure call like this:
app.configure(function() {
app.set('views', __dirname + '/views');
...
app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
app.use(connect.static(__dirname + '/public'));
app.use(app.router);
});
If you do it this way, you don't need the special route for *.less files. You just request *.css with the same name in your public folder and it's automatically generated. I use master/child layouts with jade and LESS here if an example would help:
https://github.com/JustinBeckwith/ExpressStarter
Happy Coding!

Categories