Dojo require() and AMD (1.7) - javascript

I'm having a heckuva time transitioning to Dojo and the new AMD structure, and I'm really hoping someone can shed some light on the whole concept. I've been living on Google for the last few weeks trying to find information on not the usage, but the structure and design pattern trends in using this.
I find it strange that for a relatively complex javascript application, such as for a main page where Dijits need to be created and styled, DOM elements created, etc, that I need to require, and therefore use, a TON of different modules that were otherwise available in the dojo namespace before the AMD system (or, at least, not assigned to 23 different vars).
Example:
require(['dijit/form/ValidationTextBox', 'dijit/form/SimpleTextarea', 'dijit/form/CheckBox', 'dijit/Dialog', 'dijit/form/Form'])
require(['dojo/ready', 'dojo/parser', 'dojo/dom-style', 'dijit/registry', 'dojo/dom', 'dojo/_base/connect', 'dojo/dom-construct'],
function(ready, parser, style, registry, dom, event, construct){
//...etc
}
That's only a few of the modules for one of the pages I'm working on. Surely there's a better, non-breaking-in-future-releases way of accessing these methods, etc. I mean, do I really have to import an entirely new module to use byId()? And yet another to connect events? On top of that, all the clutter being created by having to assign a variable name in the functions argument list to cling to just seems like such a backstep.
I thought maybe you would require() the module only when needed, such as the query module, but if I need it more than once, then chances are the variable it's assigned to is out of scope, and I'd need to put it in a domReady! or ready call. reaalllly....??!
Which is why I can only assume it's my lack of understanding for dojo.
I really have looked and searched and bought books (albeit, a pre-AMD one), but this library is really giving me a run for my money. I appreciate light anyone can shed on this.
Edit for Example
require(['dijit/form/ValidationTextBox'])
require(['dojo/ready', 'dojo/parser', 'dojo/dom-style', 'dijit/registry', 'dojo/dom', 'dojo/_base/connect', 'dojo/dom-construct'], function(ready, parser, style, registry, dom, event, construct){
/* perform some tasks */
var _name = new dijit.form.ValidationTextBox({
propercase : true,
tooltipPosition : ['above', 'after']
}, 'name')
/*
Let's say I want to use the query module in some places, i.e. here.
*/
require(['dojo/query', 'dojo/dom-attr'], function(query, attr){
query('#list li').forEach(function(li){
// do something with these
})
})
}
Based off of this format, which is used with many examples both from the dojo toolkit folks as well as third party sites, it would be, IMHO, absolutely ridiculous to load all the required modules as the first function(ready, parser, style, registy... would get longer and longer, and create problems with naming collisions, etc.
Firing up and require()ing all the modules I would need during the life of the script just seems silly to me. That being said, I'd have to look at some of the "package manager" scripts. But for this example, if I wanted to use the query module in select places, I would either have to load it up with the rest in the main require() statement. I understand why to an extent, but what's so bad with generic dot-syntax namespaces? dojo.whatever? dijit.findIt()? Why load module, reference in a unique name, pass through closure, blah blah?
I wish this were an easier question to ask, but I hope that makes sense.
Exasperation
Call me a newb, but this is really.. really.. driving me mad. I'm no noob when it comes to Javascript (apparently not) but wow. I cannot figure this out!
Here's what I'm gathering. In adder.js:
define('adder', function(require, exports){
exports.addTen = function(x){
return x + 10
}
})
In some master page or whatever:
require(['./js/cg/adder.js'])
...which doesn't follow the neat require(['cg/adder']) format but whatever. Not important right now.
Then, the use of adder should be:
console.log(adder.addTen(100)) // 110
The closest I got was console.log(adder) returning 3. Yep. 3. Otherwise, it's adder is not defined.
Why does this have to be so difficult? I'm using my noob card on this, cause I really have no idea why this isn't coming together.
Thanks guys.

The dependency array format:
define(["a", "b", "c"], function (a, b, c) {
});
can indeed be annoying and error-prone. Matching up the array entries to function parameters is a real pain.
I prefer the require format ("Simplified CommonJS Wrapper"):
define(function (require) {
var a = require("a");
var b = require("b");
var c = require("c");
});
This keeps your lines short and allows you to rearrange/delete/add lines without having to remember to change things in two places.
The latter format will not work on PS3 and older Opera mobile browsers, but hopefully you don't care.
As for why doing this instead of manually namespacing objects, #peller's answer gives a good overview of why modularity is a good thing, and my answer to a similar question talks about why AMD and module systems as a way of achieving modularity are a good thing.
The only thing I would add to #peller's answer is to expand on "paying attention to dependencies actually makes for much better code." If your module requires too many other modules, that's a bad sign! We have a loose rule in our 72K LOC JavaScript codebase that a module should be ~100 lines long and require between zero and four dependencies. It's served us well.

requirejs.org gives a pretty good overview of what AMD is and why you'd want to use it. Yes, Dojo is moving towards smaller modules which you would reference individually. The result is that you load less code, and your references to it are explicit. Paying attention to dependencies actually makes for much better code, I think. AMD enables optimizations, and once the migration is complete, you don't have to load everything into globals anymore. No more collisions! The require() block wraps the code which uses various modules. domReady! relates to the loading of the DOM and has nothing to do with variables being in scope.
Anyway, this is deviating from the Q&A format of SO. You might want to ask specific questions.

Related

Defining Durandal ViewModel with TypeScript

How can I do this?
Some of the examples I have seen, look horrible for example, the following, which does not read like an OO code at all, and hence what's the point of TypeScript if it's gonna be a hack. I can't exactly get intellisense on the following at all, since there's no class definition. So I have a compiled code, with no intellisense, without being able to enforce encapsulation etc - so why bother wasting time?
/// <reference path="../durandal/durandal.d.ts" />
/// <reference path="../../scripts/knockout.d.ts" />
import app = require("durandal/app");
import http = require("durandal/http");
export function activate() {
.
.
.
}
Other examples are even more funky, by exporting a variable declaration.
The resulting code is not much better, it's DI-ing this variable called exports And the code just keeps adding properties to it, which does not make sense.
If I were to write this all in javascript, I return a new object may be in JSON notation - that I can understand, a proper factory method/class. A lot less work, cleaner and no time wasted compiling.
So can someone explain what's going on?
Why is the code creating properties on a DI-ed exports object? It's like a mutant pass by reference.
Is there a more OO way of doing this? I can see myself exporting a class, but this is just too weird and goes against everything I believe to be right and just. Ok that was an exaggeration, but sure feels that way.
The resulting code is not much better, it's DI-ing this variable called exports And the code just keeps adding properties to it, which does not make sense.
This is the way web (amd) works. Its dependent on requirejs : http://requirejs.org/ and even jquery (pick any file from https://github.com/jquery/jquery/tree/master/src) uses a similar pattern e.g. : https://github.com/jquery/jquery/blob/master/src/deferred.js#L1-L5
If I were to write this all in javascript, I return a new object may be in JSON notation - that I can understand, a proper factory method/class. A lot less work, cleaner and no time wasted compiling.
You can do this with TypeScript as well by not using external modules and compiling with --out flag.
Why is the code creating properties on a DI-ed exports object? It's like a mutant pass by reference.
Is there a more OO way of doing this? I can see myself exporting a class, but this is just too weird and goes against everything I believe to be right and just. Ok that was an exaggeration, but sure feels that way.
You need to learn about External / Internal modules. In a nutshell external modules depend upon a module system (amd for the browser, provided by e.g. requirejs, commonjs for the server e.g nodejs). If you've never heard of amd/commonjs you probably shouldn't care. EXCEPT the library you are trying to use (durandal) needs you to use it. This means your javascript code would not be as simple as you think it would be.
PS: I have a video explaining typescript module systems : http://www.youtube.com/watch?hd=1&v=KDrWLMUY0R0

Are there any other ways to include JavaScript file?

We get used to include separately some javascript files with using standard <script src="file.js"></script>, but... I really don't like such a way of including.
As for the developer with the C#/C++ background, many features for me are representing as a mess.
I really don't like the way including the js files, but I understand, that it's the most regular practice.
With such kind of thoughts, I suppose to try different possible ways.
As I thought, there are two possible ways, which are able to implement the including process:
1). Create dynamically tag in imaginary function - include(), which I can define in my prototype ( class imitation in js ).
But... It's nearly the same way as the standard including, but just with some dynamic logic stored in prototypes, which may dynamically load some needed modules of web application.
And that's why I dislike it, but it's an option and I must add this to the list.
2). Dynamic load of js file via AJAX/WebSockets/SPDY, that you have wanted or even hanlding the parts of the loaded files with the partion function execution (needed some logic or implementing some design patters) with the following execution via eval() function and preparing it in the new defined function include( args ); to make the js scenario looks like:
include( "models.js" );
include( "dbController.js" );
...
Yes... I know, that eval() is an evil in JavaScript world, but I don't know the name of the different function, which allows me the same functionallity.
Also... It may be too slow compared to original way of including and I repeat even vulnerable.
These are the two ways I can imagine, maybe you will suggest a better solution or persuade me from some bad thoughts.
Require.js is a JavaScript modulisation tool that does exactly what you want. You define modules in their own file like so:
define('moduleName', [ dependencies ], function () {
// module code
});
And load them asynchronously:
require('moduleName');
Or as dependencies to other modules:
define([ 'moduleName' ], function (myModule) {
// other module
});
It also has an optimisation tool which is used to compile your modules into one JavaScript file ready for production.

Custom Lightweight JavaScript Libraries: EnderJS and MicroJS

I'm working on a custom lightweight JavaScript library that will need to run stably across the major browsers as well as across numerous independent sites without compromising or being compromised by existing libraries or namespaces. Perhaps most importantly, the library will need to be lightweight (~15k max).
UPDATE To clarify the need for such a small library: This is a third-party service that sites would pull into their page. We need to keep everything as light-weight, speedy, and self-contained as possible since we have no control over the existent libraries, speed, or page load. 15k is the target number just for the library that is accessed by the dynamic content of the service.
At this point my idea is to start with the most condensed jQuery-like base I can find, and then extend with custom modules.
Desired features:
Handle cross-browser inconsistencies like a champ (IE 6+, Chrome, FF 2+, Safari 3+).
Event handling (queuing/binding/broadcasting)
Efficient selector engine
Chaining
DOM manipulation w/ basic animations
Readily build-able and version-able from modules
I've come across EnderJS and MicroJS but I can't seem to find a lot of discussion on either. I'm more familiar and interested in Ender at this point since it seems to address all of the above features almost out of the box with "The Jeesh" weighing in at 7.5k. Tacking on a couple additional packages only pushes it to 10k in my case which would be perfect since I should only need a few k to flesh out any custom modules. It also would allow me to write and version distinct modules that can be incorporated and compressed into the main library at build-time, as well as define a unique namespace to hold it all together and hopefully protect it. Another compelling piece to the Ender library is its use of NodeJS which I would love to play around with more anyway. Having said all of that, however, I am still wide open to other ideas.
So my question is:
Does anyone have any experience with either EnderJS or MicroJS, or have another solution/approach to what I'm trying to accomplish? I realize this is not the place for "chatty, open-ended questions", and that's not my intent here. I'm just looking for suggestions on the best way to approach building a light-weight custom library without reinventing the wheel and to instead plug into the most up to date micro-libraries available.
I'm one of the co-creators of Ender and I'll +1 Fazal's words.
A note on the Jeesh, albeit a nice starter-pack to Ender, the true power lies in the ability to extend Ender with its growing set of modules. You can check them out here: https://github.com/ender-js/Ender/wiki/Ender-package-list
Somehow, one way or another Ender became the forefront of "micro library" development, but really what we're after is putting a cohesive interface onto loosely coupled modules (however large or small they are). jQuery took a great first step in abstracting its selector engine (Sizzle), but unfortunately the rest of it is interdependent (dom, events, animation, ajax, utils, promises), thus making it impossible to pick and pull what you want.
On another aside, one of the neat things about Ender is the ability to publish modules to NPM and being able to port them into your project by name allowing you to build only what you need, when you need it
It's worth checking out the learn videos at http://enderjs.com/learn which will give you a better idea of how packages are authored, built, and consumed. You'll find that setting up Ender into your environment is extremely simple and actually quite fun to work with.
Let us (#ded or #fat) know if you have any questions and we'll be more than willing to help sort things out
I've used Ender recently, and I've had no issues with it really. There are a couple of jQuery functions that aren't available from the off, but anyone who is fairly adept at JavaScript can circumvent this. Especially given the fact that Ender has a near identical structure and way of extending as jQuery.
I've used Ender on a live site recently and funnily enough I have used a couple of scripts from microjs.com alongside my own functions file, and all the JavaScript weighed in at around 15k. It's not hard to make your entire site code weigh around that or less.
As well as building a lightweight version of Ender, for example starting with the Jeesh, you might also want to consider async loading, an example is provided by Dustin Diaz:
<script src="ender.min.js"></script>
<script>
$.require('/js/core.min.js', 'core')
$.ready('core', function () {
$(document).ready(function () {
$('<p>hello world</p>').appendTo('body')
.bind('click', function (e) {
$.require('/js/ajax.min.js', function () {
$(e.target).css('position', 'relative')
.animate({
left: 500
})
})
})
})
})
</script>
By doing this you could essentially make the original ender build even lighter, and defer some of the loading, but generally speaking, if it's light in the first place you should be ok.
You might also want to take advantage of the Google closure compiler that Ender gives you access to in order to compile your site code alongside ender.
Finally, as you're probably well aware, you can do noConflict in Ender as well, just in case they already have another library present.
As you build and configure Ender you will probably want to take advantage of ender-wallet which will give you a sort of API view, allowing you to remove libraries you might not need at all.
hotlinked screenshot:
Given this:
To clarify the need for such a small library: This is a third-party service that sites would pull into their page. We need to keep everything as light-weight, speedy, and self-contained as possible since we have no control over the existant libraries, speed, or page load. 15k is the target number just for the library that is accessed by the dynamic content of the service.
I'd recommend using demand-loaded jQuery via one of the CDNs (Google's or Microsoft's; I think Google's is used more but you'd want to test). Your code can detect whether jQuery is already loaded and use it if so (~0k), and if not add a script element dynamically that pulls it from the CDN. If the user has visited any other site using jQuery from that CDN, then the script may well come from cache (~0k). If not, granted, then you have the ~31k rather than ~15k hit, but again, quite frequently you won't have any hit, or just the hit of a "not modified" response from the CDN.
You'd want to issue a noConflict call if you did load it, in case the site uses $ for something other than jQuery. That's readily done by watching for the load event on the script element (you have to use readystatechange on IE and watch for either loaded or complete status) and then doing it when that comes through.
In today's telecomms world, the difference between a 15k download and a 31k download is trivial compared with the cost of setting up the HTTP connection in the first place.
That demand-load really is a tiny bit of code, along these lines:
function loadJQuery(cb) {
var d, s, t;
if (typeof jQuery === "function"
&& parseFloat(jQuery.fn.jquery) >= 1.5) { /* Or whatever */
window.ourjQuery = jQuery;
if (cb) {
cb();
}
return;
}
d = document;
s = d.createElement('script');
t = d.body || d.getElementsByTagName('head')[0] || d.documentElement;
s.onload = loaded;
s.onreadystatechange = handleReadyStateChange;
s.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
t.appendChild(s);
function loaded() {
if (s) {
s = undefined;
window.ourjQuery = jQuery.noConflict(true);
if (cb) {
cb();
}
}
}
function handleReadyStateChange() {
if (s && (s.readyState === "loaded" || s.readyState === "complete")) {
loaded();
}
}
}
Note the URL on the script element. That's so it's friendly to both http and https pages (details). Note also that I'm checking for a minimum jQuery version and using the more rigorous form of noConflict if we load it. Either way, by the time the callback is called, the ourjQuery symbol refers to the loaded copy with the minimum version.
Update: Addressing your comment above:
That's a good idea but unfortunately not really an option for us. I agree jQuery from Google's CDN would most likely be cached - saving load - and that we could check and extend as needed, but it doesn't seem as scalable or stable as serving it ourselves. The site could decide to overwrite some jQuery module to suit their needs or worse. What we need is a light-weight self-contained library that we have complete control over and can extend and branch as needed. The goal is that this library will be cached and versioned from our CDN.
Yes, there's a small risk of a site having modified basic jQuery functionality. A very small risk. If you're restricting yourself to the core API (not plugins and such) I frankly don't think it's worth worrying about.
But if you're worried about that, then frankly I'd just use a slightly-modified jQuery hosted on your own CDN using a different symbol than jQuery (and not using $ at all). 31k vs. 15k in today's telecomms world is a non-issue; the primary cost will be in establishing the connection in the first place. If you wanted, you could probably pare that down a bit by removing parts you don't need, although sadly the jQuery internals are a bit of a morass and selectively removing functionality may not be trivial (depending on what functionality it is).

JavaScript messy code in large projects with jquery etc?

Calling the javascript gurus out there.
Basically my question is regarding how you structure your code, both visually and for functionality for example do you wrap everything in objects using this structure:
var myapp={
binds:function(){
//put some event listeners for jquery etc...
},
otherfunc:function(){
//do some other thing
},
init:function(){
//call myapp.binds and other functions and other stuff to intialize your app.
}
};
Then finally
$(document).ready(myapp.init);
The thing is with a structure like this I think JSLint complains doesn't it? Whats the pros and cons using a structure like this or is there a generally better way to structure your code? Do you follow a certain pattern from $(document).ready(call) to putting all your event listeners and "initializing" your app, do you use separate objects for methods and variables?
I also think "visually" if you have a very large webapp this structure eventually looks very messy, but maybe it's just me I don't know, any input is appreciated thanks.
Using Inheritance Patterns to Organize Large jQuery Applications
explain in detail and with better practice by Alex
http://alexsexton.com/?p=51
its very very well explain, must see
other links
How To Manage Large jQuery Apps 5 months ago
It doesn't matter much how you structure your code as long as you follow the essentials rules of programming that your teacher thought you:
Don't write repetitive code
A function must do 1 and only 1 thing
Document your code
Some other small things but mostly the above... oh and apply lots of common sense
The only error you get from that is "implied global." You can get rid of the warning for document by using this.document instead (since window is the context). The implied global for $ will stay unless you paste in the jQuery source (then gl with all the errors in that).
I trust JSLint--a lot. On big projects I tend to make object literals as you did above but I use a module pattern for object security:
var myapp = (function () {
var secret_stuff, public_stuff;
return {
stuff: public_stuff
}
}());

JavaScript dependency management

I am currently maintaining a large number of JS files and the dependency issue is growing over my head. Right now I have each function in a separate file and I manually maintain a database to work out the dependencies between functions.
This I would like to automate. For instance if I have the function f
Array.prototype.f = function() {};
which is referenced in another function g
MyObject.g = function() {
var a = new Array();
a.f();
};
I want to be able to detect that g is referencing f.
How do I go about this? Where do I start? Do I need to actually write a compiler or can I tweak Spidermonkey for instance? Did anyone else already do this?
Any pointers to get me started is very much appreciated
Thanks
Dok
Whilst you could theoretically write a static analysis tool that detected use of globals defined in other files, such as use of MyObject, you couldn't realistically track usage of prototype extension methods.
JavaScript is a dynamically-typed language so there's no practical way for any tool to know that a, if passed out of the g function, is an Array, and so if f() is called on it there's a dependency. It only gets determined what variables hold what types at run-time, so to find out you'd need an interpreter and you've made yourself a Turing-complete problem.
Not to mention the other dynamic aspects of JavaScript that completely defy static analysis, such as fetching properties by square bracket notation, the dreaded eval, or strings in timeouts or event handler attributes.
I think it's a bit of a non-starter really. You're probably better of tracking dependencies manually, but simplifying it by grouping related functions into modules which will be your basic unit of dependency tracking. OK, you'll pull in a few more functions that you technically need, but hopefully not too much.
It's also a good idea to namespace each module, so it's very clear where each call is going, making it easy to keep the dependencies in control manually (eg. by a // uses: ThisModule, ThatModule comment at the top).
Since extensions of the built-in prototypes are trickier to keep track of, keep them down to a bare minimum. Extending eg. Array to include the ECMAScript Fifth Edition methods (like indexOf) on browsers that don't already have them is a good thing to do as a basic fixup that all scripts will use. Adding completely new arbitrary functionality to existing prototypes is questionable.
Have you tried using a dependency manager like RequireJS or LabJS? I noticed no one's mentioned them in this thread.
From http://requirejs.org/docs/start.html:
Inside of main.js, you can use require() to load any other scripts you
need to run:
require(["helper/util"], function(util) {
//This function is called when scripts/helper/util.js is loaded.
//If util.js calls define(), then this function is not fired until
//util's dependencies have loaded, and the util argument will hold
//the module value for "helper/util".
});
You can nest those dependencies as well, so helper/util can require some other files within itself.
As #bobince already suggested, doing static analysis on a JavaScript program is a close to impossible problem to crack. Google Closure compiler does it to some extent but then it also relies on external help from JSDoc comments.
I had a similar problem of finding the order in which JS files should be concatenated in a previous project, and since there were loads of JS files, manually updating the inclusion order seemed too tedious. Instead, I stuck with certain conventions of what constitutes a dependency for my purposes, and based upon that and using simple regexp :) I was able to generated the correct inclusion order.
The solution used a topological sort algorithm to generate a dependency graph which then listed the files in the order in which they should be included to satisfy all dependencies. Since each file was basically a pseudo-class using MooTools syntax, there were only 3 ways dependencies could be created for my situation.
When a class Extended some other class.
When a class Implemented some other class.
When a class instantiated an object of some other class using the new keyword.
It was a simple, and definitely a broken solution for general purpose usage but it served me well. If you're interested in the solution, you can see the code here - it's in Ruby.
If your dependencies are more complex, then perhaps you could manually list the dependencies in each JS file itself using comments and some homegrown syntax such as:
// requires: Array
// requires: view/TabPanel
// requires: view/TabBar
Then read each JS file, parse out the requires comments, and construct a dependency graph which will give you the inclusion order you need.
It would be nice to have a tool that can automatically detect those dependencies for you and choose how they are loaded. The best solutions today are a bit cruder though. I created a dependency manager for my particular needs that I want to add to the list (Pyramid Dependency Manager). It has some key features which solve some unique use cases.
Handles other files (including inserting html for views...yes, you can separate your views during development)
Combines the files for you in javascript when you are ready for release (no need to install external tools)
Has a generic include for all html pages. You only have to update one file when a dependency gets added, removed, renamed, etc
Some sample code to show how it works during development.
File: dependencyLoader.js
//Set up file dependencies
Pyramid.newDependency({
name: 'standard',
files: [
'standardResources/jquery.1.6.1.min.js'
]
});
Pyramid.newDependency({
name:'lookAndFeel',
files: [
'styles.css',
'customStyles.css',
'applyStyles.js'
]
});
Pyramid.newDependency({
name:'main',
files: [
'createNamespace.js',
'views/buttonView.view', //contains just html code for a jquery.tmpl template
'models/person.js',
'init.js'
],
dependencies: ['standard','lookAndFeel']
});
Html Files
<head>
<script src="standardResources/pyramid-1.0.1.js"></script>
<script src="dependencyLoader.js"></script>
<script type="text/javascript">
Pyramid.load('main');
</script>
</head>
It does require you to maintain a single file to manage dependencies. I am thinking about creating a program that can automatically generate the loader file for you based on includes in the header but since it handles many different types of dependencies, maintaining them in one file might actually be better.
JSAnalyse uses static code analysis to detect dependencies between javascript files:
http://jsanalyse.codeplex.com/
It also allows you to define the allowed dependencies and to ensure it during the build, for instance. Of course, it cannot detect all dependencies because javascript is dynamic interpretet language which is not type-safe, like already mentioned. But it at least makes you aware of your javascript dependency graph and helps you to keep it under control.
I have written a tool to do something like this: http://github.com/damonsmith/js-class-loader
It's most useful if you have a java webapp and you structure your JS code in the java style. If you do that, it can detect all of your code dependencies and bundle them up, with support for both runtime and parse-time dependencies.

Categories

Resources