How to load settings before rest of node app? - node.js

I would like to load the settings for my node application before the app loads, so the settings will be available as the code is loaded. I can get a LoadSettings.js file to run using --require but the promise that loads the settings doesn't resolve before the app is loaded. Is there a way that I can force node to wait for the promise to resolve before the loading of this require completes and the rest of the app is loaded?

This is possible using deasync. Here's an example:
import settings from './settings';
let done = false;
function loadSettings() {
console.log('Loading settings');
return settings.load().then(() => {
console.log('Loaded settings');
done = true;
});
}
loadSettings();
require('deasync').loopWhile(() => {
return !done;
});

Related

debug library not working in conjunction with amqplib (rabbitmq)

We run our app in two "modes":
Our REST API (express js)
Our background processor (amqplib)
Our REST API that starts using nodemon runs completely fine with debug, however our background processor does not work with debug.
We declare DEBUG=app:* in our .env file and yes, we do see it when we console log but for some reason when we do the following, nothing reports when running our background processor.
We do see that one of amqp's dependencies called bitsyntax uses debug. I am wondering if it does anything to turn off debug but cannot find anything in their code that does that.
Is there anything I can do to resolve this problem?
import amqp from 'amqplib/callback_api'
import dotenv from 'dotenv'
import debug from 'debug'
const testLog = debug('app:worker')
const rabbitmq = `amqp://${process.env.RABBITMQ_USER}:${process.env.RABBITMQ_PASS}#${process.env.RABBITMQ_HOST}`
console.log(process.env.DEBUG) // app:*
const worker = () => {
try {
amqp.connect(rabbitmq, (err, conn) => {
// ...
testLog('this does not show up')
console.log('this does show up')
// ...
})
} catch (err) {
// ...
}
}
worker()
We run our background processor using the following command:
NODE_ENV=development nodemon ./src/workers/index.ts
As per the following github issue response,
on workers the following code needs to be enabled:
debug.enable(process.env.DEBUG)

How do I mock an imported object in Jest?

So, I'm working my way through learning Jest, and in a current Aurelia project, the internal working of the generated main.js script imports a configuration object (environment). Note this code is all as-generated.
// main.js
import environment from './environment';
import {PLATFORM} from 'aurelia-pal';
import 'babel-polyfill';
import * as Bluebird from 'bluebird';
// remove out if you don't want a Promise polyfill (remove also from webpack.config.js)
Bluebird.config({ warnings: { wForgottenReturn: false } });
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.feature(PLATFORM.moduleName('resources/index'));
// Uncomment the line below to enable animation.
// aurelia.use.plugin(PLATFORM.moduleName('aurelia-animator-css'));
// if the css animator is enabled, add swap-order="after" to all router-view elements
// Anyone wanting to use HTMLImports to load views, will need to install the following plugin.
// aurelia.use.plugin(PLATFORM.moduleName('aurelia-html-import-template-loader'));
if (environment.debug) {
aurelia.use.developmentLogging();
}
if (environment.testing) {
aurelia.use.plugin(PLATFORM.moduleName('aurelia-testing'));
}
return aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));
}
The environment object is just holding a couple simple values:
export default {
debug: true,
testing: true
};
Now, when I want to test the branching logic in main.js, I want to be able to flip those booleans to ensure they do or don't execute the config changes as appropriate:
import {configure} from '../../src/main';
import environment from '../../src/environment';
/* later... */
describe('when the environment is not set to debug', () => {
environment.debug = false;
it('should not configure development logging', () => {
configure(aureliaMock);
expect(aureliaMock.use.developmentLogging.mock.calls.length).toBe(0);
});
});
This does not work, as the version of environment being checked inside the configure() function still has the values in the source module. I recognize that environment in this case is my local value, but what I don't know is how to affect the instance of environment that's being checked.
I tried using the jest.mock() syntax you'd use with an ES6 class constructor, but that doesn't work either. I will probably change the configure() signature to accept an environment for testing, but before doing so I wanted to see if there's a way to do this via mocks first.

Accessing Meteor settings in Mocha

I want to do write some unit tests with mocha but for some tests i need to access the Meteor.settings which are read by meteor from a file: config/settings.json
Normally i import meteor by:
import { Meteor } from 'meteor/meteor'
But when i try to import this in my test, i get the error: ERROR: Cannot find module 'meteor/meteor' (i also tried to do relative path).
I run my test by this:
"wdio-test": "wdio tests/config/wdio.mocha.conf.js"
and
npm run wdio-test
Anyone can help importing Meteor or accessing the settings file (If possible without file IO operations)?
Stub the meteor core and the settings object:
import { MeteorStubs } from 'meteor/velocity:meteor-stubs';
describe('tests', function() {
beforeEach(function() {
MeteorStubs.install();
Meteor.settings.public.foo = 'bar';
});
afterEach(function() {
MeteorStubs.uninstall();
});
it('gets setting', function() {
chai.assert.equal(Meteor.settings.public.foo, 'bar');
});
});

Understanding ExpressJS application start-up

I am struggling with how application start-up works in Express. I am going to explain my use-case:
I have a configuration-Manager module which is used by all other application modules to load required configuration. I am setting configuration in app.listen:
app.listen(9000, function () {
try
{
config_manager.setSiteConfig();
console.log('settings..!!!')
}
catch(err)
{
console.log(err.stack);
}
});
In another module of the same application I call the Configuration-Manager function to load config, but it returns empty. Code is something like this:
var config_manager = require('configuration-manager');
console.log(config_manager.loadConfig()); // returns empty object {}
I am running the application using node app.js. The empty object gets printed first then ('settings..!!!'). Does Express compile the script before calling app.listen()? How do I make sure that my configuration is set before compilation/loading other files?
Express indeed first processes all statements in a file, basically anything that isn't in a function on startup.
In your case var config_manager = require('configuration-manager');
console.log(config_manager.loadConfig()); // returns empty object {} is executed before your app.listen because you are requering the config before the app.listen.
You're best off processing your configuration right after the first time it is required (if app.js is your main file, this means the first time it comes across a require statement pointing to configuration-manager in any file).
This should make your code work:
var config_manager = require('configuration-manager');
try {
config_manager.setSiteConfig();
} catch(err) {
console.log(err.stack);
}
console.log(config_manager.loadConfig()); // returns empty object {}
and then
app.listen(9000, function () {
console.log('settings..!!!', config_manager.loadConfig()) // Should correctly print your config
});
If this doesn't work the problem does not lay in the order of execution.

RequireJS plugin, load files on demand

I have RequireJS implemented fine, and a Grunt based build process which is optimizing the all the JS files app into one file via r.js which is also working fine. All my app files are concatenated into one big JS file for efficient production deployment.
Now I'm having the following requirements:
I need to write a plugin for requirejs, that will not load(not include the file) into the optimized file in the build process, but will required on demand:
Meaning in my code I'll have:
var myObj = require("myplugIn!jsFile");
So in the end when this line runs, it will runs in 2 options:
on build process, the file is not included in the optimized file
The application is running, it will be request the file on demand.
I wrote the following plugin, but is not working:
define(function () {
"use strict";
return {
load : function (name, req, onload, config) {
// we go inside here we are running the application not in build process
if (!config.isBuild) {
req([name], function () {
onload(arguments[0]);
});
}
}
};
});
What I'm missing here.
In your build configuration you can exclude files that you don't want to bundle. They will still be loaded on demand when needed. You may also do something like this:
define(function (){
// module code...
if (condition){
require(['mymodule'], function () {
// execute when mymodule has loaded.
});
}
}):
This way mymodule will be loaded only if condition is met. And only once, if you use same module dependency elsewhere it will return loaded module.
It was more simpler that I though, if helps someone, I'm posting the solution, I create a plugin , that in build process return nothing and in run time, returns the required file, hope helps someone.
define(function () {
"use strict";
return {
load : function (name, req, onload, config) {
if (config.isBuild) {
onload(null);
} else {
req([name], function () {
onload(arguments[0]);
});
}
}
};
});

Resources