requirejs execute require module again - requirejs

f.e. i have:
require( ['module1'], function( module1_callback){
//callback_1 after code is loaded
} );
and module1.js
define( ['module2'], function(module2_callback)
{
//function_1 to perform something
return 'something';
});
i need module1 on demand but i need to run function_1 everytime i requre that module,
in this case function_1 in module1 is executed only on first load but i need that routine every time i require module1. only return callback is executed

This is not the way requirejs works. But you can return a function that will perform something and then return something:
define( ['module2'], function(module2_callback) {
return function() {
//to perform something
return 'something';
}
});
and in your base module:
require( ['module1'], function( module1_callback){
var something = module1_callback();
});

retrieving functions introduces more complexity and it is not working in some cases with backbone plugins and circular dependencies especialy on large 1page app where some parts of the page needs to be reinitialized from scratch,
i endup using magic modules
https://github.com/jrburke/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#wiki-magic
and undef
define( ['module2', 'module'], function(module2_callback) {
//push module id into global array
window.undefArr.push(module);
//all code here will be executed on every require
});
and
//before require undef modules
//here you can control which modules undef which to leave in memory
//based on module properties like path, name, status etc.
_.each( window.undefArr, function(mod){
requirejs.undef(mod.id);
});
//init undefArr
undefArr = [];
require( ['module1']);

Related

How to avoid using global functions in NodeJS?

I have a global function in my main JS file and i need to call it several times from a module. I heard it is bad because it can create a function name collision between a local (from module) and a global function name (from main js). The global function can be called 100 times from the require module. Is there an alternative way to achieve the following without using global functions?
main.js with global function
const myMod = require('./module.js");
global.myGlobalFunction = function(param){
console.log("do something with",param);
}
module.js with the calls of the global function:
module.exports = function(){
myGlobalFunction("class");
myGlobalFunction("this");
myGlobalFunction("bubu");
// other jobs to do
}
The neater way to do it is to use modules like this:
module.js
class myGlobalUtil {
myGlobalFunction(param){
console.log("do something with",param)
}
get GetFromParam(myParam){
return this.myGlobalFunction(myParam);
}
}
module.exports = myGlobalUtil;

What is exports.install in node js?

Hi I found a framework where they use a lot this pattern.
exports.install = function(){
//code
}
but usually you see this pattern in nodejs
module.exports = {
//code
}
Is this the same thing or is this something else ?
exports is the object corresponding to module.exports before you do anything to it. I think it's due to some legacy code, but basically folks use module.exports if they want to replace the whole object with their own object or a function, while they use exports if they just want to hang functions off the module. It's a little confusing at first, but essentially exports.install just means that calling code would do something like:
const mod = require('that-module');
mod.install(params, callback); // call that function
The framework you're looking at is probably using it as part of a bootstrapping process, afaik it doesn't have significance to the node engine itself.
Yes, it is the same thing. You can use one of 2 ways to setup your code.
The different thing is memory. They point to same memory. You can think exports like a variable and you can not use this way to export your module:
Given this module:
// test.js
exports = {
// you can not use this way to export module.
// because at this time, `exports` points to another memory region
// and it did not lie on same memory with `module.exports`
sayHello: function() {
console.log("Hello !");
}
}
The following code will get the error: TypeError: test.sayHello is not a function
// app.js
var test = require("./test");
test.sayHello();
// You will get TypeError: test.sayHello is not a function
The correct way you must use module.exports to export your module:
// test.js
module.exports = {
// you can not use this way to export module.
sayHello: function() {
console.log("Hello !");
}
}
// app.js
var test = require("./test");
test.sayHello();
// Console prints: Hello !
So, it just is style of developer.

nodejs override a function in a module

I am trying to test a function in a module. This function ( I will refer to it as function_a ) calls a different function ( function_b ) within the same file. So this module looks like this:
//the module file
module.exports.function_a = function (){
//does stuff
function_b()
};
module.exports.function_b = function_b = function () {
//more stuff
}
I need to test function_a with a specific result from function_b.
I would like to override function_b from my test file, then call function_a from my test file, resulting in function_a calling this override function instead of function_b.
Just a note, I have tried and succeeded in overriding functions from separate modules, like this question, but that is not what I am interested in.
I have tried the code below, and as far as I know, doesn't work. It does illustrates what I am going for, though.
//test file
that_module = require("that module")
that_module.function_b = function () { ...override ... }
that_module.function_a() //now uses the override function
Is there a correct way to do this?
From outside a module's code, you can only modify that module's exports object. You can't "reach into" the module and change the value of function_b within the module code. However, you can (and did, in your final example) change the value of exports.function_b.
If you change function_a to call exports.function_b instead of function_b, your external change to the module will happen as expected.
You can actually use the package rewire. It allows you to get and set whatever was declared in the module
foo.js
const _secretPrefix = 'super secret ';
function secretMessage() {
return _secretPrefix + _message();
}
function _message() {
return 'hello';
}
foo.test.js
const rewire = require('rewire');
// Note that the path is relative to `foo.test.js`
const fooRewired = rewire('path_to_foo');
// Outputs 'super secret hello'
fooRewired.secretMessage();
fooRewired.__set__('_message', () => 'ciao')
// Outputs 'super secret ciao'
fooRewired.secretMessage();

RequireJS issues accessing app object across app

I have an application which has an app object which does the start routine and stores useful things like app.state and app.user. However I am trying to access this app instance without passing this from the app instance all the way around my large codebase.
Strangely I work on other projects which include app in the same way as in something.js and it works but I can't see why.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Cannot require app in another file</title>
</head>
<body>
<script data-main="config" src="require.js"></script>
</body>
</html>
config.js
requirejs.config({
deps: ['app']
});
app.js
define([
'something'
], function(Something) {
'use strict';
var App = function() {
this.name = 'My app';
};
return new App();
});
something.js
define([
'require',
'app'
], function (require, app) {
'use strict';
var SomeModule = function() {
app = require('app'); // EXCEPTION
console.log('App:', app);
};
return new SomeModule();
});
When loading this requirejs exception is throw because of the require in SomeModule:
Uncaught Error: Module name "app" has not been loaded yet for context: _
Demo of above (see console for error): http://dominictobias.com/circulardep/
It's not clear to me why you need to have a circular dependency. As stated in the documentation for RequireJS:
Circular dependencies are rare, and usually a sign that you might want to rethink the design.
This being said, if you do need the circular dependency, the issue with your code is that require('app') is called too early. It cannot be called until after the module something has returned its value. Right now, it is called before the value is returned. If you look at the code given as example in the documentation:
define(["require", "a"],
function(require, a) {
//"a" in this case will be null if a also asked for b,
//a circular dependency.
return function(title) {
return require("a").doSomething();
}
}
);
you see that the module returns a function which then would be called by the code that required the module, which happens after this module has returned its value.
So how do you fix this? What you could do is have the class you return call a function that fetches module app whenever needed. So:
define([
'require',
'app'
], function (require) {
'use strict';
var app_;
function fetch_app() {
if (app_ === undefined)
app_ = require("app");
return app_;
}
var SomeModule = function() {
// ...
};
SomeModule.prototype.doSomethingWithApp = function () {
var app = get_app();
app.whatever();
};
return new SomeModule();
});
I've removed app from the list of arguments and store the value of the app module in app_ because doing it this way provides for early detection of a missing call to get_app() in any method of SomeModule. If app is made a parameter of the module's factory function then using app inside a method without calling get_app() first would be detected only if it so happened that no other method that calls get_app() was called first. (Of course, I could type app_ and face the same problem as the one I aim to prevent. It's a matter of respective likelihoods: I'd be very likely to forget to call get_app() everywhere it is needed because I don't usually write code with circular dependencies. However, I'd be unlikely to type app_ for app because I don't usually put _ at the end of my variable names.)

Namespaces in node.js with require

I am playing around and learning about vows with a personal project. This is a small client side library, with testing done in vows. Therefore, I must build and test a file that is written like this:
(function(exports) {
var module = export.module = { "version":"0.0.1" };
//more stuff
})(this);
In my testing (based off of science.js, d3, etc.) requires that module like so:
require("../module");
I continued to get a "module not defined error" when trying to run the tests, so I went to a repl and ran:
require("../module")
and it returned:
{ module: { version: "0.0.1" } }
I realize I could do something like:
var module = require("../module").module;
but feel like I am creating a problem by doing it that way, especially since the libraries that I based this project on are doing it in the format I described.
I would like for my project to behave similar to those which I based it off of, where:
require("../module");
creates a variable in this namespace:
module.version; //is valid.
I have seen this in a variety of libraries, and I am following the format and thought process to the T but believe I might be missing something about require behavior I don't know about.
There is no problem creating it this way. Modules define what they return in the module.exports object. By the way, you don't actually need self executing functions (SEF), there is no global leakage like in browsers :-)
Examples
module1.js:
module.exports = {
module: { 'version': '0.1.1' }
};
main.js:
var module1 = require( './module1.js' );
// module1 has what is exported in module1.js
Once you've understood how this works, you can easily export the version number right away if you want to:
module1.js:
module.exports = '0.1.1';
main.js:
var module1 = require( './module1.js' );
console.log( module1 === '0.1.1' ); // true
Or if you want some logic, you can easily extend your module1.js file like this:
module.exports = ( function() {
// some code
return version;
} () ); // note the self executing part :-)
// since it's self executed, the exported part
// is what's returned in the SEF
Or, as many modules do, if you want to export some utility functions (and keep others "private"), you could do it like this:
module.exports = {
func1: function() {
return someFunc();
},
func2: function() {},
prop: '1.0.0'
};
// This function is local to this file, it's not exported
function someFunc() {
}
So, in main.js:
var module1 = require( './module1.js' );
module1.func1(); // works
module1.func2(); // works
module1.prop; // "1.0.0"
module1.someFunc(); // Reference error, the function doesn't exist
Your special case
About your special case, I wouldn't recommend doing it like they're doing.
If you look here: https://github.com/jasondavies/science.js/blob/master/science.v1.js
You see that they're not using the var keyword. So, they're creating a global variable.
This is why they can access it once they require the module defining the global variable.
And by the way, the exports argument is useless in their case. It's even misleading, since it actually is the global object (equivalent of window in browsers), not the module.exports object (this in functions is the global object, it'd be undefined if strict mode were enabled).
Conclusion
Don't do it like they're doing, it's a bad idea. Global variables are a bad idea, it's better to use node's philosophy, and to store the required module in a variable that you reuse.
If you want to have an object that you can use in client side and test in node.js, here is a way:
yourModule.js:
// Use either node's export or the global object in browsers
var global = module ? module.exports : window.yourModule;
( function( exports ) {
var yourModule = {};
// do some stuff
exports = yourModule;
} ( global ) );
Which you can shorten to this in order to avoid creating the global variable:
( function( exports ) {
var yourModule = {};
// do some stuff
exports = yourModule;
} ( module ? module.exports : window.yourModule ) );
This way, you can use it like this on the client-side:
yourModule.someMethod(); // global object, "namespace"
And on the server side:
var yourModule = require( '../yourModule.js' );
yourModule.someMethod(); // local variable :-)
Just FYI, .. means "parent directory". This is the relative path of where to get the module. If the file were in the same directory, you'd use ..

Resources