RequireJS Multi Injecting - requirejs

I am building a modular single page application which consumes multiple require config files from different sources. I would like a way in my application to be able to consume a list of all modules of a specific type. something like this:
define('module-type/an-implementation',...)
define('module-type/another-implementation',...)
require('module-type/*', function(modules){
$.each(modules,function(m){ m.doStuff(); });
})
This is similar patterns dependency injectors use with multiple dependency injection (eg. https://github.com/ninject/ninject/wiki/Multi-injection)
Is there a way to do this (or something similar) with require?

RequireJS doesn't know which modules exist until something requires them. Once a module is required / depended upon RequireJS will figure out where to request the module from based on module's name and RequireJS's configuration. Once the module is loaded it can be examined / executed to find out its dependencies and handle them in turn, until all dependencies are loaded and all module bodies are executed.
In order to be able to "consume a list of all modules of a specific type" something would need to be able to find all such modules. RequireJS doesn't have any means to know which modules exist, so it alone wouldn't be enough to implement "Multi Injection".
Speculation
Some kind of module registry could be created and populated with help of the build system: e.g. a file (say module-registry.js) could be generated each time a file in the source directory is added / removed or renamed, then multi inject could be possible like:
multiRequire('module-type/*', function(modules){
$.each(modules,function(m){ m.doStuff(); });
})
which in turn would call
require(findModules(pattern), function() {
callback(Array.prototype.slice.call(arguments, 0));
});
(where multiRequire and findModules are provided by the module registry).

Related

How do the core modules in node.js work? (https://github.com/nodejs/node/blob/master/lib)

Does the node interpreter look for core modules (let's say "fs") within the node binary? If yes, are these modules packaged as js files. Are the core modules that are referenced within our code converted to c/c++ code first and then executed? For example, I see a method in the _tls_common.js (https://github.com/nodejs/node/blob/master/lib/_tls_common.js) file called "loadPKCS12" and the only place that I see this method being referenced/defined is within the "node_crypto.cc" file (https://github.com/nodejs/node/blob/master/src/node_crypto.cc). So how does node link a method in javascript with the one defined in the c/c++ file?
here is the extract from the _tls_common.js file that makes use of the "loadPKCS12" method:
if (passphrase) {
c.context.loadPKCS12(buf, toBuf(passphrase));
} else {
c.context.loadPKCS12(buf);
}
}
} else {
const buf = toBuf(options.pfx);
const passphrase = options.passphrase;
if (passphrase) {
c.context.loadPKCS12(buf, toBuf(passphrase));
} else {
c.context.loadPKCS12(buf);
There are two different (but seemingly related) questions asked here. The first one is: "How the core modules work?". Second one being "How does NodeJS let c++ code get referenced and executed in JavaScript?". Let's take them one by one.
How the core modules work?
The core modules are packaged with NodeJS binary. And, while they are packaged with the binary, they are not converted to c++ code before packaging. The internal modules are loaded into memory during bootstrap of the node process. When a program executes, lets say require('fs'), the require function simply returns the already loaded module from cache. The actual loading of the internal module obviously happens in c++ code.
How does NodeJS let c++ code get referenced in JS?
This ability comes partly from V8 engine which exposes the ability to create and manage JS constructs in C++, and partly from NodeJS / LibUV which create a wrapper on top of V8 to provide the execution environment. The documentation about such node modules can be accessed here. As the documentation states, these c++ modules can be used in JS file by requiring them, like any other ordinary JS module.
Your example for use of c++ function in JS (loadPKCS12), however, is more special case of internal c++ functionality of NodeJS. loadPKCS12 is called on a object of SecureContext imported from crypto c++ module. If you follow the link to SecureContext import in _tls_common.js above, you will see that the crypto is not loaded using require(), instead a special (global) method internalBinding is used to obtain the reference. At the last line in node_crypto.cc file, initializer for internal module crypto is registered. Following the chain of initialization, node::crypto::Initialize calls node::crypto::SecureContext::Initialize which creates a function template, assigns the appropriate prototype methods and exports it on target. Eventually these exported functionalities from C++ world are imported and used in JS-World using internalBinding.

What is the best way to configure an AMD/Require.js module before it is loaded into other modules?

Currently I am using Marionette which registers itself as an AMD module called "marionette". Before it gets loaded into other modules, I want to set some configurations on it. My only thought as of now is to do this:
// configuredMarionette.js
define(["marionette"], function(Marionette) {
// modify Marionette here
return Marionette;
});
Then, in each of my modules that need marionette, I set "configuredMarionette" as the dependency instead of "marionette" so that I get the configured version. Is there any other way around this that is cleaner?
It may be more useful if you rename 'configuredMarionette' to 'marionette' and use 'orignalMarionette' for original one.
It will be easy to use any other module which has a dependency to 'marionette' to use configured one.

RequireJS Path With JS Extension Not Resolving

I am using a library that (very selfishly, IMHO) assumes that the baseUrl will point to the company's CDN:
baseUrl: "[http protocol slash slash]cdn.wijmo.com/amd-js/"
At first I thought that I would just copy the contents of the above Url to my own folder (such as /scripts/wijmo/amd-js), but that doesn't work because the good folks at Wijmo hardcoded path references in their AMD define statements, such as this:
define(["./wijmo.widget"], function () { ... });
What the above means (if I understand things properly) is that if you have any other non-Wijmo AMD modules then you must either:
(a) place them under the amd-js path, perhaps in a sub-folder named "myScripts"
(b) use hard-coded RequireJS path references to your own AMDs, like this:
paths: {
"myAMD_1": "http://www.example.com/scripts/myScripts/myAMD_1",
"myAMD_2": "/scripts/myScripts/myAMD_2.js"
}
(a) works, but it means that the baseUrl cannot point to the Wijmo CDN because I don't have access to the Wijmo CDN site so I must move the files published under amd-js to my own server.
(b) sort of work, and here is my problem: If I use syntax myAMD_1 then all is well. But that doesn't let me test on my local development machine, which uses localhost. (I don't want to get into detecting which server I'm running on and customize the paths value... I want the path to remain the same before and after I publish to my http server.)
Now, according to the RequireJS documentation:
There may be times when you do want to reference a script directly and not conform to the "baseUrl + paths" rules for finding it. If a module ID has one of the following characteristics, the ID will not be passed through the "baseUrl + paths" configuration, and just be treated like a regular URL that is relative to the document:
* Ends in ".js".
* Starts with a "/".
* Contains an URL protocol, like "http:" or "https:".
When I try to end (terminate) my path reference with .js (as shown in AMD_2 above), RequireJS doesn't find my AMD and because it ends up looking for myAMD_2.js.js (notice the two .js suffixes). So it looks like RequireJS is no longer honoring what the docs say it employs as a path-resolution algorithm. With the .js suffix not working properly, I can't easily fix references to my own AMDs because I don't know for sure what server name or physical path structure they'll be published to--I really want to use relative paths.
Finally, I don't want to change Wijmo's AMD modules not only because they're are dozens of them, but also because I would need to re-apply my customizations each time they issue a Wijmo update.
So if my baseUrl has to point to a hard-coded Wijmo path then how can I use my own AMDs without placing them in a subfolder under the Wijmo path and without making any fixed-path or Url assumptions about where my own AMDs are published?
I can suggest a couple of approaches to consider here--both have some drawbacks, but can work.
The first approach is to provide a path for each and every Wijmo module that needs to be loaded. This will work, but you have touched on the obvious drawbacks of this approach in the description of the question: Wijmo has many modules that will need to be referenced, and maintaining the module list across updates in the future may be problematic.
If you can live with those drawbacks, here is what the RequireJS config would look like:
require.config({
paths: {
'wijmo.wijgrid': 'http://cdn.wijmo.com/amd-js/wijmo.wijgrid',
'wijmo.widget': 'http://cdn.wijmo.com/amd-js/wijmo.widget',
'wijmo.wijutil': 'http://cdn.wijmo.com/amd-js/wijmo.wijutil',
// ... List all relevant Wijmo modules here
}
});
require(['wijmo.wijgrid'], function() { /* ... */ });
The second approach is to initially configure the RequireJS baseUrl to load the Wijmo modules. Then once Wijmo modules have been loaded, re-configure RequireJS to be able to load your local app modules. The drawback of this approach is that all the Wijmo modules will need to be loaded up front, so you lose the ability to require Wijmo modules as needed within your own modules. This drawback will need to be balanced against the nastiness of listing out explicit paths for all the Wijmo modules as done in the first approach.
For example:
require.config({
baseUrl: 'http://cdn.wijmo.com/amd-js',
paths: {
// ... List minimal modules such as Jquery and Globalize as per Wijmo documentation
}
});
require(['wijmo.wijgrid'], function() {
require.config({
baseUrl: '.'
});
require(['main'], function() {
/* ... */
});
});

RequireJs asynchron loading, synchrones loading differences between requirejs and require

Good evening,
im new with requireJs and hope my questions are not stupid, its my first :).
Why the guy is using in the code above require and requirejs, whats the difference?
require(["config"], function(config){
requirejs.config(config);
require(["App", "ember"], function(App, Ember){
var app_name = config.app_name || "App";
root[app_name] = App = Ember.Application.create(App);
App.deferUntilDOMReady();
});
});
Is there a differences beetween the different code spellings?
Will the script ressources are loaded asynchon or synchron in both cases?
If i use requirejs-jquery are jquery (the $) than global or only local scope (amd scope)?
require(['script1','script2'], function() {}
require(function(require) {
require('script1');
require('script2');
}
Is it possible to have several require configs?
For example i have a bunch of nested structures like /modules/helper/example/js/example.
At the moment i have all required shims,paths inside the main.js config.
I want to place a main.js or config.js inside each helper module, which configer the required shims, pathes, etc.
Than i no longer need places all configs, pathes inside the main.
1.1
RequireJS registers TWO instances of itself in global scope - require and requirejs - really just for one reason - if one (most likely require) is overriden with another require that is different in scope or implementation, you still have requirejs - usually always a global. This separation is important when you plan to consume resources that are relative to the module you are in now.
// contents of 'a/b/c.js' module file
define(['require'], function(require){
// "local scope" require call
// resolves to 'a/b/d.js' file
require(['./d'], function(d){})
// "global scope" require call
// resolves to 'd.js' file
requirejs(['./d'], function(d){})
})
Note that asking for local require only makes sense in define calls. As define call is what establishes the "module" and it's ID. The above is equivalent to this named define:
// contents of whatever file
define('a/b/c', ['require'], function(require){
// "local scope" require call
// resolves to 'a/b/d.js' file
require(['./d'], function(d){})
// "global scope" require call
// resolves to 'd.js' file
requirejs(['./d'], function(d){})
})
The other, secret, reason why James put requirejs in there is to force you to keep using require in local scope because his build tool looks for that specific string require to find the require calls. You do this, and r.js suddenly cannot follow you dependency tree because myLocalRequire is not what r.js expects:
// contents of 'a/b/c.js' module file
define(['require'], function(myLocalRequire){
// "local scope" require call
// resolves to 'a/b/d.js' file
myLocalRequire(['./d'], function(d){})
// "global scope" require call
// resolves to 'd.js' file
require(['./d'], function(d){})
})
1.2 RequireJS does NOT do sync loading at all. The only place where you think that "it must be sync!" - the CommonJS style call like var a = require('a') it's still not. It yanks the resource out of cache. In other words, it never loads anything sync.
1.3 Don't use bundled RequireJS+jQuery. It makes an already huge jQuery more huge and interferes with browser cache. (Instead of using cached jQuery from CDN you force user to download same jQuery again - 100k of trash).
See this instead: Use jQuery as a dependency without loading jQuery with RequireJS?
2.0 Don't. separate configs is a trap. It's hell that you willingly enter once you start "building" your apps. I dare you to give me one example of a separate sane config that I cannot express as either named defines group or "packages" where main module loads relative resource.
The only thing that must be in your RequireJS config is 'baseUrl' and 2-5 globally-used 'paths' definitions. That's it.

On-demand require()

Say I create a library in ./libname which contains one main file: main.js and multiple optional library files which are occasionally used with the main object: a.js and b.js.
I create index.js file with the following:
exports.MainClass = require('main.js').MainClass; // shortcut
exports.a = require('a');
exports.b = require('b');
And now I can use the library as follows:
var lib = require('./libname');
lib.MainClass;
lib.a.Something; // Here I need the optional utility object
lib.b.SomeOtherThing;
However, that means, I load 'a.js' and 'b.js' always and not when I really need them.
Sure I can manually load the optional modules with require('./libname/a.js'), but then I lose the pretty lib.a dot-notation :)
Is there a way to implement on-demand loading with some kind of index file? Maybe, some package.json magic can play here well?
This may possible if you called the "MainClass" to dynamically load the additional modules on-demand. But I suspect this will also mean an adjustment in the api to access the module.
I am guess your motivation is to "avoid" the extra processing used by "non-required modules".
But remember Node is single threaded so the memory footprint of loading a module is not per-connection, it's per-process. Loading a module is a one-off to get it into memory.
In other words the modules are only ever loaded when you start your server not every-time someone makes a request.
I think you looking at this from client-side programming where it's advantages to load scripts when they are required to save on both processing and or http requests.
On the server the most you will be saving is few extra bites in memory.
Looks like the only way is to use getters. In short, like this:
exports = {
MainClass : require('main.js').MainClass,
get a(){ return require('./a.js'); },
get b(){ return require('./a.js'); }
}

Resources