requireJS is giving me a headache atm. requireJS is AMD which by definition says it's asynchronous. Normally I would define a module like this.
define("some Name", ["./moduleOne"],function(moduleOne){
//this would be undefined
moduleOne.whatEver();
var aMethod = function(){
//user aModule.whatever();
}
return {
method: aMethod;
}
});
Ok, I got that I can't directly use moduelOne.whatever because it is loaded asynchronous and it's not there if the callback is being called.
First Question, is this correct?
Now if I change the module definition to this:
define("some Name", function(require, exports){
var moduleOne = require(".moduleOne");
//this is OK
moduleOne.whatEver();
var aMethod = function(){
//user aModule.whatever();
}
exports.method = aMethod;
});
I can use aModule.whatever directly. As I read from the docs, using this (commonJS) style, requires parses the function with Function.prototype.toString, sees the require statement and load the modules directly.
I am pretty sure, I am misunderstanding something here and it would be nice of someone could explain how exactly requireJS works and if the second style is really synchronous.
Thanks
You've misunderstood how it works.
In both examples you give in your question the sequence of execution is:
Something requires the module named some_Name. (I don't think RequireJS is happy with module names that have spaces so I'm assuming a module name with an underscore.)
RequireJS looks for the dependencies and the factory function for the module some_Name. The factory is the function given to define when you define the module.
a. If it happens that define("some_Name"... was called before this step, then RequireJS just gets the dependencies and factory function that was given to define.
b. If define("some_Name"... has not been executed yet, RequireJS will go to the network and attempt to fetch a file that contains the define call and execute it. By convention this will be a file with the same name as the module name + the .js extension, but this can be overridden in RequireJS' configuration.
RequireJS checks whether the dependencies are loaded. If not, then it issues require calls for each dependency that is not loaded yet.
RequireJS calls the factory function with the resolved dependencies.
Note that I did not go over all possible scenarios here. I'm sticking with the most common cases to keep things simple.
So...
Ok, I got that I can't directly use moduelOne.whatever because it is loaded asynchronous and it's not there if the callback is being called.
First Question, is this correct?
No, this is not correct. By the time moduleOne.whatEver(); executes, the module moduleOne must have been loaded already. If moduleOne is undefined this is not because of RequireJS' asynchronous nature but because there is a bug in how moduleOne is defined. For instance, if it exports the value undefined, then moduleOne will be undefined. Or you may get an undefined value for moduleOne.whatEver which will then cause an error when you try to call it, but this would be caused by, for instance, forgetting to export whatEver.
The difference between the 2nd case and the first is that the 2nd uses the CommonJS sugar syntax and this causes step 2 above to have a bit of additional processing. Before RequireJS executes the factory it parses the function (as you mentioned) and then processes the factory function as if the defined had been called like this:
define("some_Name", ['require', 'exports', './moduleOne'], function (require, exports) {
The require and exports modules are special modules defined internally by RequireJS. Note how RequireJS adds ./moduleOne at the end of the list of dependencies. Once this is done, the process is exactly the same as for the 1st case.
By the time var moduleOne = require("./moduleOne"); is executed, the module has already been loaded. So what this line does is merely return a reference to the module.
Related
Does anyone know how to use node's native "module" module (!) to load in a module manually from file as an alternative to using the normal require mechanism?
I know it's an odd request, but I need modules that declare their variables globally (to that module) and that are wrapped as new modules each time they are required, e.g.
var private;
module.exports = {
setPrivate: function (value) {private = value}
}
To elaborate, if you call require twice in separate places with the same path you get the same module back. I need to always get a new module so that when required in twice setPrivate can only affect its own variable;
Basically, I need to work out the mechanism that require() uses to create and return a module the first time it is called. Have played around with instantiating Module directly (as in https://github.com/joyent/node/blob/master/lib/module.js#L293), but no luck - the exports property is always an empty object.
Please guys no suggestions to just use a constructor... I appreciate I have an unusual use case.
You don't need to do anything so complicated.
Instead, you can simply delete it from the cache:
delete require.cache[module.id];
Consider this:
<script src='global.js'></script>
<script src='require.js'></script>
<script>
require(['modular_foo'], function() {
//do stuff
});
...and in side global.js we have, among other things:
//global.js
$.getScript("modular_bar.js");
where both modular_foo and modular_bar are anonymously defined AMD modules. Using requireJS, loading something like the above would give you our favourite error, mismatched anonymous define() modules.
It's fine enough as to why that error occurs (read up on that page if you'd like to know), but the problem is, what if you can't get out of this situation?
I'm working in an established platform which is very gradually migrating to a RJS flow, for now there's no way out of using both inline legacy scripts (some of which have AMD checks to trigger define()) and our requireJS entry-point simultaneously.
In some cases I can simply place inline AMD-compatible scripts above loading the require.js library, but that doesn't work when you need to load other things (modular_bar.js) asynchronously depending on the DOM content. I could also just comment out all AMD checks from those files loading externally to RJS but that's preventing making them incompatible with ever being loaded in a modular flow.
Anyone out there had a similar experience? How do you blend your flows to overcome these sorts of conflicts?
I do not have experience using this solution in a production environment but I spent a couple days on this question figuring out the best way to approach it.
You can use a modified RequireJS library that does not allow the anonymous define's to execute, if it is being passed through eval. Also, you can disallow any define calls by removing type check for string on name in the snippet below.
The following snippet is a modification to RequireJS that will ignore anonymous defines if being called by eval. You can find the fully modified require.js in this GitHub Gist.
The code relies on the parse-stack library. If you can't include the library before RequireJS, I suggest just concatenating it to the top of of the file.
Demo
// This is a snippet of RequireJS
// ...
define = function (name, deps, callback) {
var node, context;
// We will allow named modules to be defined by `eval`
if (!(typeof name == 'string' || name instanceof String))
{
var stack = parseStack(new Error());
// If we find any eval in the stack, do not define the module
// This is to avoid the "Mismatched anonymous define() module" error
// Caused by executing an anonymous define without requireJS
for(var i = 0; i < stack.length; i++)
{
if(stack[i].name == "eval")
{
return;
}
}
}
// ...
I am using requireJS 2.x. I found out that some tutorials (and the official docs) sometimes use
requirejs.config({ [...] });
requirejs(["module"]) ...
and sometimes
require.config({ [...] });
require(["module"]) ...
Is there any difference between those two functions (require and requirejs)? I could not find any word about that in the docs. :(
They are exactly the same.
The reason is some environments might already have a require, in which case RequireJS doesn't overwrite it and allows usage of the library through requirejs
See this commit - https://github.com/jrburke/requirejs/commit/be45948433b053921dc6a6a57bf06d04e13b3b39
Are requirejs And require the Same?
As of RequireJS 2.1.15, require and requirejs in the global space are indeed "exactly the same", as can be evidenced by this test you can perform in the console:
> require === requirejs
true
That the test returns true tells you they are the exact same function object. They are not two functions that happen to have similar or identical code. They are the same object, period.
Note, however when you execute define(['require'], function (require) { The require passed to the function is normally different from the global require.
Should You Use require or requirejs?
It depends. RequireJS is an AMD loader but it is not the only loader in town. If you want to write code that conforms 100% to the AMD spec, so that someone using your code can use whatever loader they want without having to modify your code, then you should use require at the global level, because requirejs is specific to RequireJS. Another AMD loader won't define it. The AMD spec defines require but not requirejs.
If you are loading something else that defines a global require then you have to use requirejs at the global level to avoid conflict.
Inside a module, always use define to obtain a reference to require. You should do this quite irrespective of whether there is a conflict in the global space.
OK, they may indeed be "exactly the same". Let's then focus on why you would use one versus the other...
What is unclear is what should be considered "best practice": If requirejs provides extra assurance "if some environments might already have a require", then wouldn't it be a good idea to always use the requirejs function to define a require configuration rather than the require function?
Also, what happens if the unthinkable happens and the environment in question not only already has a "require" defined but also has a "requirejs" defined? Does that mean we should have a requirejsjs too? And so on...?
They are Same
Open website which loaded require already
then open Chrome console
type require in console and press enter
type requirejs in console and press enter
you can find that they are same function with different names
I have searched high and low for documentation on this, but I just cannot find anything anywhere.
I am using Aloha and want to use their sidebar prototype to create a new side bar of my own attached to other plugin functionality.
Their sidebar.js starts off with this, but I can't for the life of me find any documentation that explains what it means.
define( [
'aloha/core',
'aloha/jquery',
'aloha/selection'
], function (Aloha, jQuery, Selection, Plugin) {
It then goes on in that wrapper to define a bunch of functions, so vars and some proptotypes- which I can just about get my head around...
What is that saying or where can I find an explanation?
I can't say for sure without seeing the entire script, but it's likely to be the define function from RequireJS, in particular the "define with dependencies" form of that function. It is used to define a "module":
A module is different from a traditional script file in that it
defines a well-scoped object that avoids polluting the global
namespace. It can explicitly list its dependencies and get a handle on
those dependencies without needing to refer to global objects, but
instead receive the dependencies as arguments to the function that
defines the module.
And the "define with dependencies" form of define is described as follows:
If the module has dependencies, the first argument should be an array
of dependency names, and the second argument should be a definition
function. The function will be called to define the module once all
dependencies have loaded. The function should return an object that
defines the module.
This is AMD pattern for writing modules which AMD stands for Asynchronous Module Definition for when you need to import modules async basically rather than something like commonJS.
define(['module1', 'module2'], function(module1, module2) {
console.log(module1.sayHi());
});
Define takes an array of dependencies and once all those are loaded in the background (async) in a non-blocking way, define calls the callback which in turn accepts arguments (in this case the dependencies).
Another thing to note is that each one of those modules also needs to be defined using "define" keyword. So for instance module1 would be defined like below :
define([], function() {
return {
sayHi: function() {
console.log('Hi Hi');
},
};
});
This way of writing modules (AMD) allows you to write with browser compatibility in mind (no require() like in nodeJS) and also you can define many formats including objects, JSON, etc while for instance commonJS needs modules to be objects.
Keep in mind, AMD has it's own downfalls. Hope this helps someone.
I've just begun to work with Require.JS and I'm a bit unclear on the appropriate cases in which it should be used, as well as the correct way to use it in those cases.
Here's how I currently have things set up with Require.JS. I have two functions, functionA() and functionB(). Both of these functions require an additional function, functionC() to work properly.
I only want to load functionC() when necessary, i.e. when functionA() or functionB() is going to be called. So I have the following files:
functionC.js
functionC(){
//do stuff
}
functionA.js
functionA(){
define(['functionC'],function(){
//functionC() is loaded because it is listed as a dependency, so we can proceed
//do some functionA() stuff
});
}
functionB.js
functionB(){
define(['functionC'],function(){
//functionC() is loaded because it is listed as a dependency, so we can proceed
//do some functionB() stuff
});
}
So, is this set up correctly? And if I end up calling both functionA() and functionB() on the same page, is extra work being done since they both load the functionC.js file? If so, is that a problem? And if so, is there a way to set it up so that they first check to see if functionC.js has been loaded yet, and only load it if it hasn't been? Finally, is this an appropriate use of Require.JS?
define() should only be used to define a module. For the above example, where a piece of code should be dynamically loaded, using require() is more appropriate:
functionA.js
functionA(){
require(['functionC'],function(functionC){
//use funcC in here to call functionC
});
}
Some notes:
require([]) is asynchronous, so if the caller of functionA is expecting a return value from that function, there will likely be errors. It is best if functionA accepts a callback that is called when functionA is done with its work.
The above code will call require() for every call to functionA; however, after the first call, there is no penalty taken to load functionC.js, it is only loaded once. The first time require() gets called, it will load functionC.js, but the rest of the time, RequireJS knows it is already loaded, so it will call the function(functionC){} function without requesting functionC.js again.
You can find details about RequireJS and JavaScript modularity here: JavaScript modularity with RequireJS (from spaghetti code to ravioli code)