requirejs dependency loaded even condition is false - requirejs

Why a script tag with the script URL corresponding to require("messages") was injected in HTML file
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="messages" src="lib/messages.js"> </script>
even the condition is false ? Thanks.
Here is the code that generates it :
define(function (require) {
var bool = false;
if (bool) {
var messages = require('messages');
alert(messages.getHello());
} else{
alert("Module messages not loaded !");
}
});
Tested the code below and noticed that the script tag for loading messages.js is not generated
define(function (require) {
var bool = false;
if(bool){
var dep = 'messages';
var messages = require(dep);
alert(messages.getHello());
} else{
alert("Module messages not loaded !!");
}
});
Same here:
define(function (require) {
var bool = false;
if (bool) {
var messages = require('messages', function(messages){
alert(messages.getHello());
});
} else{
alert(" Module messages not loaded !");
}
});

Require calls without square brackets ( like require('messages') ) are parsed from file using regular expressions and treated as dependency of the module it is written in. Author had to take this decision for adding sugar syntax we are talking about here.
If you need to use conditional dependency, you have to use square bracket syntax like below.
define(function (require) {
var bool = false;
if (bool) {
require(['messages'], function(messages){ //Note the square brackets around messages
alert(messages.getHello());
});
} else{
alert(" Module messages not loaded !");
}
});

Related

Where do I execute my on-first-start functions in my Electron app?

I am using Electron 9 and I have a main process and a single render process. On the first start of my application I would like to execute some code which is not executed on the second run.
Does Electron have a dedicated location where I should do this? Any help is highly appreciated!
Use app.getPath('userData') - it's dedicated location for your apps data for current user (eg. in windows it will point to something like AppData/Roaming/app-name/)
At startup use:
app.on('ready', () => {
const firstTimeFilePath = path.resolve(app.getPath('userData'), '.first-time-huh');
let isFirstTime;
try {
fs.closeSync(fs.openSync(firstTimeFilePath, 'wx'));
isFirstTime = true;
} catch(e) {
if (e.code === 'EEXIST') {
isFirstTime = false;
} else {
// something gone wrong
throw e;
}
}
// ...
});
Profit!
https://nodejs.org/api/fs.html#fs_file_system_flags - why use wx flag
https://nodejs.org/api/fs.html#fs_fs_opensync_path_flags_mode - fs.openSync()
https://www.electronjs.org/docs/api/app#appgetpathname - app.getPath()
If you want to write out default preferences in the first run and read them in the next runs, try this:
import defaults from './default_preferences.json'; // will work for plain js objects too
let prefs = defaultPrefs;
app.on('ready', () => {
const prefsPath = path.resolve(app.getPath('userData'), 'prefs.json');
let isFirstTime;
try {
fs.writeFileSync(prefsPath, JSON.stringify(defaultPrefs), { flag: 'wx' });
isFirstTime = true;
} catch (e) {
if (e.code === 'EEXIST') {
// slight posibility of races, you can eleminate it by using `singleInstanceLock` or waiting loop for `write` flag
prefs = require(prefsPath);
isFirstTime = false;
} else {
// something gone wrong
throw e;
}
}
...
});

NodeJS: call func from inside another func in same file

I have NodeJS program.
In one class, I have various utility methods. One function, safeGithubPush, calls safeString, another func in the same class
module.exports = {
safeString(stringToCheck) {
console.log(validator.isAscii(stringToCheck), validator.matches(stringToCheck, /^((\w)*[-.]?(\w)*)*$/))
return (
validator.isAscii(stringToCheck) &&
validator.matches(stringToCheck, /^((\w)*[-.]?(\w)*)*$/)
);
},
safeGithubPush(currentJob) {
if (
!currentJob ||
!currentJob.payload ||
!currentJob.payload.repoName ||
!currentJob.payload.repoOwner ||
!currentJob.payload.branchName
) {
this.logIn(
currentJob,
`${' (sanitize)'.padEnd(15)}failed due to insufficient job definition`
);
throw invalidJobDef;
}
if (
this.safeString(currentJob.payload.repoName) &&
this.safeString(currentJob.payload.repoOwner) &&
this.safeString(currentJob.payload.branchName)
) {
return true;
}
throw invalidJobDef;
},
}
While this.logIn(), another func in the utility class, works just fine, I get the error for safeString:
Error caught by first catch: TypeError: this.safeString is not a function
I followed a solution offer by another SO post:
safeString: function(stringToCheck){
...
}
safeGithubPush(currentJob) {
...
if (
this.safeString(currentJob.payload.repoName) &&
this.safeString(currentJob.payload.repoOwner) &&
this.safeString(currentJob.payload.branchName)
) {
return true;
}
}
But this also gets a, TypeError: this.safeString is not a function.
I'm not using arrow functions, which is the explanation for this error on a different SO post
I don't think the reason is determinable with the code you are currently presenting. It likely has something to do with how you are calling safeGithubPush. If you do something that would change the this binding the this.safeString is going to fail.
const foo = {
fizz() {
console.log("fizz");
},
buzz() {
this.fizz();
}
};
// "this" is correct
foo.buzz();
// "this" has no fizz to call
const myFizz = foo.buzz;
myFizz();
Considering you are attaching these to module.exports I am going to guess that you pull these functions off in a require call and then try to use them bare which makes the problem obvious after looking at my example above:
// Ignore these 2 lines, they let this look like node
const module = {};
const require = () => module.exports;
// Ignore above 2 lines, they let this look like node
// Your module "some.js"
module.exports = {
safeString(str) {
return true;
},
safeGithubPush(currentJob) {
if (!this.safeString("some")) {
throw new Error("Not safe");
}
return true;
}
};
try {
// Some consumer module that doesn't work
const {safeGithubPush} = require("./some.js");
const isItSafe = safeGithubPush();
console.log(`Safe? ${isItSafe}`);
} catch (err) {
console.error("Didn't bind right \"this\"");
}
try {
// Some consumer module that DOES work
const someModule = require("./some.js");
const isItSafe = someModule.safeGithubPush();
console.log(`Safe? ${isItSafe}`);
} catch (err) {
console.error(err);
}
I would restructure this code. You say these are utility functions which makes me think you don't really want to have to structure them with this in mind.
Instead of attaching them all to module.exports at their definition, define them outside and directly reference the functions you want to use, then attach them to exports so other modules can use the functions:
function safeString(stringToCheck) {
return true;
}
function safeGithubPush(currentJob) {
if (!safeString("some")) {
throw new Error("Not safe");
}
return true;
}
module.exports = {
safeString,
safeGithubPush
};

Unable to use variable outside of class in the class

I am making a simple note taking app to learn node and ES6. I have 3 modules - App, NotesManager and Note. I am importing the Note class into the NotesManager and am trying to instantiate it in its addNote function. The problem is that even though the import is correct, it turns out to be undefined inside the class definition. A simpler solution would be to just instantiate the NotesManager class and add the Note class to its constructor however, I want to have NotesManager as a static utility class.
Here is my code.
Note.js
class Note {
constructor(title, body) {
this.title = title;
this.body = body;
}
}
module.exports = Note;
NotesManager.js
const note = require("./Note");
console.log("Note: ", note); //shows correctly
class NotesManager {
constructor() {}
static addNote(title, body) {
const note = new note(title, body); //Fails here as note is undefined
NotesManager.notes.push(note);
}
static getNote(title) {
if (title) {
console.log(`Getting Note: ${title}`);
} else {
console.log("Please provide a legit title");
}
}
static removeNote(title) {
if (title) {
console.log(`Removing Note: ${title}`);
} else {
console.log("Please provide a legit title");
}
}
static getAll() {
//console.log("Getting all notes ", NotesManager.notes, note);
}
}
NotesManager.notes = []; //Want notes to be a static variable
module.exports.NotesManager = NotesManager;
App.js
console.log("Starting App");
const fs = require("fs"),
_ = require("lodash"),
yargs = require("yargs"),
{ NotesManager } = require("./NotesManager");
console.log(NotesManager.getAll()); //works
const command = process.argv[2],
argv = yargs.argv;
console.log(argv);
switch (command) {
case "add":
const title = argv.title || "No title given";
const body = argv.body || "";
NotesManager.addNote(title, body); //Fails here
break;
case "list":
NotesManager.getAll();
break;
case "remove":
NotesManager.removeNote(argv.title);
break;
case "read":
NotesManager.getNote(argv.title);
break;
default:
notes.getAll();
break;
}
Is it possible for me to create a strict utility class which I can use without instantiating like in Java? Pretty new here and have tried searching for it without any luck. Thank you for your help.
When you do this:
const note = new note(title, body);
you redefine note shadowing the original note from the outer scope. You need to pick a different variable name.
Something like this should work better:
static addNote(title, body) {
const some_note = new note(title, body); //Fails here as note is undefined
NotesManager.notes.push(some_note);
}

Inheritance in Node.JS

I am using node.js and programming based on express.js. I have tried to use util.inherits to implement inheritance in JavaScript. What I've tried is as follows:
//request.js
function Request() {
this.target = 'old';
console.log('Request Target: ' + this.target);
}
Request.prototype.target = undefined;
Request.prototype.process = function(callback) {
if (this.target === 'new')
return true;
return false;
}
module.exports = Request;
//create.js
function Create() {
Create.super_.call(this);
this.target = 'new';
}
util.inherits(Create, Request);
Create.prototype.process = function(callback) {
if (Create.super_.prototype.process.call(this, callback)) {
return callback({ message: "Target is 'new'" });
} else {
return callback({ message: "Target is not 'new'" });
}
}
module.exports = Create;
//main.js
var create = new (require('./create'))();
create.process(function(msg) {
console.log(msg);
});
My scenario is :
I have Request as base class and Create as child class. Request has field target that initialize old in Request constructor.
Now, I create Create class object which first call Request constructor and then initialize target field with new. When I call process function of Create, I expect to get message of target is 'new' but it returns another!
I searched similar threads for this, but all are what i tried! Can any one explain what was wrong?
Thanks in advance :)
util.inherits has really awkward super_... anyway, this should work:
Create.super_.prototype.process.call(this, callback);
But really,
var super_ = Request.prototype;
And then the syntax becomes almost convenient:
super_.process.call(this, callback);

How to test one function of a class and how to avoid some code when test a function?

Sample code:
function TestClass() {
var this.name = 'test';
var this.host = '...';
var this.port = '...';
//...
this.connection = this.createConnection(....);
}
TestClass.prototype.testFunc = function(data) {
if(data == this.name) {
return true;
} else {
return false;
}
}
Testclass.prototype.createConnection = function (...) {
//some code
//a real HTTP connection will be created
//some code
}
Now I want to test testFunc, it has a class variable this.name, so I have to create a TestClass instance. But if I create TestClass instance, a real HTTP connection will be created. How can I avoid this real HTTP connection when testing?
In situation like this, how can I write the test code?
Try to simply re-define createConnection in your test, before you instantiate TestClass.
TestClass.prototype.createConnection = function() {
console.log("Called redefined createConnection");
}
You should mock the dependency that make the request not your class you wanna test. Take a look at this nock, a HTTP mocking and expectations library

Resources