RequireJS dependency is undefined if I name the module - requirejs

I'm using Durandal, and I'm trying to use this module as a dependency for another module:
define('Beer', function () {
return function Beer (name, brewery) {
this.name = name;
this.brewery = brewery;
};
});
In the other module, I do this:
define(['knockout', 'models/Beer'], function (ko, Beer) {
return {
displayName: 'Add',
name: ko.observable(),
brewery: ko.observable(),
save: function () {
var beer = new Beer(this.name(), this.brewery());
console.log(beer);
}
}
});
My javascript is loaded, because I define it in my paths (and I checked in Firebug). But the Beer argument in my second module is undefined. I don't know why, as my Beer module does return something (it returns the function). What else can I look at? Most solutions I find are that the (first) module isn't returning anything, but mine clearly is.
UPDATE
Apparently, when I remove the name of my Beer module, it works:
define(function() {
return function Beer (name, brewery) {
// ...
}
});
Even though this code would seem to work, it doesn't for me. Can anyone tell me why?

You are mixing named modules with anonymous modules in your approach.
If you name the module 'Beer', you require it using the name, not the path:
require(['Beer'], function (Beer) {
var a = new Beer();
});
If you remove the name from the Beer module, you have an anonymous module which you can load by path:
require(['path/to/Beer'], function (Beer) {
var a = new Beer();
}
Edit: the topic you linked to does not use RequireJS, even though it looks similar.

Related

require.resolve() works. Why doesn't module.parent.require.resolve()?

I'm trying to find the file of included modules. From the main module, require.resolve('module') happily returns me the value of the main key from the module's package.json.
However, I would like to do this from a module that's been included via npm. If I simply call require.resolve('module'), it looks in the node_modules for this module, whereas I need to resolve it from the point of view of the running package.
According to the docs, require is actually module.require and module.parent returns the module that first required this one. Why then does module.parent.require.resolve('module') not work? I get ana
error:
TypeError: module.parent.require.resolve is not a function
Oddly though, console.log module.parent.require.toString() returns
function (path) {
assert(path, 'missing path');
assert(typeof path === 'string', 'path must be a string');
return Module._load(path, this, /* isMain */ false);
}
so it certainly looks like a function to me.
Anyone know what's going on? I've also tried require.main.require.resolve() and that does a very similar thing.
TypeError: module.parent.require.resolve is not a function
Oddly though, console.log module.parent.require.toString() returns ...
module.parent.require is a function, module.parent.require.resolve is not.
Why is resolve() not a function?
It appears require() and module.require() are not the same:
console.log(require === module.require); // false
For the curious:
console.log(module.require.toString())
function (path) {
assert(path, 'missing path');
assert(typeof path === 'string', 'path must be a string');
return Module._load(path, this, /* isMain */ false);
}
console.log(require.toString())
function require(path) {
try {
exports.requireDepth += 1;
return mod.require(path);
} finally {
exports.requireDepth -= 1;
}
}
So require() calls module.require(), but is not the same thing.
What about resolve()?
We know require.resolve is a function:
console.log(require.resolve.toString())
function resolve(request) {
return Module._resolveFilename(request, mod);
}
But module.require.resolve is not:
console.log(module.require.resolve)
undefined
So unfortunately resolve() is only available at require.resolve(), and not at module.require.resolve() (or module.parent.require.resolve() for that matter).
Solution?
Not a great solution, but you could try manually calling Module._resolveFilename() and passing in the parent module instead of the current module:
const Module = module.constructor;
const fileName = Module._resolveFilename('module', module.parent);
This solution isn't great because it relies on internal API functions that could possibly change in the future. It would be nice if NodeJS would provide better documentation and APIs for module loading/resolving.

require('use-strict') doesn't work for me

here, I am attempting to set value for read-only property but I am not getting any error:
HERE IS MY CODE:
require('use-strict');
function Employee(firstname) {
var _firstname = firstname;
Object.defineProperty(this, 'firstName', {
get: function () { return _firstname },
//set: function (value) { _firstname = value }
});
}
var employee = new Employee('Fawad');
employee.firstName = 'Yasir'; //Attempting to set a value for read-only property.
console.log(employee.firstName);
From the documentation for the use-strict package:
The implementation works by patching Node's internal module.wrapper
array, and then freezing it, so that further modifications are not
possible.
Also, this means that the current module will not be affected. You
should still "use strict" in the module that does
require('use-strict'). This module applies strictness to all future
modules loaded by your program.
Use of "use strict"; at the top of page worked for me although this approach is usually used for JavaScript development. I was trying to use one of the node.js packages which didn't worked.

Dynamic require a module by string

require('Something') //working fine
require(`${dynamicName}`) //not work with node prompt for out of memory
Can advise on how to dynamically require a module based on variable 'dynamicName' ?
You can always override require with your own version, since it is a function.
function setupMyRequire() {
var tmpreq = global.require;
global.require = function(name) {
// parse name here
console.log('will require', name);
tmpreq(name);
};
}

Defining modules in UI5

I am trying to keep my code separated in modules. When I defined my first module I extended sap.ui.base.Object and it worked. My question is: Is it a must to extend sap.ui.base.Object when defining my own module? According to the API documentation I tried following example:
sap.ui.define([], function() {
// create a new class
var SomeClass = function();
// add methods to its prototype
SomeClass.prototype.foo = function() {
return "Foo";
}
// return the class as module value
return SomeClass;
});
I required this module inside my Component.js as dependency like this:
sap.ui.define([
"path/to/SomeClass"
], function (SomeClass) {
"use strict";
//var test = new SomeClass();
I always receive a syntax error:
failed to load '[...]/Component.js' from ./Component.js: Error: failed to load '[...]/module/SomeClass.js' from ./module/Service.js: SyntaxError: Unexpected token ;
Does anyone have an idea why this happens? Thanks!
We group code in modules like this for example:
jQuery.sap.declare("our.namespace.iscool.util.Navigation");
our.namespace.iscool.util.Navigation = {
to: function (pageId, context) {
// code here
}
// etc.
}
and call the function of the module like this in a controller
jQuery.sap.require("our.namespace.iscool.util.Navigation");
sap.ui.controller("our.namespace.iscool.Detail", {
// somewhere in this file comes this
handleNavButtonPress: function (evt) {
our.namespace.iscool.util.Navigation.navBackToMaster(
evt.getSource().getBindingContext()
);
},
}
Stupid mistake - missing curly brackets in the docs.
var someclass = function() {} ;

Can I load multiple files with one require statement?

maybe this question is a little silly, but is it possible to load multiple .js files with one require statement? like this:
var mylib = require('./lib/mylibfiles');
and use:
mylib.foo(); //return "hello from one"
mylib.bar(): //return "hello from two"
And in the folder mylibfiles will have two files:
One.js
exports.foo= function(){return "hello from one";}
Two.js
exports.bar= function(){return "hello from two";}
I was thinking to put a package.json in the folder that say to load all the files, but I don't know how. Other aproach that I was thinking is to have a index.js that exports everything again but I will be duplicating work.
Thanks!!
P.D: I'm working with nodejs v0.611 on a windows 7 machine
First of all using require does not duplicate anything. It loads the module and it caches it, so calling require again will get it from memory (thus you can modify module at fly without interacting with its source code - this is sometimes desirable, for example when you want to store db connection inside module).
Also package.json does not load anything and does not interact with your app at all. It is only used for npm.
Now you cannot require multiple modules at once. For example what will happen if both One.js and Two.js have defined function with the same name?? There are more problems.
But what you can do, is to write additional file, say modules.js with the following content
module.exports = {
one : require('./one.js'),
two : require('./two.js'),
/* some other modules you want */
}
and then you can simply use
var modules = require('./modules.js');
modules.one.foo();
modules.two.bar();
I have a snippet of code that requires more than one module, but it doesn't clump them together as your post suggests. However, that can be overcome with a trick that I found.
function requireMany () {
return Array.prototype.slice.call(arguments).map(function (value) {
try {
return require(value)
}
catch (event) {
return console.log(event)
}
})
}
And you use it as such
requireMany("fs", "socket.io", "path")
Which will return
[ fs {}, socketio {}, path {} ]
If a module is not found, an error will be sent to the console. It won't break the programme. The error will be shown in the array as undefined. The array will not be shorter because one of the modules failed to load.
Then you can bind those each of those array elements to a variable name, like so:
var [fs, socketio, path] = requireMany("fs", "socket.io", "path")
It essentially works like an object, but assigns the keys and their values to the global namespace. So, in your case, you could do:
var [foo, bar] = requireMany("./foo.js", "./bar.js")
foo() //return "hello from one"
bar() //return "hello from two"
And if you do want it to break the programme on error, just use this modified version, which is smaller
function requireMany () {
return Array.prototype.slice.call(arguments).map(require)
}
Yes, you may require a folder as a module, according to the node docs. Let's say you want to require() a folder called ./mypack/.
Inside ./mypack/, create a package.json file with the name of the folder and a main javascript file with the same name, inside a ./lib/ directory.
{
"name" : "mypack",
"main" : "./lib/mypack.js"
}
Now you can use require('./mypack') and node will load ./mypack/lib/mypack.js.
However if you do not include this package.json file, it may still work. Without the file, node will attempt to load ./mypack/index.js, or if that's not there, ./mypack/index.node.
My understanding is that this could be beneficial if you have split your program into many javascript files but do not want to concatenate them for deployment.
You can use destructuring assignment to map an array of exported modules from require statements in one line:
const requires = (...modules) => modules.map(module => require(module));
const [fs, path] = requires('fs', 'path');
I was doing something similar to what #freakish suggests in his answer with a project where I've a list of test scripts that are pulled into a Puppeteer + Jest testing setup. My test files follow the naming convention testname1.js - testnameN.js and I was able use a generator function to require N number of files from the particular directory with the approach below:
const fs = require('fs');
const path = require('path');
module.exports = class FilesInDirectory {
constructor(directory) {
this.fid = fs.readdirSync(path.resolve(directory));
this.requiredFiles = (this.fid.map((fileId) => {
let resolvedPath = path.resolve(directory, fileId);
return require(resolvedPath);
})).filter(file => !!file);
}
printRetrievedFiles() {
console.log(this.requiredFiles);
}
nextFileGenerator() {
const parent = this;
const fidLength = parent.requiredFiles.length;
function* iterate(index) {
while (index < fidLength) {
yield parent.requiredFiles[index++];
}
}
return iterate(0);
}
}
Then use like so:
//Use in test
const FilesInDirectory = require('./utilities/getfilesindirectory');
const StepsCollection = new FilesInDirectory('./test-steps');
const StepsGenerator = StepsCollection.nextFileGenerator();
//Assuming we're in an async function
await StepsGenerator.next().value.FUNCTION_REQUIRED_FROM_FILE(someArg);

Resources