stealjs / steal-less

A less plugin for StealJS
https://www.npmjs.com/package/steal-less
MIT License
4 stars 2 forks source link

Less plugin should share context with other loaded .less files #1

Open zkat opened 9 years ago

zkat commented 9 years ago

When loading files with the less plugin, it should make sure that compilation of those files groups all the .less files into a single compilation unit. The main reason for this is so already-@imported .less files get deduped and shared between all the less files that use them. There's a few details that go into this:

As far as I've spoken with Justin, it's not clear SystemJS is able to delay execution like this right now, so we might have to do some patching on that as well. For reference, @shcarrico did this previously (or things like it) for both old-steal and for webpack. This has been tricky to implement correctly in both of those systems, so I don't really expect it to be a simple/easy task for new steal either, but it's a fairly important feature, imo. The need for it will become even more obvious once we have a bunch of standalone can.Components getting distributed.

See bitovi/steal#346 in reference to this.

matthewp commented 9 years ago

What is the purpose of having it as a single compilation unit?

I agree that we should override less's own import mechanism to prevent duplicate loading (not sure how that would work).

But single compilation would be very difficult if not impossible. The reason is you don't know when the loader is really finished. So you can't wait for all less files to be ready.

If your concern is duplication that should be fixed by the minifier anyways. In dev it really shouldn't matter. I think it would be interesting if possible but I can't think (off the top of my head) of how to do that.

matthewp commented 9 years ago

Thinking a bit more about this it might be possible. How I would approach this is to create a separate loader that loads but doesn't execute modules to use as a trace. Collect all of the less/css. Once it's done you can copy over the modules into the main loader and reset their state to translate. From there I think loading would pick up at the current state. Here's some pseudocode (definitely not working, but a start):


function css(loader){
  var import = loader.import;
  loader.import = function(name){
    var cssLoader = loader.clone();
    cssLoader.csses = [];

    // Prevent execution.
    var instantiate = cssLoader.instantiate;
    cssLoader.instantiate = function(){
      if(/\.css/.test(load.name)) {
        cssLoader.csses.push(load.source);
      }

      // Prevent modules from being executed.
      return Promise.resolve(instantiate.call(this, load)).then(function(result){
        result.execute = function(){
          return cssLoader.newModule({});
        };
        return result;
      });
    };

    return cssLoader.import(name).then(function(){
      // An array of css contents. Insert them into the page somehow.
      var csses = cssLoader.csses;

      // Copy over the modules. and set the state to translate
      var module;
      for(var i = 0; i < cssLoader._loader.modules.length; i++) {
        module = cssLoader._loader.modules[i];
        module.state = 'translate';
        loader._loader.modules.push(module);
      }

      // Now run load to cause execution of the copied over modules.
      return loader.load(name);
    });
  };
}

if(typeof System !== "undefined") {
  css(System);
}
wclr commented 9 years ago

You could create less plugin that uses another FileManager that uses file cache shared across the process.

justinbmeyer commented 9 years ago

What does this mean and why should we do this?

Sent from my iPhone

On Mar 7, 2015, at 5:02 PM, Alex notifications@github.com wrote:

You could create less plugin that uses another FileManager that uses file cache shared across the process.

— Reply to this email directly or view it on GitHub.