Node js - Less css cannot find file to import - node.js

I have two Less files in the public/stylesheets. I am using Express.js to serve them as CSS files.
The first file, one.less looks like this:
#import "another.less";
h1 {
color: red;
}
The second file, another.less looks like this:
p {
color: red;
}
When I try to load the page, the server quits with the error:
file 'another.less' wasn't found.
I have also tried an absolute path, but it didn't work.
This is my Express.js configuration:
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }))
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});

You should be using connect-less for this now.
The original less compiler you're using above is a part of connect, actually, and if you check out the current issue list, you'll see that TJ opted to not support less any further in connect due to the compilers being too different (a case of "can't make everyone happy") :
https://github.com/senchalabs/connect/pull/174
You can look up connect-less here :
https://github.com/MartinodF/connect-less
I'll put the steps for install here, but understand they could become dated (check the github page if this doesn't work, and let me know and I'll sync up):
Use NPM to install connect-less
npm install connect-less
Then load it in your app, specifying the source (and optionally destination) directory
app.use(require('connect-less')({ src: __dirname + '/public/' }));
This worked flawlessly for me on an armv7/Trimslice linux box with expressjs 2.5.2 and node 6.6

Edit:
'#import "/public/stylesheets/two";'
Original proposal did not work.

Related

Node and handlebars folder structure

I would like to change my file and folder structure a bit, I tried looking for solutions already online but didn't find anything simple and I have a feeling this thing should have an simple solution.
I have currently this
var expressHandlebars = require('express-handlebars');
app.set('views', __dirname + '/views');
app.engine('hbs', expressHandlebars({extname: 'hbs', defaultLayout: 'main'}));
My folder structure is as follows
views
-- frontend
---- (doesn't matter, gulp takes care of this for FE).hbs
-- layouts
---- main.hbs
-- index.hbs
What I wanna archive is to have
views
-- frontend
---- (doesn't matter, gulp takes care of this for FE).hbs
-- backend
---- views
------ index.hbs
---- main.hbs
Basically, I want when I open my views folder in root to have frontend and then backend folder. Backend folder in root should have main layout and then in folders different partials for specific views.
I can add backend folder without issues which changing
app.set('views', __dirname + '/views');
to
app.set('views', __dirname + '/backend');
But how do I swap the that layout is in the root of the views folder?
Just doing this will throw an error because he will look for layout in /backend/layouts/main.hbs and I want it to be in the root.
Also, later I render things by saying res.render('index', data);. Proposed solution should be able to do the same, or at least res.render('views/index', data); because the new views would be in folders.
Any help or tips appreciated.
Nevermind, found it out with help of coworker.
There is an actual option for this which I managed to miss when looking over documentation.
app.engine('hbs', expressHandlebars({
extname: 'hbs',
defaultLayout: 'main',
layoutsDir: './views/backend'
}));

Does using Stylus and CoffeeScript middleware slow down Node.js Express app?

Stylus and CoffeeScript middleware automatically compile any Stylus and CoffeeScript code for you without having to restart your app, eg you can edit a .styl file and just refresh the page in your browser and your changes will be there. I find this to be very convenient while developing, but would that severely effect the end-user's page load time in production?
My Express setup is usually something like this (CoffeeScript):
app = express()
app.set 'views', __dirname + '/views'
app.set 'view engine', 'jade'
compile = (str, path) -> return stylus(str).set 'filename', path
app.use stylus.middleware {
src: __dirname + '/stylus',
dest: __dirname + '/assets/css',
compile: compile
}
app.use coffee {
src: __dirname + '/coffee',
dest: __dirname + '/assets/js',
encodeSrc: false
}
app.use express.static __dirname + '/assets'
It will definitely be slower than serving the pre-compiled files statically (if Stylus and CoffeeScript don't support caching which I don't know). The question is, whether this matters. And this depends on the intensity of the traffic your app receives.
In general, I would suggest to pre-compile your files and serve it statically. For the deployment, I would suggest to use something like Gulp.js and watch your files. With gulp your files can be automatically compiled on file changes which is most of the time better than compiling it when the files are requested.

Problems with expressjs on Nodester

i just started using nodester as nodejs application paas and i stepped into a couple of problems.
Let me clarify that my local machine runs node 0.7 while on nodester i'm using node 0.6.17
The following code is inside my server.js file, executed by the platform:
app.get('/static', function(req,res) {
res.sendfile('views/myFile.html',function(error){
if(err)
res.send('An error has occurred');
});
});
app.get('/', function(req,res){
res.render('index.jade');
});
The rest of the code is the code generated by Express.js
in particular the configuration is
app.set('views', __dirname + '/views');
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'jade');
app.set('view options', {layout: 'layout.jade'}); //added by me but with no results
If i run this configuration in my local machine, everything works fine, the '/' route, perfectly sends the index.jade view inside the proper layout.jade view.
The '/static' route, sends index.html without problems.
But if i run this code on nodester (after editing package.json and asking for node 0.6)
i get different results:
The '/' route doesn't render the layout.jade, but only index.jade. This is pretty weird, since i just edited the layout.jade file, generated by express!
The '/static' route just throws an error, that i can catch with the callback. So the html file is not sent.
Where am i wrong? i am probably missing something.. any ideas?
Answer for 2
In nodester the node process might be running from a different directory making process.cwd() not equal to your app's root directory.
To solve this issue, use the following code
app.get('/static', function(req,res) {
res.sendfile(__dirname + '/views/myFile.html',function(error){
if(err)
res.send('An error has occurred');
});
});
Answer for 1
Similiar problem as above. So, please check and tell me.

Expressjs not recognizing static files

I have a nodejs app and am using expressjs. I've defined my static directory, but when I access it, it doesn't load. My express config is:
var app = express.createServer().listen(8001);
app.configure(function(){
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(app.router);
app.use('/public', express.static(__dirname + '/public'));
app.use(express.cookieParser());
app.use(express.session({ secret: "appsession" }));
app.use(express.errorHandler({showStack: true, dumpExceptions: true}));
app.set('views', __dirname + '/views');
app.set('view engine', 'hbs');
});
Inside my /public directory I have 3 folders, css, js, and img. Inside css I have a style.css. When I try to access it directly via http://localhost:8001/public/css/style.css I get: Cannot GET /public/css/style.css
Any ideas what I could be doing wrong?
Thanks!
EDIT:
It seems to be related to how I have my routes setup. I'm doing it like this:
var routes = require('./routes')(db);
pp.get('/', routes.index);
Then in my index.js file, I have:
module.exports = function(db) {
return {
index: function(req, res, next) {
res.render('index');
}
}
}
I have my error handling enabled, but when I use the routing in this way, it doesn't use expresses error handling, however if I take this out, it does.
You setup the static http middleware as follows:
app.use(express.static(__dirname + '/public'));
And retrieve a file in ./public/css/style.css with the url:
"/css/style.css"
public is not part of the path when you actually request the file.
Change your static handler to this:
app.use('/public/css', express.static(__dirname + '/public/css'));
Then http://localhost:8001/public/css/style.css should get what you want
Full sample app that allows curl http://localhost:8001/public/css/style.css:
app.js
|-public
|-css
|-style.css
var express = require("express"),
app = express.createServer();
app.use('/public/css', express.static(__dirname + '/public/css'));
app.listen(8001);
Was running into the same issue found the answer here
https://github.com/senchalabs/connect/issues/298
When you have try to use nested files it kinda get lost,
it says fixed on the tracker a year ago, however i tried today and worked fine
I figured it out.
I have two services running on my host. Django is running the site at the root: http://myURL.com, and then Node is running at http://myURL.com/node
The configuration is fine with all the files in Node. The index.html file is requested fine, but the index.html when it requests the stylesheets and static files, the request gets caught by Django before it makes it to Node. Django saw the file and had no idea what it is and returned the 404 error.
By disabling Django from catching the requests to those files it all works fine.

Twitter Bootstrap LESS with Node.js & Express

Since Twitter Bootstrap 2 is out, I wanted to integrate that into my Node.js project. Unfortunately, there's something wrong with the less compiler and I can't get it to work. I put all files into the public folder and set up a new project with express -c less newproj. and added the lines for less
less = require('less');
app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
All Node tells me is:
Express server listening on port 3000 in development mode
undefined
On the client side I get a 500 (Internal Server Error) for the bootstrap.css file, which should be compiled by lessc.
lessc bootstrap.less
Works fine.
Anybody knows how to solve the issue?
For posterity, this has changed a lot in recent Express:
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
// This is just boilerplate you should already have
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
Ok, here is what I have found for you.
First you need both the compiler and the static middleware. The compiler compiles your less and recompiles on changes, the static middleware does the actual serving of the css
app.use(express.compiler({ src : __dirname + '/public', enable: ['less']}));
app.use(express.static(__dirname + '/public'));
Second, for some reason when the compiler runs it is losing the current path information, so it can't find the includes. So I had to go through the bootstrap.css and add the path to each import.
#import "/public/stylesheets/reset.less";
This is clearly odd, I am going to dig into it further.
Edit: While odd, a deep look through the code shows me no simple way around it. A bit more searching found this pull request on the connect repo https://github.com/senchalabs/connect/pull/174 which offers a fix for this, but the devs don't seem to want it.
There are also some workarounds in that thread, but it seems the best idea is to absolute path your includes.

Resources