Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aura heavily bound with RequireJS + others... why? #7

Closed
panosru opened this issue Feb 14, 2012 · 6 comments
Closed

Aura heavily bound with RequireJS + others... why? #7

panosru opened this issue Feb 14, 2012 · 6 comments

Comments

@panosru
Copy link

panosru commented Feb 14, 2012

As title says... why aura is so tight bound with RequireJS and jQuery and Underscore?

For example, the pup/sub technique that mediator uses shouldn't be bound so tight with RequireJS module autoloading and DOM selection as it is now, of course these are very useful, but only for those who use jquery + requirejs but thing is that not everyone uses (at least the second...).

I prefer to keep the following as the very basic example of mediator/facade pattern with permissions intermediate:

//==== Mediator Pattern
var channels = {};
var mediator = {};

mediator.subscribe = function (channel, subscription) {
  if (!channels[channel]) channels[channel] = [];
  channels[channel].push(subscription);
};

mediator.publish = function (channel) {
  if (!channels[channel]) return;
  var args = [].slice.call(arguments, 1);
  for (var i = 0, l = channels[channel].length; i < l; i++) {
    channels[channel][i].apply(this, args);
  }
};

//=== Permissions 
var permissions = {
  endContentEditing:{
    todoSaver:true,
    testing : true
  }
};

permissions.validate = function(subscriber, channel){
  var test = permissions[channel][subscriber];
  return test===undefined? false: test;
};

//=== Facade Pattern
var facade = facade || {};

facade.subscribe = function(subscriber, channel, callback){

  if(permissions.validate(subscriber, channel)){
    mediator.subscribe( channel, callback );
  }
}

facade.publish = function() {
  args = [].slice.apply(arguments, [0, 2]); // first two arguments for mediator
  arguments = [].slice.call(arguments, 2); // Rest for facade

  mediator.publish.apply(mediator, args);
}


//=== Application Use Case
facade.subscribe('todoSaver','endContentEditing', function (context) {
  try {
    console.loger('todoSaver');
  } catch (e) {
    console.log('todoSaver f**** up!');
  }
});

facade.subscribe('testing','endContentEditing', function (context) {
  console.log('testing');
});

facade.publish('endContentEditing', {
  test : 'test!'
});
@addyosmani
Copy link
Member

Perhaps what we should maintain are a few different versions of this, at least initially for reference purposes. The version I first posted was't as tightly coupled with RequireJS (much like the above), but I would like to see whether we can use it and it's dependency management system to evolving the first version of the codebase into something simpler.

I'm happy to dig up an earlier implementation we can either store in a different directory (or in branch), but if you feel your approach differed from that one greatly (if you remember that version of the code) please feel free to send a PR my way!

@panosru
Copy link
Author

panosru commented Feb 14, 2012

The only difference of the above code with your initial approach of aura is that you had:

facade.publish = function(channel) {
  mediator.publish(channel);
}

instead of

facade.publish = function() {
  args = [].slice.apply(arguments, [0, 2]); // first two arguments for mediator
  arguments = [].slice.call(arguments, 2); // Rest for facade

  mediator.publish.apply(mediator, args);
}

I prefer the second option to be honest.

Also the reason that I want to stick with the original version (and probably extend it a bit more) is that I personally develop apps in PHP and/or Node and for the apps I use 100% Node I tend to use Node's require instead of RequireJS since RequireJS is not the best way to go, also I had a discussion regarding requirejs with node so I end up using node module named modul8, as you can imagine if Aura is bound with RequireJS it will be hard for people who work with Node **-**RequireJS to use Aura, of course I could propose a node compatible version of Aura (which I plan to do for me) if you want so you could have a very basic example as the above + a node example without RequireJS.

@addyosmani
Copy link
Member

@panosru I would be fine with the second version to be honest. In a lot of cases, I've seen developers wishing to write for node opting for alternative module formats like CommonJS, whilst of course a RequireJS solution would work best with AMD (even though it can work with CJS modules too).

With this in mind, maybe what we could do is this:

  • Original version / original with your tweaks
  • RequireJS version (which is still in an experimental phase)
  • Node version

I'm sure there will be room for overlap between the implementations, but maybe this would allow us to cover the stacks people will be most interested in.

@panosru
Copy link
Author

panosru commented Feb 14, 2012

Yeap I agree :) I'll send a pull request most probably during this week :)

@addyosmani
Copy link
Member

Just to confirm: we've decided for the latest version to specifically use AMD for our module format and RequireJS as our loader. With respect to jQuery and Underscore, jQuery is used in the library but we're going to make it easier to switch out for something else. Underscore is just used for templating and can be replaced at any time with something else. Thanks!

@peterudo
Copy link
Member

One way to make jquery more easily replaceable, is to reference 'jquery' as 'dom', or something similar, instead.
This is the approach I'm currently using in my app, to be able to switch between jquery and zepto more easily.

First the config can be changed to something like this:

require.config({
    paths: {
        dom: 'aura/lib/jquery'
    }
});

You could then replace:

define(['jquery', 'underscore'], function ($, _) {
    // ...
});

With this:

define(['dom', 'underscore'], function ($, _) {
    // ...
});

Of course, this is a compile-time step, thus removing the ability to change the dom-library in the runtime. So if you want to have some client side check on which library to load, another approach might be better.
Just thought I'd share the idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants