Can a require.js module depend on itself - javascript

We have two modules that get loaded (with 'define') by require.js:
ds.test.js
ds.js
As you might guess, the former tests the latter. The preamble to ds.test.js is as follows, with some console/logging I've added:
define(["ds", "test", "assert"], function (ds, test, assert) {
console.log(arguments);
// the rest is a 'pure' module --
// no executable code outside of a returned object/map of methods
The output from the console/logging being what I expect: [Object, Object, Object]
The preamble (with console/logging) of ds.js is as follows:
define(["ds"], function (ds) {
console.log(arguments);
// the rest is a 'pure' module
The output from the console/logging however is: [undefined]
Why would the former (ds.test.js) be able to successfully load ds, but ds.js itself cannot? This causes one of my tests to fail, as one of the methods returned by ds refers to a method within itself, i.e.: 'ds.assoc()'. Interestingly before require.js we used a home-rolled dependency manager, and the test did not fail on the same method -- ds.js was able to refer to itself.
Would this be an issue of a so-called "circular dependency"? In that ds.test.js relies on ds.js, and ds.js relies on itself. If so how might I resolve my issue?
For what it's worth, ds.test.js gets loaded first -- it gets picked up as a global var named "SUITE" by 'test.runner.js', the preamble of which is as follows:
define(["test", SUITE], function (test, suite) {
Then whatever test suite gets loaded (in this cast, ds.test.js) in turn loads the module which it is testing (e.g. "ds")
Some final context is that I've just inherited this code in the last few weeks, and what I'm doing is based on our existing conversion of another application from our home-rolled dependency manager to require.js. So I guess I'm asking that be taken into consideration before any sniping with comments such as "why are you using a global variable"; if you've got suggestions for a concrete alternative, great I look forward to it.

(Comment added as an answer by request.)
If ds refers to a method within itself, couldn't you call your example function of assoc() directly, rather than try to use ds.assoc()? (This also eliminates the perceived need for ds to load itself.)

Related

Dojo module loading in general

Coming from Java/C# I struggle to understand what that actually means for me as a developer (I'm thinking too much object-oriented).
Suppose there are two html files that use the same Dojo module via require() in a script tag like so:
<script type="text/javascript">
require(["some/module"],
function(someModule) {
...
}
);
</script>
I understand that require() loads all the given modules before calling the callback method. But, is the module loaded for each and every require() where it is defined? So in the sample above is some/module loaded once and then shared between the two HTMLs or is it loaded twice (i.e. loaded for every require where it is listed in the requirements list)?
If the module is loaded only once, can I share information between the two callbacks then? In case it is loaded twice, how can I share information between those two callbacks then?
The official documentation says "The global function define allows you to register a module with the loader. ". Does that mean that defines are something like static classes/methods?
If you load the module twice in the same window, it will only load the module once and return the same object when you request it a second time.
So, if you're having two seperate pages, then it will have two windows which will mean that it will load the module two times. If you want to share information, you will have to store it somewhere (the web is stateless), you could use a back-end service + database, or you could use the HTML5 localStorage API or the IndexedDB (for example).
If you don't want that, you can always use single page applications. This means that you will load multiple pages in one window using JavaScript (asynchronous pages).
About your last question... with define() you define modules. A module can be a simple object (which would be similar to static classes since you don't have to instantiate), but a module can also be a prototype, which means you will be able to create instances, for example:
define([], function() {
return {
"foo": function() {
console.log("bar");
}
};
});
This will return the same single object every time you need it. You can see it as a static class or a singleton. If you require it twice, then it will return the same object.
However, you could also write something like this:
define([], function() {
return function() {
this.foo = function() {
console.log("bar");
};
};
});
Which means that you're returning a prototype. Using it requires you to instantiate it, for example:
require(["my/Module"], function(Module) {
new Module().foo();
});
Prototyping is a basic feature of JavaScript, but in Dojo there's a module that does that for you, called dojo/_base/declare. You will often see things like this:
define(["dojo/_base/declare"], function(declare) {
return declare([], {
foo: function() {
console.log("bar");
}
});
});
In this case, you will have to load it similarly to a prototype (using the new keyword).
You can find a demo of all this on Plunker.
You might ask, how can you tell the difference between a singleton/static class module, and a prototypal module... well, there's a common naming convention to it. When your module starts with a capital letter (for example dijit/layout/ContentPane, dojo/dnd/Moveable, ...) then it usually means the module requires instances. When the module starts with a lowercase letter, it's a static class/singleton (for example dojo/_base/declare, dijit/registry)
1) dojo require, loads the module once and then if you called it again require() will simply return if the package is already loaded. so the request will be called once and it will also call any dependencies once.
but all that if you are in the same HTML page if you leave the page and call the same module in a different page then it will be called from the server. you can also use cache in your config settings so things will be cached in the browser and the file will or not by setting the cacheBust to true if you want a fresh copy or false if you want things to be cached.
2) if you are in the same html page and domain, the module didn't change the module will be the same and you can share values and any change you make you can get it from anywhere unless you call a new instance. but that is not possible between different html pages.
3) not it is not like a static classes or methods from what I understand static methods A static class can be used as a convenient container for sets of methods that just operate on input parameters and do not have to get or set any internal instance fields..
dojo work differently it is a reference for an object if you did it in that way :
define(function(){
var privateValue = 0;
return {
increment: function(){
privateValue++;
},
decrement: function(){
privateValue--;
},
getValue: function(){
return privateValue;
}
};
});
This means every bit of code loads that module will reference the same object in memory so the value will be the same through out the use of that module.
of course that is my understanding please feel free to tell me where I am wrong.

Stop Emscripten from creating global "Module"

Is there a way to prevent emscripten from creating window scoped global "Module"?
I generate some .js using something like emcc --bind -O3 --memory-init-file 0 whatever.... If I include the output script, window object gets flooded with various internal emscripten functions and objects.
I tried to wrap generated code like this:
Some.Namespace.Whatever = (function() { ...generated code...; return Module;})();
Everything seems to work fine, but emscripten still creates window scoped global "Module" (other internal functions are gone).
Since this commit from February 4th this year, which I believe is part of Emscripten > v1.29.9, if the code is wrapped by some method, the Module object is not exposed on the global scope.
Maybe you can use the pre and post js options to wrap the code in a self executing anonymous function? [0] So he pre js would be (function () { and post js would be })();. This could just as easily be done manually as part of a build step with Unix cat.
That or shove it in a worker. [1]
I don't think emscripten assigns window.Module or this.Module in emitted code, but I'm not a computer to check right now, maybe you could?
[0] https://github.com/kripken/emscripten/blob/1c12291bcb77fac633d9fbe08c817746c4ce24c3/site/build/text/docs/tools_reference/emcc.txt#L269-L277
[1] https://github.com/kripken/emscripten/blob/1c12291bcb77fac633d9fbe08c817746c4ce24c3/site/build/text/docs/tools_reference/emcc.txt#L468-L474

RequireJs extend module initialize begin and end

I have created a JavaScript library which can be used for logging purposes.
I also want to support the logging of requirejs.
Which functions/events of requirejs can I prototype/wrap so I can log when a module is initialized and when it is done initializing and returns the initialized object.
For instance if I call require(["obj1","obj2", "obj3"], function(obj1, obj2, obj3){}
I would like to know when requirejs begins on initializing each of the object, and I would like to know when each object is completely initialized.
I looked into the documentation/code, but could not find any usefull functions I can access from the requirejs object or the require object.
Note: I do not want to change the existing code of requirejs I wish to append functionality from the outside by either prototyping or wrapping.
What I have tried (problem is that this only accesses the begin and end of the entire batch of modules):
var oldrequire = require;
require = function (deps, callback, errback, optional) {
console.log("start");
var callbackWrapper = callback;
callbackWrapper = function () {
console.log("end");
var args = new Array();
for(var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
callback.apply(this, args);
};
oldrequire.call(this, deps, callbackWrapper, errback, optional);
};
This is a "better than nothing answer", not a definitive answer, but it might help you look in another direction. Not sure if that's good or bad, certainly it's brainstorming.
I've looked into this recently for a single particular module I had to wrap. I ended up writing a second module ("module-wrapper") for which I added a path entry with the name of the original module ("module"). I then added a second entry ("module-actual") that references the actual module which I require() as a dependency in the wrapper.
I can then add code before and after initialization, and finally return the actual module. This is transparent to user modules as well as the actual module, and very clean and straightforward from a design standpoint.
However, it is obviously not practical to create a wrapper per module manually in your case, but you might be able to generate them dynamically with some trickery. Or somehow figure out what name was used to import the (unique) wrapper module from within it so that it can in turn dynamically import the associated actual module (with an async require, which wouldn't be transparent to user code).
Of course, it would be best if requirejs provided official hooks. I've never seen such hooks in the docs, but you might want to go through them again if you're not more certain than me.

How to handle dependency cycle in commonjs

I've been working on a commonjs implementation on ExtendScript Toolkit lately and I am stuck with this "dependency cycle" thing. My code passed most of the commonjs compliance tests except on these: cyclic, determinism, exactExports, monkeys.
The wiki states that:
If there is a dependency cycle, the foreign module may not have finished executing at the time it is required by one of its transitive dependencies; in this case, the object returned by "require" must contain at least the exports that the foreign module has prepared before the call to require that led to the current module's execution.
Can somebody please explain to me further how this specification should be implemented? Do I throw an exception if it detects a dependency cycle?
You can check my code at: https://github.com/madevelopers/estk
Only tested on ExtendScript Toolkit CS6
In CommonJS, you attach the things you're exporting onto an export object. The intention of the spec is that if there is a 'require' statement part way through a file and then part way through that required file there is a require of the original file, then the second require gets the state of the exports object as it is at that point. I'll provide an example.
// file A.js
exports.A1 = {};
exports.A2 = {};
// The object returned from this require call has B1, B2 and B3
var B = require('./B.js');
exports.A3 = B.B1;
And in file B.js:
// fie B.js
exports.B1 = {};
exports.B2 = {};
// This require call causes a cycle. The object returned has only A1 and A2.
// A3 will be added to the exports object later, *after* this file is loaded.
var A = require('./A.js');
exports.B3 = A.A1;
This example would have worked correctly, even though there is a cycle in the code. Here's another example that would work even though it is circular:
var OtherModule = require('./OtherModule.js');
// even if OtherModule requires this file and causes a circular dependency
// this will work, since doAThing is only defined and not called by requiring this
// this file. By the time doAThing is called, OtherModule will have finished
// loading.
exports.doAThing = function() {
return OtherModule.doSomething() + 3;
}
Even though OtherModule.doSomething doesn't exist when this files code is executed and doAThing is defined, as long as doAThing doesn't get called until later, then everything is fine.

Javascript Modular Layout : How to call a function defined in one module from another?

Below is an example of a modular layout of a javascript application. I want to start using such a structure for my work. I am struggling to get my head round how it works and need to understand how to call a function that is defined in one module from a different module? Is this definitely the bet way to layout a JavaScript heavy application?
window.MainModule = (function($, win, doc, undefined) {
var modules = {};
// -- Create as many modules as you need ...
modules["alerter"] = (function(){
var someFunction = function(){ alert('I alert first'); };
return {
init: someFunction
};
}());
modules["alerter2"] = (function(){
var someFunction = function(){ alert('I alert second'); };
return {
init: someFunction
};
}());
return {
init: function(){
for (var key in modules){
modules[key].init();
}
}
};
}(jQuery, this, document));
$(window.MainModule.init);
Modularity with RequireJS:
module1.js
define( ["dependency"] , function( dep ){
return {
speak: function(){
alert( dep.message );
}
}
} );
dependency.js
define( {
message: "Hello world!"
} );
impl.js
if ( $(".someCssExpression").length ) {
require( [ "module1" ] , function( mod ){
mod.speak();
});
}
index.html
...
<script src="require.js" data-main="impl"></script>
...
Your file structure will be modular.
Your implementation will be modular.
And no clunky namespacing or weird constructs to make it feel organised.
Takes some getting used to, but totally worth it.
Also read:
ScriptJunkie article
In order to access anything it needs to be available in the scope from where you are calling. "Module" - or any capsulation method for that matter - in JS always means "function". A module is just an anonymous (unnamed) function. So to access an element defined in another function B(module) from inside function A it either has to be made available in GLOBAL SCOPE (in browsers: the window object), OR it must have obtained access some other way, e.g. by having received a reference through some function call. YUI3 ([http://developer.yahoo.com/yui/3/]) is an interesting example for the latter, there nothing of your application ever is available in global scope (I consider YUI3 one of the by far best JS frameworks for SERIOUS softwarfe development, also definitely DO check out http://developer.yahoo.com/yui/theater/, especially any videos from Douglas Crockford, a Javascript God (and I'm not usually given to giving these kinds of statements).
What you have to keep in mind with Javascript is that part of what in languages such as C is done by the compiler now happens at runtime. For such things like immediate function invocations that return a function (causing encapsulation through usage of closures) you should remember that that code runs exactly ONCE DURING LOADING, but during runtime completely different code is executed - which depends on what the on-load code execution did.
In your example the function after window.MainModule=... is executed on loading of the JS code. Note that window.MainModule does NOT POINT TO THAT FUNCTION!!!
Instead, that function is, as I said, executed on load, and the RESULT is assigned to window.MainModule. What is the result? Well, there is just one return statement, and it returns and object, and the object has just one property "init" which points to an anonymous function.
Before returning that object, though, that function creates a variable "modules" in its local scope, which points to an object. The object has two properties, and those properties are assigned functions the same way that window.MainModule is assigned one, so you have three closures all in all.
So after loading you have one global variable
window.MainModule = {
init: function(){...}
So after loading you have one global variable
window.MainModule = {
init: function(){...}
}
In the last line that function is executed.
}
In the last line that function is executed.
The example does not make a lot of sense though, because you don't really encapsulate anything. You make available the private function with double pointers: from init to the local variable someFunction, nothing is hidden. Check out the above URLs (Yahoo Developer Theater) for better examples and very thorough explanations. It is MUST-WATCH even if you never touch YUI3 - especially the videos from D. Crockford are general JS knowhow.
Well umm..
It all depands on what you need from your application.
I would suggest sticking to the jQuery plugins for as long as you touch the gui.
You could use the Namespace pattern like yahoo, and just forge a great framework for your
application.
You probably don't need your modules to run on every page, like you did when instantiating the main module (There is no point to it unless f.e. you have a widget in every page on your website).
After you finish to abstract all the actions you need from your javascript into function and modules, build a module that will load the logic according to each page/action/whatever whenever you need it.
By the way, You can always develop OO style using mootools and this is endless really. It all boils down to your application needs
I would really recommend you to watch some lectures of Douglas Crockford(As been stated before me) and here is a nice article about modules that may help you understand it a bit further. Good luck!

Categories

Resources