less / less.js

Less. The dynamic stylesheet language.
http://lesscss.org
Apache License 2.0
17.04k stars 3.41k forks source link

Feature request: Allow LESS.js to be run in environments that have JS but no DOM #1312

Closed stutteringp0et closed 10 years ago

stutteringp0et commented 11 years ago

global less option to NOT automatically parse the DOM searching for less links to compile.

Something like: autocompile:false

This would be a convenient addition which would allow less.js to be run in environments that have a javascript interpreter - but no DOM (like PHP implementations of Google V8 and Mozilla SpiderMonkey)

matthew-dean commented 11 years ago

Ah, interesting. Makes sense. I assume the Node implementation doesn't look for a DOM? How is that switch made there?

jonschlinkert commented 11 years ago

node.js runs on V8

stutteringp0et commented 11 years ago

Everything is notably difficult to implement in the sandboxed V8Js. As far as I know, you can't bring files into the sandbox, only strings. The documentation is thin.

It's ok though, I've found a way to fool less into thinking it's in a document when within the DOM-less V8Js environment....

    window = this;
    window.location = {
        href:"file:://",
        port:""
    }
    document = {
        getElementsByTagName:function(){ return [] }
    }

And I've managed to get less.js to render and return the result to PHP, so I'm good!

Having an option to prevent automatic parsing would save some steps for me, but now that I have a way around it - it seems less important.

lukeapage commented 11 years ago

This should form part of our work to seperate parser, node.js and browser.. the idea being you could implement an interface for sandboxed v8 and not use node or browser specific versions.

jonschlinkert commented 11 years ago

very interesting...

stutteringp0et commented 11 years ago

The V8 option is just to get me out of a pinch. @leafo of lessphp has been MIA for quite a while now and his version 0.3.9 can't compile Bootstrap 3 - which I've been tasked with deploying the nanosecond it's finalized. I could have as easily chosen the PHP implementation of Mozilla SpiderMonkey, and I'm not entirely sure this same code wouldn't work there. I'm going on with PHP because that's the environment I'm authorized to host.

My point is that although less.js is awesome - it's JavaScript - which is going to limit its usefulness. I won't deploy less to clients - not because less isn't reliable, but because clients (the users I mean) aren't reliable. They muck with their settings and I don't have time to support that. I can't use lessphp because it no longer works. So I take extreme measures - trudging through the less files, manually processing the imports to stitch them into a single less string to feed to V8Js serverside. It's ugly, but it only needs to run when the less files or variables change.

For me and the armies of Wordpress, Joomla, Drupal, .net guys out there who were using lessphp or dotnetless - the ultimate solution would be an official serverside implementation for each of the major languages. How great would that be? World Domination Great! You would be everywhere!

matthew-dean commented 11 years ago

The PHP code is problematic. I found that on a site that used the PHP LESS library, it had feature parity, but not equal error handling. So, there were things that were errors in the LESS code which failed silently in PHP, but gave an explicit error in Less.js.

At this time, we're only planning to implement / support one parser in JavaScript, but that still gives Wordpress, Joomla, Drupal devs lots of options. You don't have to have Node on your web server. You can precompile using various build systems or LESS GUI tools, and then distribute CSS with your site as you normally would.

Having said that, you've come across a known problem, which is that Less.js assumes you are either Node or you're a browser (which is often an incorrect assumption), and we're working to decouple that, as @lukeapage mentioned, and actually make a more extensible / modular API.

matthew-dean commented 11 years ago

One thought that a local LESS dev had down the road for people who want to work "live" on LESS files and don't have a Node backend handy is some kind of live build system, that you could reference like:

<link href="http://buildserver.example.com?http://mydomain.com/less/root.less" media="all" rel="stylesheet" type="text/css">

Probably crazy, but cool idea.

UPDATE: Credit to @zenimpulse for this idea.

jonschlinkert commented 11 years ago

"Less Express"? lol Yeah that is interesting. Another option is to create a simple service that works just like a CDN. The Dropbox API is pretty simple, you could have a service grab Less files, compile them, and make them available to a static shortened URL to retrieve the compiled CSS. Or do it the way a web font service like typekit does, with a script tag/account id.

leafo commented 11 years ago

@stutteringp0et Pushed a fix for you :wink: leafo/lessphp@dbb61d4beaafb0d708b79b008d0b708abeb4eae9

stutteringp0et commented 11 years ago

YAY @LEAFO

I'm in process of writing a set of classes to provide less capabilities by autodetecting V8, SpiderMonkey and falling back to lessphp. Likely, most will use lessphp

lukeapage commented 11 years ago

Same issue with dotless.. and I dont have time to work on both js and c# versions. Am thinking of doing the same thing..

matthew-dean commented 11 years ago

@jonschlinkert - I thought of that, but as soon as you get a script involved, then you're doing parsing of the LESS file in browser to know what @import files to send, and at THAT point, we might as well fix the browser component to work across the board, IE7 and up (which I'm not necessarily against). The reason we often recommend against using LESS.js in-browser is because a) it's buggy, b) it's not supported by all major browsers, c) we have a full plate just maintaining the feature set we have now. However, none of that has to do with whether or not it's a good idea. I'd recommended chopping off in-browser to focus the project, not because I think it's not a good feature. There's nothing stopping us from making Less.js in the browser production-ready, like TypeKit as you mention. I just think we need to go in one direction or the other. Either kill in-browser compilation, or make it awesome and a selling feature. Theoretically, if it were really production ready, then we could address issues about PHP / C# / hosted blog scenarios.

But, somewhat off-topic. To the original issue, we still need separation of the pieces to be more agnostic about environment.

jonschlinkert commented 11 years ago

but as soon as you get a script involved, then you're doing parsing of the LESS file

I was thinking that as I wrote it, but (since we're just having fun brainstorming here) to your point I was thinking that this would be a way around some of the browser issues - since node.js would really be doing the work.

I agree though, these are fun issues to explore but this:

we still need separation of the pieces to be more agnostic about environment.

...is the first hurdle. Right now I just want to try to remove obstacles for @lukeapage, since he has enough on his plate. For 2.0, once the repos are split out, it will start to get more interesting. IMHO, after the transition we should focus more on "utility API" functionality in the core repo, which can then be consumed and re-purposed across other Less projects, higher level build systems, etc - whether they are core or community.

stutteringp0et commented 11 years ago

Addendum to my previous post about the script necessary to prepare enough DOM for less.js

After finishing with my V8 implementation, I'm working on the SpiderMonkey implementation and it appears that the script used to prepare V8 works without modification in SpiderMonkey.

matthew-dean commented 11 years ago

@jonschlinkert Sounds good. I might be interested in looking at the browser implementation once we split everything out. Despite things I've said in the past few months, it might be an interesting engineering challenge if we could actually have a "production-ready" browser script.

stutteringp0et commented 11 years ago

I've hit a snag in my spidermonkey implementation.

I can pass an object into spidermonkey, and I use this object to: 1. deliver the less code to parse, and 2 to return the compiled CSS.

The problem I'm running into is that result.toCSS() causes spidermonkey to segfault.

matthew-dean commented 11 years ago

@jonschlinkert It's worth noting that the Wikipedia article on LESS mentions more than once that the distinguishing feature of LESS from other pre-processors is that it can be run client-side... which is sort of true, and I've heard mentioned from the beginning. http://en.wikipedia.org/wiki/LESS_(stylesheet_language)

jonschlinkert commented 11 years ago

@matthewdl I'm not entirely against keeping the browser version around, I think the "separation of concerns" and the increase in focus on each codebase after 2.0 could potentially lead to something more stable. In any case I agree with the point you're making, running LESS client-side seems to be viewed as a "quintessential" feature of Less.js - even though it's recommended not that it not be used that way in production, I think a lot of new LESS users use the browser version as a way of becoming familiarized with the language before taking the next step to learn how to pre-compile. I'd like to see it stay around after 2.0 if we can get more support - especially since the "newer" of a LESS developer you are, the more unlikely it is that you will add your voice to this discussion.

Soviut commented 11 years ago

There are plenty of situations where running it client side is the only way to use it effectively such as dynamic stylesheets or site hosts that only offer server-side editing of templates. It also vastly speeds up testing when you don't have to wait for the watch compiler to finish. And removes a technical step of installing node the less compiler and running a watch on their files.

I would see it fitting that any browser-specific code be factored into its own module that could be integrated for web builds only. This would leave a pristine core whose only responsibility is parsing.

matthew-dean commented 11 years ago

@Soviut Agreed. We were originally thinking of phasing out browser support because it was kind of mucking up the codebase for the parser. But we can achieve the same goal (cleaning up parser code) with proper separation. Make the parser completely pluggable with a flexible API, and then refine / maintain the browser component separately.

In some ways, I think the browser mode has never really "had its day", because it hasn't ever been deemed safe for production. But, I agree, while server-side mode may be recommended, there's an ease of integration for client-side mode that could be quite appealing, if a little more work were put into stability / browser support.

shovon commented 10 years ago

What's the status on this?

SomMeri commented 10 years ago

I think that it waits for this one #1732 , but I do not know whether someone started on that or not.

lukeapage commented 10 years ago

Yes, @matthew-dean was helping someone called nir started on it.. not sure on their progress or github username though.. would be good to know in case I get time to start on it.

matthew-dean commented 10 years ago

@losnir is the developer, and he's been busy, so this hasn't happened yet (and I don't think started). So, if someone else wants to take it on, that would be great. Yes @SomMeri, this is connected to #1732. The gist is that Less.js would strictly be a parsing / output library, but would support a basic API for environments to return file data. It would cover this issue as well because the "DOM" would be a concept of the "browser environment plugin", not Less.js. The Less library should not care about DOM. It should care about your Less input and returning CSS output, source maps, and object trees to environments that request them.

matthew-dean commented 10 years ago

Once the environment is decoupled and refactored, Less.js should be much more portable to any JavaScript environment, regardless of DOM, filesystem, or if it's run on a server or browser. @lukeapage You think you might take this on soon?

lukeapage commented 10 years ago

@matthew-dean I don't know, I think my first priority is finishing off less-docs, but I will contact Nir if I get to the point where I have time to spend on it.

lukeapage commented 10 years ago

This should be done in v2 http://lesscss.org/usage/#developing-less-how-to-run-less-in-other-environments I think we should raise new issue for specific problems with the changes