문제

I'm using the client-side javascript version of LESS to compile out less code, and would like to continue using this even on the final live site (I know... bad form, but it gives me the ability to allow users to customize a few less variables and have that "theme" their whole app on the fly, seeing as it's a webapp that once loaded never refreshes, I'm thinking the additional second of load time to compile the less is acceptable).

I'm also using requireJS.

The question is:

A) How do I get requireJS to load less code?

B) Does less dispatch any events when compilation is complete? and

C) Is there a way to trigger less to re-compile on command?

Thanks.

도움이 되었습니까?

해결책

I have used the text loader plugin for RequireJS to load the .less file as text, then create a new less.Parser instance to parse the text, then add the style text myself:

(new less.Parser()).parse(lessText, function (err, css) {
  if (err) {
    if (typeof console !== 'undefined' && console.error) {
      console.error(err);
    }
  } else {
    var style = document.createElement('style');
    style.type = 'text/css';
    style.textContent = css.toCSS();
  }
});

You could take a similar approach, but give the style node an ID and remove that ID and then add back another reparsed LESS text when you want on demand.

A caveat: the text plugin can only load text files on demand when the text file is on the same domain as the web page. If you use the RequireJS optimizer, you can inline the text into a built, optimized JS file.

다른 팁

@jrburke: I've put together a quick requirejs plugin based on your code:

define({

    version: '0.1',

    load: function(name, req, onLoad, config) {

        req(['text!' + name, 'base/less'], function(lessText) {

            var styleElem;

            (new less.Parser()).parse(lessText, function (err, css) {
                if (err) {
                    if (typeof console !== 'undefined' && console.error) {
                        console.error(err);
                    }
                } else {
                    styleElem = document.createElement('style');
                    styleElem.type = 'text/css';

                    if (styleElem.styleSheet) 
                        styleElem.styleSheet.cssText = css.toCSS();
                    else 
                        styleElem.appendChild( document.createTextNode( css.toCSS() ) );

                    document.getElementsByTagName("head")[0].appendChild( styleElem );
                }

                onLoad(styleElem);
            });

        });     
    }

});

"base/less" points to the less source. You could also load this ahead of time, and assume the global less object exists. Ideally, I'd like to pull the less Parser object into this plugin itself so it doesn't create a global at all.

Using this I can do stuff like:

require(['less!global.less'], function(elem) {

});

At which point, global.less has been parsed and added to the page and gives back elem pointing to the style element in case I need to remove or modify it for some reason.

Does anyone have any input or know a better way of doing this?

Cheers

I was having trouble with @nicholas plugin with imports. I fixed it by adding the path of the file to the search path, and set filename for better error messages:

// http://stackoverflow.com/questions/5889901/requirejs-and-less
// enables require(['share/less!whatever.less'], function(elem) {});
define({
    version: '0.1',
    load: function(name, req, onLoad, config) {
        req(['share/text!' + name, 'share/less-1.3.0'], function(lessText) {
            var styleElem;
            var parser = new(less.Parser)({
                filename: name,
                paths: [name.split('/').slice(0,-1).join('/') + '/'],
            });
            parser.parse(lessText, function (err, css) {
                if (err) {
                    if (typeof console !== 'undefined' && console.error) {
                        console.error(err);
                    }
                } else {
                    styleElem = document.createElement('style');
                    styleElem.type = 'text/css';

                    if (styleElem.styleSheet)
                        styleElem.styleSheet.cssText = css.toCSS();
                    else
                        styleElem.appendChild( document.createTextNode( css.toCSS() ) );

                    document.getElementsByTagName("head")[0].appendChild( styleElem );
                }
                onLoad(styleElem);
            });
        });
    }
});
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top