Using LESS in atom-shell


#1

I’m guessing the answer is “generate the CSS using a watcher process and link to it directly in your main window’s HTML”. Or possibly "link to less.js and include your *.less files as <link rel="stylesheet">. But I thought I’d ask the experts here if there’s another way.

I’d prefer not to have a separate process from the Atom/browser process itself. I’d also prefer not to have to “compile” the LESS files every time I show a new window.

Is there some way to make the browser process generate the CSS from the LESS file and insert it into the page? I tried using WebContents.insertCSS but could never get it to work. When is it safe to call that method? I called it just after a call to loadUrl and then tried calling it from within a did-finish-load event handler but neither worked nor produced an error.

I tried following what Atom itself is doing but got lost in the layers of abstraction. It looks like it’s relying on the Package lifecycle to insert the CSS via the template manager, or the less cache? My app is simpler so I was hoping my solution would be simple, too.


#2

And hey! Looks like a classic case of overthinking it! I included the LESS files straight in as <link rel="stylesheet" href="less/main.less> and it worked beautifully.

Okay, then. :blush:

EDIT: Oh, right, it’s just getting served as text/plain and not getting preprocessed. Classic case of UNDERthinking it. :blush:++


#3

Sorry to keep bumping, I’m on a mission of discovery.

I ended up compiling the LESS in my renderer doing this:

var fs = require('fs');
var less = require('less');

var styles = fs.readFileSync(__dirname + '/../../less/main.less', 'utf8');
less.render(styles, {
  paths: [__dirname + '/../../less']
}, function(e, output) {
  console.log('less render complete.');
  var styleElem = document.createElement('style');
  styleElem.type = 'text/css';
  styleElem.appendChild(document.createTextNode(output.css));
  document.head.appendChild(styleElem);
});

There’s a pretty long flash of unstyled content while that’s happening. Any tips are appreciated.


#4

Don’t worry about bumping with real useful information :grinning: That’s what the board is for! You’re on a roll … I’m sure this information will help people down the line. Thanks for contributing!


#5

Actually, I’m building some atom-shell apps internally using stylus instead of less so I’ve pretty much the same issue than yours regarding compilation. I opted for a compile/copy grunt task rather than trying to compile everything on the fly (faster startup time, less risks than something break when the app is deployed).

If you still want your app to compile the less files for you at runtime, you can try to compile them in the main script (the one that actually open the window with the html file), then caching it somewhere so that you HTML file can retrieve them, or pass them in some way to the html file. Another approach could be to start a node server in the main script whose purpose would be to compile/serve this kind of assets.


#6

That’s an interesting idea! Thanks for the suggestions! It seems a leetle weird to start a web server to get my native app to render… but hey, they’re my parameters. :wink: The more I think about it the more a npm script watcher process makes sense…

Not sure how much time I’ll get to work on it today, but I’ll probably try rendering it somewhere cacheable on the browser process first and see if there’s noticeable lag pulling it to the renderer process.


#7

I would be willing to bet there are a dozen NPM modules to do exactly what you want.


#8

Indeed! I ended up doing this as a script in package.json:

"watch-css": "catw -c 'lessc --include-path=less/ less/main.less' 'less/*.less' -o static/css/style.css -v",

Figured I should stop ice-skating up hill.