Related
All, I am working on a highly interactive web application which will need a lot of jquery or js code, And I'm finding that my code is becoming a little hard to maintain and is not all that readable. Sometimes even the author can't find the specified code.
So far what I had done for the clear code is below.
One js component in one js file .(for example. CustomTab.js is a tab component in my app.)
Using the templete to generate component HTML based on JSON.
Using Jquery UI.
Unobtrusive JavaScript.
Is there any other points I need pay attention? Anyway, Any suggestion or recommend technique for making js library/framework easy to miantanance is appeciated, thanks.
I could suggest you to use module pattern together with RequireJS to organize your JavaScript code. For the production you'll be able to use RequireJS optimizer to build your modules into one JavaScript file.
Also if you're expecting that your client-side application will be huge, consider to use some JavaScript MVC framework like Backbone.js together with the server-side RESTful service.
I use this namespacing pattern for my libraries:
MyLibrary.ListView.js:
var MyLibrary = MyLibrary || {};
MyLibrary.ListView = {
doSomethingOnListView: function() {
...
return this;
},
doSpecialThing: function() {
...
return this;
},
init: function() {
// Additional methods to run for all pages
this.doSomethingOnListView();
return this;
}
};
Whichever page needs this:
<script type="text/javascript" src="/js/MyLibrary.ListView.js"></script>
<script type="text/javascript">
$(function() {
MyLibrary.ListView
.init()
.doSpecialThing();
});
</script>
You can even chain methods if a certain page requires an additional function.
This is exactly the same question which I ask myself each time. I think there are few ways to get easy maintaining code.
Contribute in javascript opensource projects and understand how they solved that problem. I think you can gather some unique solution from each project and common part of projects structure will answer to your question about maintenance.
Use prepared solutions like backbone, knockout, ember or angularjs if I am not mistaken angular doesn't give you structure but provide you powerful tool for creating pages with less code. Also check todomvc for ready-made solutions.
Read books and try to create some structure for your needs. It will be difficult and long but result (maybe few years later :)) will be awesome.
Currently I'm also working on a JS framework for my company. What I'm doing is I use OOP elements for JS. In other words I'm implementing similar code to C# libraries(not that similar, simulating will be the correct word). As an example in C# you use Microsoft.Window.Forms, so I can use JSOOP and use method extending and overriding to create the same scenario. But if you gone to far in your project converting your JS code to JSOOP will be time consuming.
use JSLint, this will validate your code and bring down to a readable, script engine friendly code. Though JSLint is very strict so you can use JSHint also.
using seperate file for each component is a good idea I'm doing it also.
If you like you can download the jQuery developers version and you can have a general idea how they created the framework. I learned lot of thing looking at jQuery framework!
I have two teams working on the same project , both are using template engines ( Client and Server Side Engines ) with the same notations "{{X}}" but with different contexts .
now what I want to do is to change the Handlebars notations from {{ }} into something else for example <% %>
I want to use this notation for example :
<div><%X%></div>
instead of :
<div>{{X}}</div>
some edits needs to be done on the Handlebars.js , but I can't find it.
how can I do that ?
knowing that I can do it with Mustache by changing the line
exports.tags = ["{{", "}}"];
to
exports.tags = ["<%", "%>"];
You should really think twice before proceeding with this approach. Modifying Handlebars.js and adding customized features is going to introduce several management issues that could possibly present a much higher cost at a later stages of the project. Consider these points:
If you modify the current version, it will be either very hard or time-consuming to keep up with future updates of the tool.
Current documentation and tutorials about the tool becomes obsolete or hard to follow.
Any new developers added to the project will need to adjust to the changes and try to understand the new features of the tool.
Given these points, I would suggest to follow the standards and best-practices provided by each third party tool.
Hope this helps, and good luck!
Handlebars is defined with a formal grammar. You need to change https://github.com/wycats/handlebars.js/blob/master/src/handlebars.l
I have some experience with JavaScript - but mainly with some small stuff, I never did anything really big in Javascript previously.
Right now, however, I'm doing quite a large javascript-related project, a jquery-powered frontend that communicates with the server-side backend by sending/receiving JSON via Ajax.
I'm wondering if you could provide some useful information on how to deal with large javascript projects - are there any helpful tools/libaries/good practices?
Thanks in advance.
My one big tip would modularize
In JavaScript, it is very easy for variables to clobber other variables. In order to avoid this, modularization is a must. There are several ways to take advantage of JavaScripts scope rules to minimize the possibility of variable conflicts.
var myProject = {};
myProject.form = function(p_name, p_method, p_action)
{
var name = p_name,
method = p_method,
action = p_action;
var addInput = function(p_input)
{
// etc...
}
return {
addInput: addInput,
name: name
};
}
myProject.input = function(p_name, p_type, p_value)
{
var name, method, value;
var setValue = function(p_value)
{
value = p_value;
return true;
}
return {
setValue: setValue,
name: name
};
}
// etc...
If you're careful about using var, and keep track of your function scope, then you have only one global variable - myProject.
In order to get a new form Object, you'd simply do the following: var myForm = myProject.form('form1', 'post', 'post.php').
You may want to check out Backbone.js
Backbone supplies structure to
JavaScript-heavy applications by
providing models with key-value
binding and custom events, collections
with a rich API of enumerable
functions, views with declarative
event handling, and connects it all to
your existing application over a
RESTful JSON interface.
Grigory ,
Even i moved from a backend to UI few months back only follow this approach
read all the concepts of jquery
either from google or through some
book or through jquery
documentation.
follow some of the jquery best practices http://psdcollector.blogspot.com/2010/03/77-best-jquery-tips-i-have-ever-read.html
write utitlity functions for all repeated code like getcookie ,subsstrings etc etc
keep getting your code reviewed by experienced person who can guide you
post to stackoverflow if you get stuck anywhere.
as it is big project divide into mutiple files and use proper naming convintion.
please let me know if you need anything else
jQuery and YUI 3: A Tale of Two JavaScript Libraries is a nice comparison of them in the context of a complex application, and gives useful hints for jQuery programmers as well.
The best advice is to keep your code segmented in different files as "classes". I personally hate working in a file that's more than a few hundred lines long.
Then assemble and minify your code with one of the tools on the web, like Shrinksafe or Google Closure Compiler
Note that Dojo, YUI, and Ext are all designed to handle large Ajax applications. You'll struggle a bit with jQuery. But I'm guessing this app isn't all that big and you should be fine.
Have you consider checking out MooTools?
MooTools is a compact, modular, Object-Oriented JavaScript framework designed for the intermediate to advanced JavaScript developer. It allows you to write powerful, flexible, and cross-browser code with its elegant, well documented, and coherent API.
I've been arguing for some time against embedding server-side tags in JavaScript code, but was put on the spot today by a developer who seemed unconvinced
The code in question was a legacy ASP application, although this is largely unimportant as it could equally apply to ASP.NET or PHP (for example).
The example in question revolved around the use of a constant that they had defined in ServerSide code.
'VB
Const MY_CONST: MY_CONST = 1
If sMyVbVar = MY_CONST Then
'Do Something
End If
//JavaScript
if (sMyJsVar === "<%= MY_CONST%>"){
//DoSomething
}
My standard arguments against this are:
Script injection: The server-side tag could include code that can break the JavaScript code
Unit testing. Harder to isolate units of code for testing
Code Separation : We should keep web page technologies apart as much as possible.
The reason for doing this was so that the developer did not have to define the constant in two places. They reasoned that as it was a value that they controlled, that it wasn't subject to script injection. This reduced my justification for (1) to "We're trying to keep the standards simple, and defining exception cases would confuse people"
The unit testing and code separation arguments did not hold water either, as the page itself was a horrible amalgam of HTML, JavaScript, ASP.NET, CSS, XML....you name it, it was there. No code that was every going to be included in this page could possibly be unit tested.
So I found myself feeling like a bit of a pedant insisting that the code was changed, given the circumstances.
Are there any further arguments that might support my reasoning, or am I, in fact being a bit pedantic in this insistence?
Script injection: The server-side tag could include code that can break the JavaScript code
So write the code properly and make sure that values are correctly escaped when introduced into the JavaScript context. If your framework doesn't include a JavaScript "quoter" tool (hint: the JSON support is probably all you need), write one.
Unit testing. Harder to isolate units of code for testing
This is a good point, but if it's necessary for the server to drop things into the page for code to use, then it's necessary. I mean, there are times when this simply has to be done. A good way to do it is for the page to contain some sort of minimal block of data. Thus the server-munged JavaScript on the page really isn't "code" to be tested, it's just data. The real client code included from .js files can find the data and use it.
Thus, the page may contain:
<script>
(function(window) {
window['pageData'] = {
companyName: '<%= company.name %>',
// etc
};
})(this);
</script>
Now your nicely-encapsulated pure JavaScript code in ".js" files just has to check for window.pageData, and it's good to go.
Code Separation : We should keep web page technologies apart as much as possible.
Agreed, but it's simply a fact that sometimes server-side data needs to drive client-side behavior. To create hidden DOM nodes solely for the purpose of storing data and satisfying your rules is itself a pretty ugly practice.
Coding rules and aesthetics are Good Things. However, one should be pragmatic and take everything in perspective. It's important to remember that the context of such rules is not always a Perfect Divine Creation, and in the case of HTML, CSS, and JavaScript I think that fact is glaringly clear. In such an imperfect environment, hard-line rules can force you into unnecessary work and code that's actually harder to maintain.
edit — oh here's something else I just thought of; sort-of a compromise. A "trick" popularized (in part) by the jQuery gang with their "micro template" facility (apologies to the web genius who actually hit upon this first) is to use <script> tags that are sort-of "neutered":
<script id='pageData' type='text/plain'>
{
'companyName': '<%= company.name %>',
'accountType': '<%= user.primaryAccount.type %>',
// etc
}
</script>
Now the browser itself will not even execute that script - the "type" attribute isn't something it understands as being code, so it just ignores it. However, browsers do make the content of such scripts available, so your code can find the script by "id" value and then, via some safe JSON library or a native browser API if available, parse the notation and extract what it needs. The values still have to be properly quoted etc, but you're somewhat safer from XSS holes because it's being parsed as JSON and not as "live" full-blown JavaScript.
The reason for doing this was so that the developer did not have to define the constant in two places.
To me, this is a better argument than any argument you can make against it. It is the DRY principle. And it greatly enhances code maintainability.
Every style guide/rule taken to extreme leads to an anti-pattern. In this case your insistence of separation of technology breaks the DRY principle and can potentially make code harder to maintain. Even DRY itself if taken to extreme can lead to an anti-pattern: softcoding.
Code maintainability is a fine balance. Style guides are there to help maintain that balance. But you have to know when those very guides help and when they themselves become a problem.
Note that in the example you have given the code would not break syntax hilighting or parsing (even stackoverflow hilights it correctly) so the IDE argument would not work since the IDE can still parse that code correctly.
it simply gets unreadable. You have to take a closer look to divide the different languages. If JavaScript and the mixed-in language use the same variable names, things are getting even worse. This is especially hard for people that have to look at others people code.
Many IDEs have problems with syntax highlighting of heavily mixed documents, which can lead to the loss of Auto-Completion, proper Syntax Highlighting and so on.
It makes the code less re-usable. Think of a JavaScript function that does a common task, like echoing an array of things. If you separate the JavaScript-logic from the data it's iterating over, you can use the same function all over your application, and changes to this function have to be done only once. If the data it's iterating over is mixed with the JavaScript output loop you probably end up repeating the JavaScript code just because the mixed in language has an additional if-statement before each loop.
When I first started with Javascript, I usually just put whatever I needed into functions and called them when I needed them. That was then.
Now, as I am building more and more complex web applications with Javascript; taking advantage of its more responsive user interaction, I am realizing that I need to make my code more readable - not only by me, but anyone who replaces me. Besides that, I would like the reduce the moments of 'what the heck, why did I do this' when I read my own code months later (yes, I am being honest here, I do have what the heck was I thinking moments myself, although I try to avoid such cases)
A couple weeks ago, I got into Joose, and so far, it has been good, but I am wondering what the rest do to make their chunk their codes into meaningful segments and readable by the next programmer.
Besides making it readable, what are your steps in making your HTML separated from your code logic? Say you need to create dynamic table rows with data. Do you include that in your Javascript code, appending the td element to the string or do you do anything else. I am looking for real world solutions and ideas, not some theoretical ideas posed by some expert.
So, in case you didnt't understand the above, do you use OOP practices. If you don't what do you use?
For really JS-heavy applications, you should try to mimic Java.
Have as little JS in your HTML as possible (preferably - just the call to the bootstrap function)
Break the code into logical units, keep them all in separate files
Use a script to concatenate/minify the files into a single bundle which you will serve as part of your app
Use JS namespaces to avoid cluttering up the global namespace:
var myapp = {};
myapp.FirstClass = function() { ... };
myapp.FirstClass.prototype.method = function() { ... };
myapp.SecondClass = function() { ... };
Using all these techniques together will yield a very manageable project, even if you are not using any frameworks.
I use unobtrusive javascript, so, outside of the script tags I don't keep any javascript in the html.
The two are completely separated.
A javascript function will start when the DOM tree is completed, which will go through the html and add the javascript events, and whatever else needs to be changed.
In order to organize, I tend to have some javascript files that are named similar to the html pages that they use, and then for common functions I tend to group them by what they do, and pick a name that explains that.
So, for example, if I have UI functions then I may call them: myapp_ui_functions.js
I try to put the name of the application in the filename, unless there is some javascript that is common to several projects, such as strings.js.
I have (usually) one file that contains a bunch of functions and that's it. That is included in every page that uses Javascript. In the pages themselves, I'll make the calls to the functions like:
$(function() {
$("#delete").click(delete_user);
$("#new").click(new_user);
});
where delete_user() and new_user() are defined in the external file.
I too use unobtrusive Javascript, which for me means jQuery (there are other libraries that are unobtrusive).
You don't want a separate file for each page. That just means more unnecessary external HTTP requests. With one file—assuming you've cached it effectively—it'll be downloaded once and that's it (until it changes).
If I have a large amount of Javascript or the site is effectively split into multiple areas then I may split the Javascript but that's not often the case.
Also, in terms of my source code, I may have multiple JS files but I'll often end up combining them into one download for the client (to reduce HTTP requests).
More at Multiple javascript/css files: best practices? and Supercharging Javascript in PHP.
I've been rewriting a lot of my reusable code as jQuery plugins. I moved to jQuery from Prototype when I started doing ASP.NET MVC. Overtime I've migrated a lot my reusable code, or at least the ideas, from Prototype-based OO to jQuery-style plugins. Most of these are stored in their own JS files (mainly intranet apps so page load speed is pretty high anyway despite the extra requests). I suppose I could add a build step that coalesces these if I needed to.
I've also settled on a MasterPage approach that uses a ContentPlaceHolder for scripts that is right before the closing body tag. The standard jQuery/jQuery UI loads, and any other common JS goes right before the script placeholder in the MasterPage. I have tiny bit of JS at the top of the MasterPage that defines an array that holds any functions that partial views need to run on page load. These functions are run from the base document.ready() function in the MasterPage.
All of my JS is completely separate from my mark up. Some JS may exist in partial views -- these are encapsulated when the partial may be included more than once to make it specific to that instance of the view -- but generally not. Typically only included in the placeholders so that it's loaded at the bottom of the page.
Also, if you want to go OO heavy, check out mochikit: http://www.mochikit.com/
I find that developing your javascript using OO methodology is the way to go if you want it to be clean, readable and even somewhat secure. I posted the following question
Cleanest format for writing javascript objects
And got some fantastic responses on how to write my javascript code well. If you follow these basic principles you can use almost any library, such as yui, jquery and prototype, with ease.