How to organize large JS / jQuery codebases throughout the site?

How do you organize large JS / jQuery codebases throughout your site? There are many good resources for how to organize fragments of your code, but it doesn’t cost anything to put it all together and customize every detail in place: an organization with a wide code, several pages using the same code, remaining DRY with free communication , and etc.

Below I will tell you how I deal with this. I never liked organizing my code like this because I think it is messy and can lead to maintainability / scaling problems, but I don't know anything better.

I understand that each of us has its own set of requirements and there are no turnkey solutions, but I like to hear some opinions about what I am doing wrong, WHY I am doing it wrong, and suggestions on how to write more convenient code.

What I think I'm really trying to understand:

  • How do you deal with the logic that you need to use in several places, on several pages?

  • How do you organize your page code? Is placing the names of each page in a global object a good idea? one.

  • What do you do from the very beginning do not force you to constantly reprint your organization as your application grows and grows larger? Maybe I'm at the 4th iteration writing this thing .2.

Each page receives the main application.js file. Each additional page has its own application.pagename.js. I use server-side logic to include files (first checking to see if it exists even for a page - some pages are not needed by JS) and then initialize them in order.

So my home page looks like this:

<script src="js/application.js"></script> <script src="js/application.index.js"></script> <script> MyApp.init(); MyApp.index.init(); </script> 

my url convention is / page / subpage / id /. I have about 10 pages and a whole number of subpages, each subpage requires their own logic. see the last example in this post.

Most of my code is already modulated either in jQuery UI widgets or in jQuery plugins, so I would say that 75% of the code in these files requires () “widget and initialization”.

I use requireJS to pull widgets as needed.

 // application.js var MyApp = { init: function(){ var self = this; // these widgets are available on every single page // notice the call to jquery.deparam.js - i'll use this later to init subpage logic. require(['js/widget1.js', 'js/widget2.js', 'js/widget3.js', 'js/jquery.deparam.js'], function(){ // deparam the query string. I'll use this later. self.querystring = $.deparam.querystring(); // init widgets once the document is ready $(function(){ $("#widget1").widget1(); $("#widget2").widget2(); // make these bindings available immediately as well. self.rebindable(); }); }); }, // I use jQuery UI Dialog extensively as a window manager, and each dialog is loaded // via an AJAX request. I'll call this method after each AJAX request to // rebind some key widgets. rebindable: function(){ $("#widget3").widget3(); } }; // application.index.js // home page specific stuff. this file is only included on the home page. MyApp.index = { // my convention is that init is automatically called after the script // is included in a page, outside of a doc.ready statement. init: function(){ var self = this; require(['js/widget4.js'], function(){ $(function(){ self.widget4( $("#foo") ); }); }); }, // passing elements to each method allows me to call this init code // outside of the index page. I can require() this file, and only init // widget4, and even use a different element. widget4: function( element ){ var config = { something: "custom to the home page" }; element.widget4( config ); } }; // application.foo.js // page "foo" stuff MyApp.foo = { init: function(){ var self = this; // this page happens to use the same widget3 and configuration present // in MyApp.index. this is where things can get sloppy and unmaintainable // really quickly. require(['js/application.index.js'], function(){ $(function(){ MyApp.index.widget3( $("#bar") ); }); }); // page "foo" has three subpages (or actions) and require // their own logic. url convention: /foo/subpage1/ // init whichever page we're on... switch( self.querystring.subpage ){ case "subpage1": self.subpage1.init(); break; case "subpage2": self.subpage2.init(); break; case "subpage3": self.subpage3.init(); break; } }, subpage1: function(){ init: function(){ var self = this; // once the DOM is ready init dialog. $(function(){ self.dialog( $("#openDialog") ); }); }, dialog: function( element ){ element.bind("click", function(){ $('<div></div>').dialog({ open: function(){ // see what i'm doing here? MyApp.rebindable(); // maybe more bindings specific to this // dialog here } }); }); } }, subpage2: function(){ init: function(){ } }, subpage3: function(){ init: function(){ } } }; 
+41
javascript jquery
Sep 08 '10 at 14:05
source share
1 answer

To help me answer your specific questions, let me talk a little bit about JavaScriptMVC :

The controller will improve your jQuery widgets, taking care of customization / separation, extensibility.

The view adds client-side templates that can be embedded in your application.

The model abstracts the service / data layer, minimizing and localizing JS changes if your server changes.

Steal performs dependency management, compression, and code cleanup. It will even take all of your scripts on all of your pages, identify common dependencies, and combine scripts into optimal payloads.

FuncUnit makes testing your applications as easy as possible.

DocumentJS ... well ... documents your code

.

Now about your specific questions:

How to work with the logic used in several places?

I use the StealJS dependency management system to upload the features I need to my page. Dependency management is absolutely essential for applications of a certain size. RequireJS is a good choice if you can easily build it.

How do you arrange page-specific code

The page code should be as small as possible. This usually involves loading dependencies and the "MainController". This master controller customizes the page to meet the functional / business requirements of this page. It is usually referred to as something like:

 App.Controllers.Main 

how to stop writing the same patterns

Well, I suggest using a framework that has stable development patterns. In addition, your modules / plugins / widgets should be as small as possible (and verifiable). This will greatly reduce the likelihood of these parts changing.

Finally....

It seems your biggest tension in the fight between:

  • general functionality
  • several pages
  • timely loading time

Therefore, choosing a solid dependency management tool is extremely critical. StealJS can help you get a very optimal load time, but you will have to deviate from the standard JavaScriptMVC directory organization due to your more pages.

RequireJS is more flexible, but you will have to upload many files. This will not only be slow, but the creation of a large number of large JS files that are not very organized will begin.

If you are happy with the download time and feel that they will not force you to compress the code into files that it does not belong to, your current solution looks like it will work.

I believe that the secret to supporting development is how easily your system / structure can isolate problems. It is important to break the application into the smallest parts. In addition, you should test these parts. People get side tracks when they think about the functionality of their pages. But for really large-scale development, you really need something that allows you to break the application into small parts, easily download these parts and somehow make the application continue to work quickly in the production process.

+12
Sep 08 '10 at 15:45
source share



All Articles