I created a javascript application with all of the code in one file. The application has grown quite a bit and I think it's time to split it up into multiple files, but I'm having a hard time figuring out how to do this. I think the problem lies with how I have decided to build the app, which uses the following template:
var myApp = function(){ //there are several global variables that all of the modules use; var global1, global2, module1, module2; global1 = { prop1:1 }; //There are also several functions that are shared between modules function globalFunction(){ } var ModuleOne = function(){ function doSomething(){ //using the global function globalFunction(); } return{ doSomething:doSomething } }; var ModuleTwo = function(){ function doSomething(){ //module 2 also needs the global function globalFunction(); //Use the functionality in module 1 //I can refactor this part to be loosely coupled/event driven module1.doSomething(); } }; module1 = new ModuleOne(); module2 = new ModuleTwo(); };
Even if all of the modules were loosely coupled and event driven, I still don't know how I would go about splitting this into multiple files given each module's reliance on the shared functions/variables. Does anyone have suggestions?
You should put your JS code in a separate file because this makes it easier to test and develop. The question of how you serve the code is a different matter. Serving the HTML and the JS separately has the advantage that a client can cache the JS.
You can write your JS in separate files, but when it comes to deploying, it's more efficient to minify them all into a single file. For each script you load in your browser, you make a round-trip to the server, so it makes sense to minimize those.
Code splitting is the splitting of code into various bundles or components which can then be loaded on demand or in parallel. As an application grows in complexity or is maintained, CSS and JavaScripts files or bundles grow in byte size, especially as the number and size of included third-party libraries increases.
It is generally accepted, that you should concat your scripts into one file to minimize requests and speedup pageload. Something most people don't know about, is that this rule was established before 2006 and browsers changed and improved a lot since than.
Take a look at the design pattern in this article: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth - you can split your module definition across multiple files in a way that lets common properties be shared but also lets you create variables or methods that are private just to a particular file.
The basic idea is that the individual JS files add to the same module with code like this:
var MODULE = (function (my) { var privateToThisFile = "something"; // add capabilities... my.publicProperty = "something"; return my; }(MODULE || {}));
Where in each JS file if MODULE
is already defined (from another JS file) you add to it otherwise you create it. You can set it up so that it (mostly) doesn't matter what order the various files are included in.
The article details several variations, and of course you'll probably come up with your own tweaks...
not to add to the confusion, but coming from a C++ background, I've tried to construct something that resembles something like a c++ namespace in the manner described below. it works, but I'd like to know if this is an acceptable pattern for the OP ?
--------------------------------file main.js:----------------
var namespacename = function(){} namespacename.mainvalue = 5; namespacename.maintest = function() { var cm = new namespacename.game(); cm.callme(); }
--------------------------------file game.js:----------------
namespacename.gamevalue = 15; namespacename.game = function(){ this.callme = function(){ console.log( "callme" ); } } namespacename.gametest = function() { console.log( "gametest:gamevalue:" + this.gamevalue ); console.log( "gametest:mainvalue:" + this.mainvalue ); }
--------------------------------file index.html:--------------
<html> <head> <title>testbed</title> </head> <body onload="init();"> </body> <script type="text/javascript" src="main.js"></script> <script type="text/javascript" src="game.js"></script> <script type="text/javascript"> init = function() { namespacename.maintest(); namespacename.gametest(); console.log( "html main:" + namespacename.mainvalue ); console.log( "html game:" + namespacename.gamevalue ); } </script> </html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With