Large AngularJS application design - javascript
I need advise on designing an AngularJS application with multiple complex modules and based upon the user role the module gets loaded after authentication & authorization. Some users could have access to one simple module and some could have dashboard and some could have access to 2+ modules.
There are lot of directives we have identified which can be reused across different modules. During the design phase we have identified the following things that should exist and we have answers for some of the below items, but we still need advice from experts:
A Module could have
Partials
Controllers
Directive
Services
Exception handling (HTTP Status code or Business errors)
Logging (With line number, from which function)
May also need to save the logged info in the server
Should have the ability to turn on and off logging
custom widgets via factory class (Reused in other modules)
Shared Directives (isolated scope)
Shared Modules
Shared Utilities (sorting, filtering, etc.)
Enumerators as per master data
Constants via singleton
Authentication (CSRF)
offline storage
REST services
Event handling for dispatching from one module and handling it in other
UI of the application looks like, a fixed menu bar on the top of the page with a drop down navigation on top left with multiple links depending on the user's role. When the user clicks on a link the corresponding module should get loaded in the page. There has to be an empty project which is manually bootstrapped and loads the other modules at run-time.
Our approach is to have the following folder structure:
app
assets
css
lib js
images
common components
directives
utilities
authentication
Service proxy to hold the $resource calls
Enums
Constants
Model
entity json (example customer, product, etc.)
business Module A
Partials
Directives
Services
Controllers
business Module B
business Module C
index.html
Requirejs config file
So my questions are:
How can a service inside a module talk to other module?
Module should be developed and run independently?
How the communication between module can be handled with transferring data?
How to integrate all the above elements, particularly exception handling, logging?
Developers should understand the convention we have defined?
What method to call for logging, sending info between module?
I recommend to include yeoman into your workflow and use a generator for your project, that makes a lot easier the way that you structure your app, specially if you are working in a team.
earlier this year people from angular released a document with best practices for your app structure, I'd recomment you to read it, being said that there's a generator based on those best practices named cg-angular which I totally recommend.
I'll quote from cg-angular site:
All subgenerators prompt the user to specify where to save the new
files. Thus you can create any directory structure you desire,
including nesting. The generator will create a handful of files in the
root of your project including index.html, app.js, and app.less. You
determine how the rest of the project will be structured.
regarding to your questions:
How can a service inside a module talk to other module?
you can create a folder for directives/ and services/ you are going
to reuse in different modules.
Module should be developed and run independently?
you can have several modules inside an app (you could load them as
needed, maybe using require js but this is offtopic)
How the communication between module can be handled with transferring data?
Use services to pass information between controllers, in different
modules
How to integrate all the above elements , particularly exception handling, logging?
you can do a generic error handler and a generic http interceptor for
all the modules
Developers should understand the convention we have defined?
use a generator they are opinioated and they give the order and the
conventions you need for a team.
Lots of good questions to be asking; they appear to be in two major groups -- the first is a question of code structure and the second is about metrics (logs, etc.).
How can a service inside a module talk to other module?
You should ideally be using directives for your modules. This way you can leverage the ability to link controllers via the require property. Here is a page on sharing data between directives and controllers.
Module should be developed and run independently?
I assume you're thinking about unit testing. Yes, your modules should ideally be as tightly-scoped as possible in order to make testing easier.
How the communication between module can be handled with transferring data?
This is where services are typically used. Note: services, factories and providers all mean the same thing in AngularJS, they're just declared in slightly different ways. Pick whichever one you're most comfortable with.
How to integrate all the above elements , particularly exception handling, logging?
Logging is a separate issue. The beauty of AngularJS is that you can very easily augment existing parts of the framework in order to add functionality or behaviors as you see fit. You do this using decorators. Here is an example of exception logging that I think will cover any use cases you might be interested in
Developers should understand the convention we have defined?
The answer to this is always the same: communication is how they know. Developers need to socialize the convention otherwise you'll never get buy-in.
What method to call for logging , sending info between module?
Answered above.
Code Organization in Large AngularJS and JavaScript Applications
Many developers struggle with how to organize an application's code
base once it grows in size. I've seen this recently in AngularJS and
JavaScript applications but historically it's been a problem across
all technologies including many Java and Flex apps I've worked on in
the past.
The general trend is an obsession with organizing things by type. It
bears a striking resemblance to the way people organize their
clothing.
Piles on the Floor
Let's take a look at angular-seed, the official starting point for
AngularJS apps. The "app" directory contains the following structure:
css/ img/ js/ app.js controllers.js directives.js filters.js
services.js lib/ partials/ The JavaScript directory has one file for
every type of object we write. This is much like organizing your
clothes into different piles on the floor. You have a pile of socks,
underwear, shirts, pants, etc. You know your black wool socks are in
that pile in the corner but it's going to take a while to dig them
out.
This is a mess. People shouldn't live like this and developers
shouldn't code like this. Once you get beyond a half-dozen or so
controllers or services these files become unwieldy: objects you're
looking for are hard to find, file changesets in source control become
opaque, etc.
The Sock Drawer
The next logical pass at organizing JavaScript involves creating a
directory for some of the archetypes and splitting objects into their
own files. To continue the clothing metaphor, we've now invested in a
nice mohaghony dresser and plan to put socks in one drawer, underwear
in another, and neatly fold our pants and shirts in still others.
Let's imagine we're building a simple e-commerce site with a login
flow, product catalog and shopping cart UI's. We've also defined new
archetypes for Models (business logic and state) and Services (proxies
to HTTP/JSON endpoints) rather than lumping them into Angular's single
"service" archetype. Our JavaScript directory can now look like this:
controllers/ LoginController.js RegistrationController.js
ProductDetailController.js SearchResultsController.js directives.js
filters.js models/ CartModel.js ProductModel.js SearchResultsModel.js
UserModel.js services/ CartService.js UserService.js ProductService.js
Nice! Objects can now be located easily by browsing the file tree or
using IDE shortcuts, changesets in source control now clearly indicate
what was modified, etc. This is a major improvement but still suffers
from some limitations.
Imagine you're at the office and realize you need a few outfits
dry-cleaned for a business trip tomorrow morning. You call home and
ask your significant other to take your black charcoal and blue
pinstripe suits to the cleaners. And don't forget the grey shirt with
the black paisley tie and the white shirt with the solid yellow tie.
Imagine that your significant other is completely unfamiliar with the
your dresser and wardrobe. As they sift through your tie drawer they
see three yellow ties. Which one to pick?
Wouldn't it be nice if your clothing was organized by outfit? While
there are practical constraints like cost and space that make this
difficult with clothing in the real world, something similar can be
done with code at zero cost.
Modularity
Hopefully the trite metaphors haven't been too tedious but here's the
recap:
Your significant other is the new developer on the team who's been
asked to fix a bug on one of the many screens in your app. The
developer sifts through the directory structure and sees all the
controllers, models and services neatly organized. Unfortunately it
tells him/her nothing about which objects are related or have
dependencies on one another. If at some point the developer wants to
reuse some of the code, they need to collect files from a bunch of
different folders and will invariably forget code from another folder
somewhere else. Believe it or not, you rarely have a need to reuse all
of the controllers from the e-commerce app in the new reporting app
you're building. You may however have a need to reuse some of the
authentication logic. Wouldn't it be nice if that was all in one
place? Let's reorganize the app based on functional areas:
cart/ CartModel.js CartService.js common/ directives.js filters.js
product/ search/ SearchResultsController.js SearchResultsModel.js
ProductDetailController.js ProductModel.js ProductService.js user/
LoginController.js RegistrationController.js UserModel.js
UserService.js Any random developer can now open the top-level folder
and immediately gain insight into what the application does. Objects
in the same folder have a relationship and some will have dependencies
on others. Understanding how the login and registration process work
is as easy as browsing the files in that folder. Primitive reuse via
copy/paste can at least be accomplished by copying the folder into
another project.
With AngularJS we can take this a step further and create a module of
this related code:
1 2 3 4 5 6 7 8 9 10 11 12 13 var userModule =
angular.module('userModule',[]); userModule.factory('userService',
['$http', function($http) { return new UserService($http); }]);
userModule.factory('userModel', ['userService', function(userService)
{ return new UserModel(userService); }]);
userModule.controller('loginController', ['$scope', 'userModel',
LoginController]); userModule.controller('registrationController',
['$scope', 'userModel', RegistrationController]); view
rawUserModule.js hosted with ❤ by GitHub If we then place
UserModule.js into the user folder it becomes a "manifest" of the
objects used in that module. This would also be a reasonable place to
add some loader directives for RequireJS or Browserify.
Tips for Common Code
Every application has common code that is used by many modules. We
just need a place for it which can be a folder named "common" or
"shared" or whatever you like. In really big applications there tends
to be a lot of overlap of functionality and cross-cutting concerns.
This can be made manageable through a few techniques:
If your module's objects require direct access to several "common"
objects, write one or more Facades for them. This can help reduce the
number of collaborators for each object since having too many
collaborators is typically a code smell. If your "common" module
becomes large subdivide it into submodules that address a particular
functional area or concern. Ensure your application modules use only
the "common" modules they need. This is a variant of the "Interface
segregation principle" from SOLID. Add utility methods onto $rootScope
so they can be used by child scopes. This can help prevent having to
wire the same dependency (such as "PermissionsModel") into every
controller in the application. Note that this should be done sparingly
to avoid cluttering up the global scope and making dependencies
non-obvious. Use events to decouple two components that don't require
an explicit reference to one another. AngularJS makes this possible
via the $emit, $broadcast and $on methods on the Scope object. A
controller can fire an event to perform some action and then receive a
notification that the action completed. Quick Note on Assets and Tests
I think there's more room for flexibility with respect to organizing
HTML, CSS and images. Placing them in an "assets" subfolder of the
module probably strikes the best balance between encapsulating the
module's asset dependencies and not cluttering things up too much.
However I think a separate top-level folder for this content which
contains a folder structure that mirrors the app's package structure
is reasonable too. I think it works well for tests as well.
Please have a look at the below link,
https://blog.safaribooksonline.com/2014/03/27/13-step-guide-angularjs-modularization/
Related
Angular 2: What is the "official" standard folder structure?
So I've been looking around to see what the most popular / standard folder structure is for Angular 2 apps and it doesn't seem like there is one. Is there anyone who is using in Angular 2 in production who can shed some light? Here are some approaches I found: 1) Split by feature, with 1) a shared folder 2) a folder for each feature that contains all the files (whether component, or service, or whatever) directly inside that folder https://angular.io/docs/ts/latest/guide/style-guide.html#!#application-structure 2) Angular 1 style (no nesting or separation by features, just components, pipes, services, models) For #1 would it feels weird not having a subfolder for components, subfolder for services, etc. Where would I put a service being used across all the routes? BTW I'm using the Angular CLI generator: https://github.com/angular/angular-cli
The style guide provides lots of does and don'ts about how to structure your app https://angular.io/styleguide It says to maintain a flat hierarchy with a folder per feature and related files (component, template, style, ...) in the same folder.
I think that it depends of how you like to organise your app. If the app is small I like to separate them by type (components, services, views, etc) but if it's a big and complex application then I use to divide it by functionalities because it's easier to find the folder you are looking for. Another alternative would be a combination of both, divide the app by type (components, services, etc) and then inside each type divide it by similarity (all the components related to users inside the folder components/users/usercomponent1, usercomponent2, etc)
Ember-cli : define routes outside of the app/routes/ folder
I am currently writing a big Ember.js application. I know Ember.js is quite monolithic but I wanted to drift a bit from this and create modules that I would plug in my application. I have no problem with component-only modules or those kind of things. My big issue is to import new routes in my Ember-cli application. Usually I would have my App.Router and I could create App.xxxRoute whether I define the route in app/routes/my-route.js or in lib/myModule/routes/my-route.js. With the Ember-cli ES6 Module syntax, the routes taken into account are only the ones from the app/routes folder and as there is no global scope anymore, I can't attach the routes coming from my module to my main application. This is a bit of a pain. I have tried a lot of things, ranging from trying to add my routes to the Ember.Router.router.recognizer manually (does not work) to creating the routes files in app/routes and exporting the ones from my modules for each of one of them (but it creates a lot of useless files). The easiest solution would be to be able to add a directory to the ember-cli path loader or whatever it's called but I'm open to any suggestion. Thanks a lot.
The approach that I would take is to build an add-on, as mentioned in the comments. And maybe, depending on your needs, add some initializers that inject objects and anything you like to all your routes or controllers in your app. See: Dependency Injection & Service Lookup For an example of an add-on that uses initializers you can check Ember Simple Auth
Does it make sense to use Require.js with Angular.js? [closed]
Closed. This question is opinion-based. It is not currently accepting answers. Want to improve this question? Update the question so it can be answered with facts and citations by editing this post. Closed 8 years ago. Improve this question I'm a newbie to Angular.js and trying to understand how it's different from Backbone.js... We used to manage our packages dependencies with Require.js while using Backbone. Does it make sense to do the same with Angular.js?
Yes it makes sense to use angular.js along with require.js wherein you can use require.js for modularizing components. There is a seed project which uses both angular.js and require.js.
To restate what I think the OP's question really is: If I'm building an application principally in Angular 1.x, and (implicitly) doing so in the era of Grunt/Gulp/Broccoli and Bower/NPM, and I maybe have a couple additional library dependencies, does Require add clear, specific value beyond what I get by using Angular without Require? Or, put another way: "Does vanilla Angular need Require to manage basic Angular component-loading effectively, if I have other ways of handling basic script-loading?" And I believe the basic answer to that is: "not unless you've got something else going on, and/or you're unable to use newer, more modern tools." Let's be clear at the outset: RequireJS is a great tool that solved some very important problems, and started us down the road that we're on, toward more scalable, more professional Javascript applications. Importantly, it was the first time many people encountered the concept of modularization and of getting things out of global scope. So, if you're going to build a Javascript application that needs to scale, then Require and the AMD pattern are not bad tools for doing that. But, is there anything particular about Angular that makes Require/AMD a particularly good fit? No. In fact, Angular provides you with its own modularization and encapsulation pattern, which in many ways renders redundant the basic modularization features of AMD. And, integrating Angular modules into the AMD pattern is not impossible, but it's a bit... finicky. You'll definitely be spending time getting the two patterns to integrate nicely. For some perspective from the Angular team itself, there's this, from Brian Ford, author of the Angular Batarang and now a member of the Angular core team: I don't recommend using RequireJS with AngularJS. Although it's certainly possible, I haven't seen any instance where RequireJS was beneficial in practice. So, on the very specific question of AngularJS: Angular and Require/AMD are orthogonal, and in places overlapping. You can use them together, but there's no reason specifically related to the nature/patterns of Angular itself. But what about basic management of internal and external dependencies for scalable Javascript applications? Doesn't Require do something really critical for me there? I recommend checking out Bower and NPM, and particularly NPM. I'm not trying to start a holy war about the comparative benefits of these tools. I merely want to say: there are other ways to skin that cat, and those ways may be even better than AMD/Require. (They certainly have much more popular momentum in late-2015, particularly NPM, combined with ES6 or CommonJS modules. See related SO question.) What about lazy-loading? Note that lazy-loading and lazy-downloading are different. Angular's lazy-loading doesn't mean you're pulling them direct from the server. In a Yeoman-style application with javascript automation, you're concatenating and minifying the whole shebang together into a single file. They're present, but not executed/instantiated until needed. The speed and bandwidth improvements you get from doing this vastly, vastly outweigh any alleged improvements from lazy-downloading a particular 20-line controller. In fact, the wasted network latency and transmission overhead for that controller is going to be an order of magnitude greater than the size of the controller itself. But let's say you really do need lazy-downloading, perhaps for infrequently-used pieces of your application, such as an admin interface. That's a very legitimate case. Require can indeed do that for you. But there are also many other, potentially more flexible options that accomplish the same thing. And Angular 2.0 will apparently take care of this for us, built-in to the router. (Details.) But what about during development on my local dev boxen? How can I get all my dozens/hundreds of script files loaded without needing to attach them all to index.html manually? Have a look at the sub-generators in Yeoman's generator-angular, or at the automation patterns embodied in generator-gulp-angular, or at the standard Webpack automation for React. These provide you a clean, scalable way to either: automatically attach the files at the time that components are scaffolded, or to simply grab them all automatically if they are present in certain folders/match certain glob-patterns. You never again need to think about your own script-loading once you've got the latter options. Bottom-line? Require is a great tool, for certain things. But go with the grain whenever possible, and separate your concerns whenever possible. Let Angular worry about Angular's own modularization pattern, and consider using ES6 modules or CommonJS as a general modularization pattern. Let modern automation tools worry about script-loading and dependency-management. And take care of async lazy-loading in a granular way, rather than by tangling it up with the other two concerns. That said, if you're developing Angular apps but can't install Node on your machine to use Javascript automation tools for some reason, then Require may be a good alternate solution. And I've seen really elaborate setups where people want to dynamically load Angular components that each declare their own dependencies or something. And while I'd probably try to solve that problem another way, I can see the merits of the idea, for that very particular situation. But otherwise... when starting from scratch with a new Angular application and flexibility to create a modern automation environment... you've got a lot of other, more flexible, more modern options. (Updated repeatedly to keep up with the evolving JS scene.)
Yes, it makes sense. Angular modules don't try to solve the problem of script load ordering or lazy script fetching. These goals are orthogonal and both module systems can live side by side and fulfil their goals. Source: Angular JS official website
This I believe is a subjective question, so I will provide my subjective opinion. Angular has a modularization mechanism built in. When you create your app, the first thing you would do is var app = angular.module("myApp"); and then app.directive(...); app.controller(...); app.service(...); If you have a look at the angular-seed which is neat starter app for angular, they have separated out the directives, services, controllers etc into different modules and then loaded those modules as dependancies on your main app. Something like : var app = angular.module("myApp",["Directives","Controllers","Services"]; Angular also lazy loads these modules ( into memory) not their script files. In terms of lazy loading script files, to be frank unless you are writing something extremely large it would be an overkill because angular by its very nature reduces the amount of code you write. A typical app written in most other frameworks could expect a reduction in around 30-50% in LOC if written in angular.
Using RequireJS with AngularJS makes sense but only if you understand how each of them works regarding dependency injection, as although both of them injects dependencies, they inject very different things. AngularJS has its own dependency system that let you inject AngularJS modules to a newly created module in order to reuse implementations. Let's say you created a "first" module that implements an AngularJS filter "greet": angular .module('first', []) .filter('greet', function() { return function(name) { return 'Hello, ' + name + '!'; } }); And now let's say you want to use the "greet" filter in another module called "second" that implements a "goodbye" filter. You may do that injecting the "first" module to the "second" module: angular .module('second', ['first']) .filter('goodbye', function() { return function(name) { return 'Good bye, ' + name + '!'; } }); The thing is that in order to make this work correctly without RequireJS, you have to make sure that the "first" AngularJS module is loaded on the page before you create the "second" AngularJS module. Quoting documentation: Depending on a module implies that required module needs to be loaded before the requiring module is loaded. In that sense, here is where RequireJS can help you as RequireJS provides a clean way to inject scripts to the page helping you organize script dependencies between each other. Going back to the "first" and "second" AngularJS modules, here is how you can do it using RequireJS separating the modules on different files to leverage script dependencies loading: // firstModule.js file define(['angular'], function(angular) { angular .module('first', []) .filter('greet', function() { return function(name) { return 'Hello, ' + name + '!'; } }); }); // secondModule.js file define(['angular', 'firstModule'], function(angular) { angular .module('second', ['first']) .filter('goodbye', function() { return function(name) { return 'Good bye, ' + name + '!'; } }); }); You can see that we are depending on "firstModule" file to be injected before the content of the RequireJS callback can be executed which needs "first" AngularJS module to be loaded to create "second" AngularJS module. Side note: Injecting "angular" on the "firstModule" and "secondModule" files as dependency is required in order to use AngularJS inside the RequireJS callback function and it have to be configured on RequireJS config to map "angular" to the library code. You may have AngularJS loaded to the page in a traditional manner too (script tag) although defeats RequireJS benefits. More details on having RequireJS support from AngularJS core from 2.0 version on my blog post. Based on my blog post "Making sense of RequireJS with AngularJS", here is the link.
As #ganaraj mentioned AngularJS has dependency injection at its core. When building toy seed applications with and without RequireJS, I personally found RequireJS was probably overkill for most use cases. That doesn't mean RequireJS is not useful for it's script loading capabilities and keeping your codebase clean during development. Combining the r.js optimizer (https://github.com/jrburke/r.js) with almond (https://github.com/jrburke/almond) can create a very slim script loading story. However since its dependency management features are not as important with angular at the core of your application, you can also evaluate other client side (HeadJS, LABjs, ...) or even server side (MVC4 Bundler, ...) script loading solutions for your particular application.
Yes, it does, specially for very large SPA. In some scenario, RequireJS is a must. For example, I develop PhoneGap applications using AngularJS that also uses Google Map API. Without AMD loader like RequireJS, the app would simply crash upon launch when offline as it cannot source the Google Map API scripts. An AMD loader gives me a chance to display an error message to the user. However, integration between AngularJS and RequireJS is a bit tricky. I created angularAMD to make this a less painful process: http://marcoslin.github.io/angularAMD/
Short answer is, it make sense. Recently this was discussed in ng-conf 2014. Here is the talk on this topic: http://www.youtube.com/watch?v=4yulGISBF8w
It makes sense to use requirejs with angularjs if you plan on lazy loading controllers and directives etc, while also combining multiple lazy dependencies into single script files for much faster lazy loading. RequireJS has an optimisation tool that makes the combining easy. See http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/
Yes it makes sense to use requireJS with Angular, I spent several days to test several technical solutions. I made an Angular Seed with RequireJS on Server Side. Very simple one. I use SHIM notation for no AMD module and not AMD because I think it's very difficult to deal with two different Dependency injection system. I use grunt and r.js to concatenate js files on server depends on the SHIM configuration (dependency) file. So I refer only one js file in my app. For more information go on my github Angular Seed : https://github.com/matohawk/angular-seed-requirejs
I would avoid using Require.js. Apps I've seen that do this wind up a mess of multiple types of module pattern architecture. AMD, Revealing, different flavors of IIFE, etc. There are other ways to load on demand like the loadOnDemand Angular mod. Adding other stuff just fills your code full of cruft and creates a low signal to noise ratio and makes your code hard to read.
Here is the approach I use: http://thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-very-large-applications/ The page shows a possible implementation of AngularJS + RequireJS, where the code is split by features and then component type.
Answer from Brian Ford AngularJS has it's own module system an typically doesn't need something like RJS. Reference: https://github.com/yeoman/generator-angular/issues/40
I think that it depends on your project complexity since angular is pretty much modularized. Your controllers can be mapped and you can just import those JavaScript classes in your index.html page. But in case your project get bigger. Or you anticipates such scenario, you should integrate angular with requirejs. In this article you can see a demo app for such integration.
Backbone-RequireJs boilerplate for component based large web-projects
We have a large web project, where we need components which can talk to each other which can be put in a central repository of components for different projects. Using reuirejs and Backbone for the modular development. Went through different boilerplate available for backbone and requirejs, but none matched my requirement. So I have created following directory structure. It can be explained as follows. ---resources |---custom-components |---mycomponent |---js |---views |---models |---collections |---css |---templates |---mycomponent.js |---mycomponent2 |---js |---views |---models |---collections |---css |---templates |---mycomponent2.js |---libraries |---backbone |---underscore |---jquery |---jquery-ui |---jqueryplugins |---jcarouselite |---thirdpartyplugins |---page-js |---mypage.js |---mypage2.js resources directory will contain all the resources. Under that we will have 4 directories as mentioned. libraries, jqueryplugins and thirdpartyplugins are obviusly the directories for the name they say. page-js directory will contain the actual main-js which will be used inside our html file as requirejs data-main attribute. Custom-component is where all widgets created by us will reside, as you can see it has a js file with same name as that of the component, which will be entry point of this widget. This directory also has directories for js, css and templates. CSS and templates will be loaded by text plugin and CSS plugin respectively. Js directory will contain all the backbone code to make this widget work. Custom components will be asked by main-js residing in page-js. Coming to what I need. 1. I want experts to have review this directory structure in perspective of large web projects, where you will need to share your widgets with other teams. suggestions are welcome. 2. My each custom-component will define a module, which will have dependencies within package structure as well as outside package structure. I want to know, if there is any way to use r.js to optimize only my custom widget dependency within package structure and let the plugins and libraries optimized separately. 3. I am developing single page ajax application, so I will be asking modules on demand so I need to cleanup modules and widgets when I dont need them, is there any way for cleaning up I should be aware of?
About the directory structure As a directory structure pattern, I highly recommend using directory structure of cakePHP. it's really robust as in words!! I'm running multiple apps (one of them is as big as Groupon) and it works just like a charm. You may need to tweak it a little because, you know, cake is a PHP framework and yours is a javascript one. Here is the cake's awesome MVC directory structure: Please note that you may host thousands of apps on a single cake installation. so if you're interested, what are you waiting for? go to their site and read their docs. About the cleaning up techniques Well, here is one of the downsides of the Javascript which I don't like. there is no real way to destroy a OO module like in Java or C++. here we don't have such things like C++'s ~ destructors. For many years, programmers use module = null to free up memory from un-used codes. Take a look at these also: Can dynamically loaded JavaScript be unloaded? Loading/unloading Javascript dynamically How to unload a javascript from an html? Hope it helps and good luck on designing your app ;D
Probably I'm late in answering this, but anyway let me share my views here, incase someone else finds it useful. Your directory structure looks alright. It is always a better design to keep your business components self contained in to a particular directory. I will not recommend Cake MVC structure which break the Open Close Principle. Also have a look at the directory structure recommended by http://boilerplatejs.org which is a reference architecture for large scale JavaScript development. I do not get the question very clear. when r.js is run it will optimize all JS files it find in the directory (exclude possible) and then create a single script by going though the dependency tree. In production you only need that single script (plus locale files if i18n plugin is used) Read my blog post below. It might give you some hints: http://blog.hasith.net/2012/11/how-much-multi-page-single-page.html
What's the recommended way to organise big sproutcore projects?
I'm just taking a look at Sproutcore (gem version 1.6.0.1) to see what I can do with it.. so excuses for the beginner questions... I've gone through the tutorial and looked at the doc mini-site. I'm wondering how I should organise my source code files. After building the really simple todo app I've already got one messy monolithic javascript file that contains a model, some views, some view controllers, etc.. i can't picture this scaling well. I've noticed that if I add another js file it is automatically inserted into the project when I load the app in a browser but I'm second-guessing what order those files go in - alphabetically my file (test.js) should have been included before todos.js but it wasn't. What's the recommended approach to organise a larger scale app; are there some guidelines for this? Couldn't see anything on the sproutcore website, strangely enough.. What if I want to share models between apps, is that possible too ? Thanks
The helper tools should arrange the files for you. Granted, you might not use them. Here is the folder structure I have from a project I did a while ago So under the root project directory, there is an apps dir, a frameworks dir, and a Buildfile and README (the other stuff you see is not necessary for sproutcore). In the apps dir, you see the main app (sudoku in this case) directory. Under it, you see, directories that directly relate to the objects you are going to create -- datasources, controllers, models, views, states, etc....If you put more than one app in the apps dir, you can access both from localhost:4020/, i.e. localhost:4020/app1 vs localhost:4020/app2 I didn't expand the frameworks dir, but in it are all the frameworks the project uses. So if you want to modify sproutcore, you can put the version you use in frameworks, and the build tools will use that version. It is a good idea to make your model layer its own framework, so you can use it with other projects if you want. You model framework should be completely decoupled from the rest of the app; it should expose an API that any client app will use. You can further create other directories under these directories at your discretion. For example, if you have a complicated application around a Person model, you can create person directories under models, views, controllers, etc, and then put your code in their. Note that if you have a PersonController object, the file name would be person.js according to convention, but that's up to you.