What is exactly define(function(require){...}) in JavaScript - javascript

I understand that define is used to define a module, and function is an anonymous function, but what does the argument 'require' in the function hold?
If I write anything in define(function(require){...}), when will this be called? How to give a call to his anonymous function?
Please help, I am new to advanced JS.

This is part of the requireJs api, it's not vanilla JS.
You can see the full docs in here:
http://requirejs.org/docs/api.html#define
"require" in the above example is actually the "require" code, this pattern allows you to require a JS and, than only when loading the JS is completed, load yet another dependency, but do so in the scope of the previously required file.
At large, this pattern allows you to break your app into multiple small JS files, and load them in an async way to speed up the loading process of web pages.
Some would argue that this is all going to be less needed when SPDY and HTTP2 are going to be more widely used. In any case, this is surely promotes a better modularity in the code design.

Related

Avoiding re-evaluation and dynamically unloading objects called with `require`

i'm studying how nodejs module system works.
I've found so far this literature:
https://nodejs.org/api/modules.html
http://fredkschott.com/post/2014/06/require-and-the-module-system/
http://www.bennadel.com/blog/2169-where-does-node-js-and-require-look-for-modules.htm
It helps me to understand a few points however is still have these questions:
If i have a expensive resource (let's say database pooling connection) inside a module, how can i make sure that by requiring the module again i am not re-evaluating the resource?
How can i dynamically unload a disposable resource once i already called the 'require' on it?
It's important because i have some scenarios that demands me to make sure that i have a single instance of database pool. because of this i'm exporting modules which are able to receive parameters instead of just require the expensive resource.
Any guidance is very appreciated.
Alon Salont has written an EXCELLENT guide to understanding exports in NodeJS (which is what you're accessing when you call require()) here:
http://bites.goodeggs.com/posts/export-this/#singleton
If you study the list of options for what a module can export, you'll see that the answer to your question depends on how the module is written. When you call require, NodeJS will look for the module loaded in its cache and return it if it already had it loaded elsewhere.
That means if you choose to export a Singleton pattern, are monkey-patching, or creating global objects (I recommend only the first one in your case), only ONE shared object will be created / will exist. Singleton patterns are good for things like database connections that you want to be shared by many modules. Although some argue that "injecting" these dependencies via a parent/caller is better, this is a philosophical view not shared by all, and singletons are widely used by software developers for shared-service tasks like this.
If you export a function, typically a constructor, require() will STILL return just one shared reference to that. However, in this case, the reference is to a function, not something the function returns. require() doesn't actually CALL the function for you, it just gives you a reference to it. To do any real work here, you must now call the function, and that means each module that requires this thing will have its own instance of whatever class the module provides. This pattern is the more traditional one where a class instance is desired / is the goal. Most NPM modules fit this category, although that doesn't mean a singleton is a bad idea in your case.

Can/will AMD modules load in-between in-line script tags?

For reasons that aren't relevant to the question, my coworker needs to load a script that uses the Universal Module Definition pattern. Our environment usually has an AMD tool loaded, but for more irrelevant reasons, my coworker needs the script to define a global rather than registering a module through AMD. The approach that is currently checked in on their branch is something along the lines of this:
<script>
var backupDefine = define;
define = null;
</script>
<script src="../path/to/some/script/using/UMD.js"></script>
<script>
define = backupDefine;
backupDefine = null;
</script>
My question is: Is this a horrible idea? Is there a guarantee in the way browsers load scripts from script tags that will ensure nothing other than loading the UMD-based script will happen between undefining define and restoring define? We have a very large, very heavily async asset load primarily based around AMD modules, so what I am concerned with is an AMD module attempting to define itself in that intermittent state where define is currently not defined.
So long as UMD.js in no way modifies the scripts in the DOM, those scripts are guaranteed to execute in the order that they're authored in before any asynchronous callbacks that may have been queued before the first script executes.
I see this as a bad idea and spec breaking even if the case where define is always necessary is rare or even non-existent due to <script> load order considering your case. In an AMD environment, define, require and the like should basically be treated as first class keywords since their goal is to help you to remove globals.
Realistically, you're treading into undefined behavior as far as I can tell and writing code that is hard to maintain. You're relying on a tricky case with a spec where you have to undefine something and them immediately redefine it hoping that nothing tried to use it in the mean time. I'd say that that's "unsafe".
If you really need this to happen, I'd comment and document it heavily to make sure a future developer doesn't misunderstand what you're doing. However, I would say the better course of action is to rewrite the UMD.js file so that you export your global your own way. Rhetorically, why are you trying to use UMD if you don't want it to UMD things?
You're writing this module to support AMD through UMD but then you say that you don't want it to be used by AMD. Rewrite the file to just export to the global and avoid messing with define before you accidentally conflict with an additional library that does something tricky with define.

Is it possible to load requirejs under a different name

I know that for design reasons requirejs doesn't offer a way to load itself in noContext mode, bound to a different variable. Is it possible to do this manually somehow, or does require utilize the specific word "require" to execute its code? I know that it needs to the "require" and "requirejs" global variables to work - is it possible to change these names?
A little context: I am building Chrome extension which needs to load requireJS on a page to load a decent number of modules. However, some pages (upworthy.com and slate.com being 2 prominent examples) have critical functionality already bound to the name "require" (in the case of upworthy, they use requirebin or browserify). So I want to load requireJS without interfering with whatever native functionality is already assigned to require.
The JavaScript execution environment of content scripts are separated from the page, so you should not have any namespace collisions.
If you really need to inject the script in the page, then I strongly recommend to use r.js to generate one single JavaScript file, wrapped in an anonymous self-invoking function. Then, the require variable of your script will not conflict with the one in the page.

Asynchronous loading JavaScript functions.

I am building a framework in which I have merged all JavaScript files into one file (minify).
Example:
function A() {} function B() {}
Through minified file i want to load function asynchronous and remove from HTML when its work is done.
Example: load function A when it is required but not function B.
I have seen one framework Require.js but in that it loads JavaScript file asynchronous based on requirement.
Is there any framework which loads JavaScript functions on demand which are defined in same js file.
The downside to concatenation is you get less fine-grained control over what you are including on a given page load. The solution to this is, rather than creating one concatenated file, create layers of functionality that can be included a little more modularly. Thus you don't need all your JS on a page that may only use a few specific functions. This can actually be a win in speed as well, since having just one JS file might not take advantage of the browsers 6 concurrent connections. Moreover, once SPDY is fully adopted, one large file will actually be less performant than more smaller ones (since connections can be reused). Minification will still be important, however.
All that said, it seems you are asking for something a little difficult to pull off. When a browser loads a script, it gets parsed and executed immediately. You can't load the file then... only load part of the file. By concatenating, you are restricting yourself to that large payload.
It is possible to delay execution by wrapping a script in a block comment, then accessing it from the script node and eval()ing it... but that doesn't seem like what you are asking. It can be a useful strategy, though, if you want to preload modules without locking the UI.
That's not how javascript works. When the function's source file is loaded, the function is available in memory. Since the language is interpreted, the functions that are defined would be loaded as soon as the source file was read by the browser.
Your best bet is to use Require.js or something similar if you want to have explicit dependency chains.

dojo style developement

I'm having difficulty wrapping my head around dojo style of coding. The reason I am drawn to it is because of its class style coding. I have done AS developement and some java so it makes sense to me to be drawn to it. I have done some jquery style DOM work but I require a more framework based setup for a project I'm starting.
My question is should I be creating everything as classes with the declare and then requiring them when needed. Or could I write closure type functions with namespaces just like regular javascript modules. I'm confused.
Example I want to have a group of methods that take care of managing data. Then I want to have another collection of methods that handle special ajax calls. Would I create a class with declare for each of these groups of methods, in separate js files. Then in my app.js which is my application class where I'm handling the initialization of all my classes, would I require both those classes before dojo.ready(){}
then once the ready method is called I can start to use those classes.
Can someone set me straight here before I dojo out.
Does require make a load request for that js file and if so do you always have to use the ready method. If so is it best to require a bunch of your classes up front at the start of your application initialization.
Technically for what you're wanting to do, you could go either way - using dojo.declare or simply creating an object with function members. I'd be inclined to do the latter, since dojo.declare's elaborate inheritance considerations will be total overkill that you won't be making use of in this case, and it doesn't generally make sense to be instantiating anything when you just want to group some utility methods together.
For modules that simply group utility methods together, I'd be inclined to do something along these lines:
dojo.provide('my.utils');
my.utils = {
doSomething: function(){
/* do something... */
},
doSomethingElse: function(){
/* do something else... */
}
};
RE loading, if I'm reading you right, then yes, you have the right idea. In your web page, you would dojo.require(...) the modules your page requires (perhaps just one, if you have all your other dependencies further required within it). Then, any code in the page that expects these modules to be loaded should be within a function passed to dojo.ready. This ensures that even in cases where modules are asynchronously loaded (i.e. using the cross-domain loader), your code will still work. dojo.ready specifically waits for (1) the DOM to be ready and (2) all dojo.required modules up to that point to be loaded.
Note that within modules themselves, you do NOT need to enclose code in dojo.ready for the sake of waiting for dojo.required modules to load; this is figured out by the loader automatically. (However, if some logic in your module needs to wait for the DOM to be ready, you would still rely upon dojo.ready.)
I've written more about dojo.ready in the past; maybe it'll be a helpful read: http://kennethfranqueiro.com/2010/08/dojo-required-reading/

Categories

Resources