Skip to content
New issue

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

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

Already on GitHub? # to your account

Remove modules / Support multiple apps #1321

Closed
samccone opened this issue May 14, 2014 · 43 comments
Closed

Remove modules / Support multiple apps #1321

samccone opened this issue May 14, 2014 · 43 comments
Labels
Milestone

Comments

@samccone
Copy link
Member

Much has been said about these crazy things, the code base will cheer when they are dead.

Multiple apps should solve peoples needs.

Lets put this as critical for the path to v3.

@samccone samccone added this to the v3.0.0 milestone May 14, 2014
@samccone samccone added the major label May 14, 2014
@jamesplease
Copy link
Member

Bye modules 👋

@cobbweb
Copy link
Member

cobbweb commented May 15, 2014

Ah this is a good solution to the module problem 👍

@JSteunou
Copy link
Contributor

Hooooo no :'(

@samccone @jmeas please reconsider:

I'm currently using modules in a lot of my app! It allows us to share tiny "group" of views, logic that have one goal.

Like a module that displays modals / popups for example. They mostly do not have router, but they have an init phase, a controller, some views and an API through events.

We were so glad when you introduced "Class" based modules, please do not through it away.

@JSteunou
Copy link
Contributor

Ok I was so afraid I even did not read #1229 before booing.

In fact if I can do the same with multiple app, I'm taking it. Could be a big enhancement!

@samccone
Copy link
Member Author

@JSteunou yeah this is slated for v3 but i think you will be able to move over to multiple apps prior to three when we fix a few event issues. I agree this is going to be a pain for most people using marionette, however it will improve patterns and peoples code by so much.

@jamesplease jamesplease changed the title Remove Modules Remove modules / Support multiple apps May 22, 2014
@tony
Copy link
Contributor

tony commented May 26, 2014

@samccone : I'm quite interested in this. @isochronous took a stab at this at https://gist.github.com/isochronous/4185418. I was looking into this all day and found this thread now, I'm happy to see people are open to having multiple apps.

Do any of you guys use Flask and are familiar with Blueprints? (see testsuite/blueprints.py).

A blueprint is basically the same as a Flask app, except it can be "mounted" under a url path or route.

The concept is similar to the gist, allow an Application to be ran by itself (as it is currently), but also allow an "ApplicationManager" (name could change?) to mount routes/events to a namespace.

@JSteunou
Copy link
Contributor

@tony I used to use Flask, that's why I'm using Marionette modules like Flask blueprint.

Independent re-usable component. That's the key!

If I still can do that but with Marionette App I say amen to that change.

@tony
Copy link
Contributor

tony commented May 26, 2014

Regarding things like #62, #1177, I think the pattern flask blueprints adopts hits the nail on the head.

@JSteunou : Seeing that, I think an ApplicationManager should be able to mount an Application, blueprint style.

  1. An Application can be started by itself, taking the main Router and vent namespace, great for testing and staying decoupled.
  2. Or it can be instantiated from an "ApplicationManager" somehow (whatever is most tasteful backbone/marionette aesthetics) onto an event / router namespace.

I'm inclined to believe a system where Application's can have a router, possibly by default, or can be mounted onto a routing prefix / event prefix with an ApplicationManager, is pretty much where things are going.

Keeping that in sync with bb / marionette aesthetics will be a key thing.

@JSteunou
Copy link
Contributor

+1

I'm struggling with actual Marionette objects to do things like that. I'm using App as the ApplicationManager and Module as Application, but Router as to be shutdown and relaunch everytime I stop or start a module.

@jamesplease
Copy link
Member

Might be worth looking at for ideas: https://gist.github.com/ShayDavidson/4578770

@JSteunou
Copy link
Contributor

Hey i'm using it exactly like this! I have a module.js instead of the index.js but that's it!

I just have some more candy features. Each module create an HTML node at body with a specific id and each module has a base marionette.layout which regions are given to the controller so the controller can change the main view and update header & footer.

Some modules do not have a complex layout, but just are drop in component to add some widget to our app.

On top of that the main app controller listen to children modules radio (thanks wreqr) to perform specific action, like shutting down some widget or starting others.

Also each module has its own router, but I have to be sure only one 'top level' module with router is started at a time. And stopping / starting a 'top level' module make me stop Backbone.History, clear routes before restarting it again.

@samccone samccone mentioned this issue Jun 13, 2014
@jamesplease
Copy link
Member

One of the use-cases for Modules should be replaced with Marionette.Namespaces. This would provide nearly-backwards-compatible functionality to users who rely on this behavior. The behavior I'm referring to is the anonymous fn definition of modules, which looks like:

myApp.module('My.Deeply.Nested.Module', function() {

});

Marionette.Namespaces could be a library that isn't included in core by default (we should promote AMD/CommonJS modules instead), but could work like this:

// Attach the library to your app
myApp.namespaces = new Marionette.Namespaces();

// Use it as you do
myApp.namespaces('My.Deeply.Nested.Namespace', function() {
  // lalala
});

For a super lightweight implementation of this we can get inspiration from @cobbweb's ocky.

@JSteunou
Copy link
Contributor

I do not think a new breaking major version like v2 should make 2 steps forwards and 1 step backward. Changes should be deeply assumed and pushed forward. Allowing old fashion way of adding modules while promoting new "app / sub app / modules" could be confusing and not helping the transition.

@jamesplease
Copy link
Member

@JSteunou, I don't disagree. More important to me than whether or not all users can replace their way of using modules, though, is simply getting them to be able to upgrade for each major release. I'm thinking that the use case for Marionette.Namespace are those apps that are simply too big to be changed. Like an app the size of the New York Times, or something. Just because we're promoting new, flashy modules doesn't mean it's feasible for apps that large to transition over.

This use case can be stressed such that it won't be a problem for other users. First, it will be removed from the core library. That's huge already. Removing things from core causes usage to plummet. Secondly, a big disclaimer will be at the top of the Readme for the library.

I think this will accomplish both goals – promoting better architecture while allowing everyone to keep their apps up-to-date. Win, win. What do you think?

@JSteunou
Copy link
Contributor

Sure it could be a win / win.

Is just moving to Marionette.Namespace will be enough though? I do not know all the changes made to app / module, but beside the submodule path, will that be a huge effort to make old module works? Arent you afraid that will bring a system on Marionette with deprecated but not removed features just to make Marionette.Namespace work?

@jamesplease
Copy link
Member

The beauty of this solution is that it will have no effect on the core library, and be trivial to update existing apps to use Namespace.

// what was once
app.module('myModule', function(){});

// is now
app.namespace('myModule', function(){});

There's no downside to this that I can see. Users of core are unaffected; users with apps that are too large to change can still upgrade.

@JSteunou
Copy link
Contributor

And so what about multiple app / router? Is this will be dropped in favour of Marionette.Namespace?

@samccone
Copy link
Member Author

@JSteunou that is a separate thing that we are still investigating :)

@JSteunou
Copy link
Contributor

Nice, you seem to got it all cover guys, start considering selling fan team shirts :D

@samccone
Copy link
Member Author

@JSteunou we will be making knit hats 👍 :

@jamiebuilds
Copy link
Member

Collectors Item: For the obsessed fan who doesn't like getting guilt tripped
dont-tell-james
FOR A LIMITED TIME ONLY

@samccone
Copy link
Member Author

i'd buy one

@jamesplease
Copy link
Member

looool

@JSteunou
Copy link
Contributor

@ridmahajan when you're using router things get messy because there is only one backbone history.

@cmaher
Copy link
Member

cmaher commented Jun 21, 2014

For the app, would it make sense to provide the option to configure the channel?

var App1 = new Marionette.Application({
 channel: 'channel1'
});

var App2 = new Marionette.Application({
 channel: 'channel2'
});

@jamesplease
Copy link
Member

@cmaher absolutely. That's a great idea. I can see that landing in 2.x, for sure.

For 3.x, though, I'm not sure if Applications will even have a channel!

@cmaher
Copy link
Member

cmaher commented Jun 21, 2014

@jmeas Assuming 3.x is a long way off, I'll work on that and submit a pull request.

@jamesplease
Copy link
Member

👍 v3 is at least 3-4 months away I'd wager.

@ridmahajan
Copy link

@jmeas Thanks for the clarity! That's helpful to know.
@JSteunou I'm not planning to implement routing in my app for now, but it's definitely something to keep in mind.

@stephanebachelier
Copy link
Contributor

About multiple applications in the same page which is something I'm using, the main concern is about closing an application. I miss the addFinalizer which where in Application a long (long!) time ago.

The addFinalizer and close methods delegate the cleanup to the developer.

As I am using AMD I don't use and don't need namespace. Also I don't use the App.vent but a single instance of EventAggregator which are used by every application and modules (think about AMD module not Marionette module)

When using multiple application anybody should be able to override the default app.vent with a custom one.

Are you interested with a PR ?

@JSteunou
Copy link
Contributor

@stephanebachelier I'm using modules as multiple app, all wrapped in a container app. This way you can start / stop your modules and wire a onStart / onStop method.

Using an instance of Wreqr in my container app & modules help a lot orchestrating all modules.

@jamesplease
Copy link
Member

When using multiple application anybody should be able to override the default app.vent with a custom one.

Are you interested with a PR ?

Yes, but one that implements @cmaher's suggestion to allow you to specify the channel per App.

new Application({
  channel: 'channelName'
});

Using channels gives you named instance of Commands, RequestResponse, and the EventAggregator, which is the recommended way to access instances of the three messaging systems.

@stephanebachelier
Copy link
Contributor

@jmeas I really like channels.
But how would you do in AMD without each module having a reference to any app ?

@JSteunou
Copy link
Contributor

You cannot. Somehow you have to expose an API from an App to let others App interact with you.
The simplest: each app create its channel from its name and document its API.

Others App can listen to events from another App, RPC like with req/res, etc.

@jamiebuilds
Copy link
Member

@JSteunou @stephanebachelier You don't need a reference to the app to get the channel

@JSteunou
Copy link
Contributor

I did not mean you would have to reference the app to get a channel. But you would have to have some acknowledgement between apps.Sorry I expressed my previous opinion the wrong way.

@stephanebachelier
Copy link
Contributor

@thejameskyle you are right about referencing an app to get the channel. My main concern is what @cmaher is trying to achieve in his PR #1528.
Configuring the application channel rather than accessing 'global' channel is better.

cmaher added a commit to cmaher/backbone.marionette that referenced this issue Jun 28, 2014
As discussed in marionettejs#1321, configurable channels for applications will allow
multiple applications to exist on the same page without picking up each
other's events.
jasonLaster pushed a commit that referenced this issue Jun 28, 2014
As discussed in #1321, configurable channels for applications will allow
multiple applications to exist on the same page without picking up each
other's events.
@paulfalgout
Copy link
Member

We've been investigating the work it will take to migrate away from modules to multiple apps. First off, thrilled to be doing so soon. However there's one question that's been coming up. Currently our App loads and creates regions based on selectors already available in the DOM. Our "subapps" however generally load a layout right off the bat.

Is it expected that multiple apps will each control their own set of regions and if so what would be generating the markup? It seems like subapps would need the ability to render a layout template to use.

@JSteunou
Copy link
Contributor

JSteunou commented Jul 1, 2014

My 2cents: "subapps" or actual module should create their own DOM node and attach it to options.parentNode || body.
Then create a basic layout on it or just expose its self as region.

I do this and it keeps every modules very independent either from DOM and regions point of view.

@jamesplease
Copy link
Member

Honestly, we don't have a plan set in stone for how these sub apps / future modules will work. I don't think we can really advise you on future-proof ways to structure your architecture such that it lines up nicely with the next major release. It is still really far away.

What I can tell you is that it will likely be really easy to update your app, so long as you don't do anything too weird like rely on the fact that Module Classes propagate down an entire chain of newly-instantiate deeply-nested modules or anything like that (chances are, you'll be fine). The best advice I can give you is to find something that works and go with it.

What I can do is tell you how likely it is that whatever structure you come up will be easily formatted to fit future releases of Marionette.

cmaher added a commit that referenced this issue Jul 9, 2014
As discussed in #1321, configurable channels for applications will allow
multiple applications to exist on the same page without picking up each
other's events.
cmaher added a commit that referenced this issue Jul 12, 2014
As discussed in #1321, configurable channels for applications will allow
multiple applications to exist on the same page without picking up each
other's events.
cmaher added a commit that referenced this issue Jul 19, 2014
As discussed in #1321, configurable channels for applications will allow
multiple applications to exist on the same page without picking up each
other's events.
cmaher added a commit that referenced this issue Jul 21, 2014
As discussed in #1321, configurable channels for applications will allow
multiple applications to exist on the same page without picking up each
other's events.
cmaher added a commit that referenced this issue Jul 30, 2014
As discussed in #1321, configurable channels for applications will allow
multiple applications to exist on the same page without picking up each
other's events.
@samccone
Copy link
Member Author

samccone commented Sep 1, 2014

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

No branches or pull requests

10 participants