How do you manage a big script? - javascript

I'm building a JavaScript engine. I used a simple function as a class, added subfunctions, strings... and used prototypes to add other objects...
Everything is fine. The problem now, is that I'm using one class (or main function), because I need it to be so. It's becoming huge, to the point that I can't control it any more and debugging the code is becoming as hard as hell.
I'm a C# developer, who used Visual Studio. I never come across this problem, because I have different files/classes/forms...
I wonder how developers here deal with large JavaScript files. What tools/strategies/techniques do you use to solve this issue.
Thanks

You can still create multiple objects analogous to your classes and objects in C#.
I suggest you go look at some JavaScript frameworks like YUI3 ( http://developer.yahoo.com/yui/3/ )
These provide nice mechanisms for structuring your JavaScript code and behaviours. For example YUI3 provides the Y.extend method to allow you to extend one object from another much like you do in C#. There's a whole suite of other mechanisms you can use in JavaScript that are actually a lot more powerful than what you've learnt in C#.
Go look up prototypal inheritance, and maybe watch some of the videos by Douglas Crockford on the YUI Theater ( http://developer.yahoo.com/yui/theater/ ). All really excellent stuff that'll show you how you can do this sort of thing in JavaScript without the major headache of giant scripts.
To answer you question more specifically, I use the module pattern in YUI3 to allow me to split my code up into mulitple files. It allows a mechanism where you can define modules then use them from other files, while auto-resolving the required dependancies. So you define multiple JavaScript files containing your behaviours and code defining various modules, which can then be 'used' in other files.
YUI().use('my-module', 'my-other-module', function(Y) {
Y.MyModule.doSomething();
Y.MyOtherModule.doSomethingElse();
});
'my-module' and 'my-other-module' can be defined in completely different JS files, which I then tell the YUI loader where to find, and it automatically includes them into my pages.
This is really powerful, and lets you break up your code for maximum reuse and simplicity. Lots of other developers are also putting their code up on the YUI Gallery so you can mix and match behaviours into your projects.

jQuery. It's a great tool to help you write less and better code. It's a simple JS framework/library you link to on every html page. It should be quite simple to learn, and there's a lot of support, manuals, books.

Google created GWT to solve this problem.

Related

Removing jQuery for performance reasons justified?

I am on a new project and our job is to rewrite an e-commerce website that is having performance problems on mobile devices.
We are re-writing the javascript based on a more object-oriented/modular architecture which I think is great! However my team lead said that we should remove all the jQuery calls and replace with javascript like so domElem.querySelectorAll(query) , which has better performance. I understand jQuery does some kind of caching in the background which can create memory issues.
I am a little sceptical of this, firstly because it seems like a case of 'premature optimization', that is, we should find the bottle-necks first before we re-write anything. And secondly I haven't found anything on the internet that says that jQuery has significant performance problems.
The current website does have a lot of overlapping dom branch queries which I think creates a lot of redundancy. That is there is too much querying happening, and on our new architectual approach we are restricting our object/module to fewer dom queries and more targeted dom queries which is great. This does need to be re-written.
But whether or not we use domElem.querySelector(query) or $(domElem).find(query), I can't see there as being much of a difference. Is my thinking right?
Some tests are done here (check other revisions as well). Good detailed discussion is done here over pros and cons of using jquery over javascript.
Also want to point out that jquery doesn't do any caching of selectors.
The thing we often forget because of using Javascript frameworks all the time is that jQuery is not a framework.
Obviously, if you do the exact same one-operator action using the jQuery '$' object and using a direct DOM method like getElementById, the latter will be noticeably faster as jQuery itself is written in Javascript and does a lot of background stuff.
However, nothing (except code readability) prevents you, as a developer, from combining jQuery with plain Javascript: using plain Javascript wherever possible and only using jQuery functions that provide complex functionality and take some time to write and optimize from scratch. There are a lot of those in jQuery: providing browser-independent css, serializing object and doing lots of other cool stuff.
It depends on the application but usually performance troubles are related to badly-designed algorithms, not the use of jQuery.
In any case, if your application does a lot of DOM-manipulation, it may be worthwhile to re-write it using plain Javascript and test. Keep the library, just don't use it for simple operations you can easily write without it.
If your application is heavily-reliant on jQuery functions with complex functionality, removing it is out of the question.
I myself use this combined approach: everything simple written in Javascript with jQuery functions for stuff that is difficult to implement.
Also, a good place to dig around if the app has troubles with performance is the DOM-manipulation. Those operations are very heavy compared to almost everything else in Javascript. You may be able to cut down on time by rolling several operations into one, building finished objects with one constructor, instead of creating empty ones and assigning properties one-by-one, etc.
Sorry, if the answer is a bit vague but it's difficult to be precise in this case without seeing the code and running tests.
Let me quote Uncle Bob about this discussion "Architecture is about intent, we have made it about frameworks and details"
Premature optimizations needs to be considered carefully.
They often result architectural decisions that are not easily revertible.
They introduce code optimizations that are usually specific to the problems they solve, which makes the code less abstract thus hard to
maintain, and more complicated thus prone to more bugs.
They tend to be prejudice and not objective, sometimes without any real comparison to other alternatives.
The problems they are trying to solve tends to be overestimated, to the degree of non-existent.
I'm not a big expert on Web development but if possible, you should always push this kind of decisions to the end by separation of concerns, and good abstraction.
For example over the parts that generate the java-script code you can have an abstraction of JavaScriptWriter, and use different frameworks. This way you can use JQuery at the beginning, test the system and only then replace parts you know to be inefficient.

What tools or techniques do people use to make Javascript APIs more transparent?

In all the ways I've worked with Javascript, I find that nothing ever satisfies my desire for self-documenting code. I want to be able to see the APIs of modules, functions, "struct" fields, and event payloads within my own code.
I'm curious if any IDEs or transpiled languages help people easily keep their internal API visible? For example, with many languages, often an IDE will give an expandable tree view of packages/modules/classes/functions. Javascript makes this difficult as there are so many ways to code all of these entities.
I find when writing an application in Javascript that after it reaches a certain size, I have to keep jumping between source files to remember these things. Consistent naming, clear coding style, and such good habits only go so far. In a language that has no static typing, very loose rules around function arguments, and passing functions as callbacks, JS code can be hard to scan and immediately see the higher-level structure. It's hard to separate interface from implementation, as all JS code is implementation.
In large projects with many programmers, it makes sense to enforce rules about documenting functions in comments and maybe auto-generate docs. But doing independent development, this is like a lot of manual work just to remind oneself of the architecture and internal API, and likely to be out of date most of the time. I'm not going to look up a function to remember what params it takes, see that it has no docstring comments, add them and rebuild the docs so I can go read them.
TypeScript sounds promising but seems too tied to Microsoft tools. CoffeeScript saves typing and can make for cleaner code, but I don't think it solves the problem of exposing a high-level view of the structure of an application.
WebStorm actually exposes some of what I'm looking for, but I wonder what else exists.
I'm looking for any tips, tools, techniques others use to mitigate this issue.

Managing a large codebase in Node.js

I am about to embark on a Node.js project with a fairly large codebase. I would prefer to keep my code separate from node_modules.
I would ideally like to work with namespaces and folders as I think it would be a nice way to manage things. However, assuming I have read correctly, this would mean that I would have to import any files/"classes" I require using the path to the file which would be quite messy and hard to manage.
What is the defacto method for managing a large amount/ of code for a Node.js project?
My advice is to use a static typed language, since they provide automatic functionality which helps managing large codebases. That could for example be dart, typescript or coffeescript, all being able to produce javascript.
This post explains well the benefits (especially compared to JS):
http://arstechnica.com/information-technology/2014/06/why-do-dynamic-languages-make-it-difficult-to-maintain-large-codebases/
Some of the main problems stated in the linked article:
There is no modularization system; there are no classes, interfaces,
or even namespaces. These elements are in other languages to help
organize large codebases.
The inheritance system—prototype
inheritance—is both weak and poorly understood. It is by no means
obvious how to correctly build prototypes for deep hierarchies (a
captain is a kind of pirate, a pirate is a kind of person, a person is
a kind of thing...) in out-of-the-box JavaScript.
There is no
encapsulation whatsoever; every property of every object is yielded up
to the for-in construct, and is modifiable at will by any part of the
program.
There is no way to annotate any restriction on storage; any
variable may hold any value.
If you started with JS and don't want to abandon your current code base, you could switch to typescript.
Shortly before my JS project reached 5000 lines of code (in about 15 files), I moved it to typescript. It took me about 4 hours to get it back to running.
This post gives some insights from someone movig Node.js to a typescript environment:
http://tech.kinja.com/my-experience-with-typescript-710191610

How to achieve library-agnosticism when building a javascript framework?

I've started looking into architecturing a javascript framework.
I don't want to reinvent the wheel here, especially regarding browser quirks, and know that for that matter, I'll have to rely, at some point, on some commonly-used libraries to handle low-level concerns.
The thing is, I'm not sure how i can depend on an external library for some piece of functionality (say for example dom manipulation), without tying it to my design.
Practical examples would help make a better point, but I'm not at the design stage yet, and I'm merely trying to avoid getting started on the wrong foot.
So I'm looking for some examples, guidelines, best-practices or maybe patterns that could help in this situation.
Any insight ?
EDIT : Bit of a clarification on why I'd want to do this.
My goal is to build something resembling more of an application framework than most traditional libraries like jQuery.
Think layered architecture, where the libraries would fit into the infrastructure layer (as per Evans' definition in Domain Driven Design), and handle things such as events, dom traversing and manipulation etc...
This is a very broad question, but if I were you, I would use jQuery as a base. It is a very easy library to extend and add functionality too.
I'd recommend grabbing a copy of ExtJS and taking a look at how they provide support for replacing the underlying core of their product. You can use their higher level libraries, such as grids, trees, etc, but choose to use YUI or prototype in place of their Ext core.
That should give you a good starting point.
Edit to answer comment:
Once you've downloaded ExtJS, take a look in the "adapter" folder. In there, you'll see the various adapters that exist to make ExtJS work with other libraries. You'll quickly see how they define functions that in turn make use of the appropriate underlying lib.
Segregate your code:
use the external libraries to the fullest possible, within their separate section of code.
Taking jQuery as an example, just designate a section for interfacing with jQuery and then use jQuery within that section of the library like there's no tomorrow, and give it interface functions that the rest of the code uses exclusively.
Frankly, if you integrate a library with your code and try to make it generic enough that you can trivially swap it out with something else, you're probably going to neuter the library to the point where you might as well have not included it at all.
Accept that you may need to rewrite if you end up swapping libraries, but prepare for that by giving the library-interfacing code it's own separate section, and you'll be able to write less generic, more powerful code with those external libraries and save yourself a lot of work.
This doesn't answer your pattern question, but a word about the frameworks. All of the modern JavaScript libraries are pretty good at playing well with each other, but some are better than others. Just make sure that they libraries don't monkey-patch the core objects with arbitrary properties or muck with the global namespace and you should be good to go. JQuery and YUI are both well designed and namespaced libraries. Dojo is also quite good, but a couple years ago when looking at all of the options, it seemed like Dojo encouraged the use of proprietary element attributes in markup as JS hooks. At that time Prototype was the library that mucked with objects like String/Array and didn't play well with others. I haven't looked/used Dojo or Prototype so take that with a grain of salt. I'm actively using YUI and JQuery in the same app; YUI for widgets and event management and JQuery for Selector/DOM manipulation.
I'd suggest you pick a single general purpose library or no library at all, depending on the requirements of the framework you plan to write. It's very difficult to make any kind of recommendation without more information, such as what your framework is aiming to achieve, who will be using it and in what kind of environment.
If you're considering writing a script of reasonable complexity then I would suggest learning the relevant "low level" DOM manipulation techniques for yourself. It's not as difficult as devotees of some of the famous general purpose libraries would have you believe.
Use some kind of interface to link to the library.
Don't do:
$("blah").something();
do
something("blah")
function something(id){
$(id).something();
}
Since you could call something() 20 times, it'll be simpler to update if the actual use of the library is in only 1 place.
It'll add development time and then complexity, but you won't be as dependent on a library.
I don't think this can be achieved very effortlessly. If you really want this behavior, I think you'd have to manually map the features that are covered by all libraries you want to include support for.
So that the implementation would look like:
yourLibrary.coreFramework = 'prototype';
yourLibrary.doStuff();
And your librar would treat it in the following manner:
function doStuff() {
var elem = getElement('id');
// do stuff with 'elem';
}
function getElement(id) {
switch(this.coreFramework) {
case 'prototype': return $(id);
case 'jquery': return $('#'+id);
/* etc */
}
}
Check out the jQuery or prototype frameworks.
If you decide you need to, then extend these.

What JavaScript frameworks conflict with each other?

There are times when I want to use mootools for certain things and Prototype & script.aculo.us for others but within the same site. I've even considered adding others, but was concerned about conflicts. Anyone have experience, or am I just trying to make things too complicated for myself?
If you really, really want to do this, then you will be able to without too many problems - the main libraries are designed to behave well inside their own namespaces, with a couple of notable exceptions - from Using JQuery with Other Frameworks:
The jQuery library, and virtually all of its plugins are constrained within the jQuery namespace. As a general rule, "global" objects are stored inside the jQuery namespace as well, so you shouldn't get a clash between jQuery and any other library (like Prototype, MooTools, or YUI).
That said, there is one caveat: By default, jQuery uses "$" as a shortcut for "jQuery", which you can over-ride.
So, yes, you can do it, but you'd likely be creating maintenance headaches further down the line for yourself - subtle differences between framework functions may be obvious to you today, but come back in 6 months and it can be a whole other story! So I would recommend keeping it as simple as you can, and having as few different frameworks (preferrably 1!) as you can in your codebase.
AFAIK, all the popular frameworks are designed to be combined with other frameworks. I don't think combining them is that much of a problem. I would however discourage combining them purely from a case of bandwidth needs. A slow site experience is less forgivable than a more complicated development experience.
A recent question: jQuery & Prototype Conflict
Prototype.js library used to be very offensive and conflicted with many other libraries / code. However, to my knowledge, they recently given up with some really hard-core staff, such as replacing Element object etc.
You are better off sticking with a single framework per application. Otherwise your client will spend too much time/bandwidth downloading the javascripts.
That being said, Prototype and JQuery can work together. Information is on the JQuery web site.
My suggestion is to learn one (or more!) framework(s) very well so that you will be able to replicate the features you need without adding the overhead of multiple frameworks.
remember the more code that you push to the client the slower everything becomes.
From my experience I can say that some javascript libraries rather conflict with the browser, than with each other. What I mean is the following: sometime code written against some library will not well co-exist with the code written against browser DOM.
My Framework Scanner tool is useful for finding JS/CSS conflicts between libraries:
http://mankz.com/code/GlobalCheck.htm

Categories

Resources