Nodejs express es6 dotenv file loading after controller load - node.js

I load dotenv module in app.js in my node application. I need to call .env attributes inside constructor classes. When I call process.env.ATTRIBUTE it always say undefined. When I look closely I noticed that constructors(JS classes) invoking first before the app.js invoke. How I can make those attribute available in constructor class in order to use them.

Related

Clarification of jest mocking behaviour in nested modules

I'm confused by the jest docs.
This is in the documentation for jest.mock():
Modules that are mocked with jest.mock are mocked only for the file that calls jest.mock. Another file that imports the module will get the original implementation even if it runs after the test file that mocks the module.
But the example in the general section on mocking has:
axios imported in a file called Users
users.test.js sets up the following mock:
import axios from 'axios';
import Users from './users';
jest.mock('axios');
The documentation suggests to me that the test file is should not be able to mock axios in the src users.js file... and yet, this is the example in the docs, so surely it should work.
In my test suite I have a test file that implements a very similar pattern
const fetch = require('node-fetch')
const { getApp } = require('../get-app');
jest.mock('node-fetch', () => require('fetch-mock-jest').sandbox())
the only differences being that
node-fetchis not imported directly within get-app.js, but by one of its dependencies
I use require() rather than import
But my example does not work; when I log out the value of teh fetch function in the dependency that calls it, I get the unmocked implementation of node-fetch.
Can anybody explain
How the example in the jest docs is consistent with the description of how mocking is supposed to work
Why the example in the docs would work, but mine doesn't
Have discovered the issue is with the project being a monorepo, which means there are multiple copies of node-fetch around.
Other than explicitly requiring the other package's copy of node-fetch (i.e. require('../other-package/node_modules/node-fetch'), how could I get the tests of one package to mock a node_module contained in another package's node_modules directory?

Node.js express resource management

Given the following situation:
A Node.js express app with some routes and modules
app.js
/routes
|-user.js
|-login.js
|-e.t.c.
/modules
|-logger.js
Let's say that all the routes need the logger to do proper error handling and logging. Would it be better to include the logger in all the routes or only in app.js and then inject the logger object into the routes?
The latter would seem to be less resource heavy because the object only gets created once, but is this the case?

NODE JS APP: What does this notation mean?

I've picked up a project from another developer, uses the typical MEAN stack with the entry point being server.js.
Now, in server.js, the module that does:
var express = require('express');
var app = express();
var passport = require('passport');
There are another 2 lines of code that look like they are doing some sort of routing but I can't figure out what it actually means:
require('./routes.js')(app, passport);
require('./apiRequest/authenticate')(app, passport);
I'm confused because it looks like require() is called from the global scope, whereas all the other routing methods are called off app, i.e app.use(). Can someone explain what the sets of parameters mean, and why are there two sets also where is require() called from, is it provided by Express?
routes.js and apiRequest/authenticate are two local (project) modules / js files that are basically required here.
express and passport are node modules/libraries that are provided from npm_modules, via node module resolution.
app is simply an express instance created by invoking the express module/default function.
The parameters passed to the required local modules (routes and authenticate) are just parameters passed to those modules (default exported function) that can be used further in those files (e.g. if you look in routes.js you will probably see that they use app.use(..., where app is given as param as well as the passport module)
To explain the syntax require('./routes.js')(app, passport); more clearly:
require - node OOB function for importing modules into the current file/module
require('./routes.js') resolves the default export from the routes.js file which in this case is a function
...(app, passport) this function (from above point) is then invoked with the provided params (which were previously defined here - i.e. imported with require)

Scoping issue using require() in node JS

I set up a web server using node JS and the Express module. My code is as follows :
file tree:
/src
|
+-- server.js
+-- /app
|
+-- routes.js
server.js
// set up ======================================================================
var express = require('express');
var app = express();
var mongoose = require('mongoose');
...
// configuration ===============================================================
mongoose.connect(configDB.url);
...
// routes ======================================================================
require('./app/routes.js')(app, passport);
// launch ======================================================================
app.listen(port);
routes.js
module.exports = function(app, passport) {
app.get('/some-route', function(req, res) {
// this line bugs out
var User = mongoose.model('User', userSchema);
});
};
My question:
Calling mongoose.model() in routes.js throws the following error
ReferenceError:mongoose is not defined
Why is mongoose not known in this context when I've included it in server.js, the file in which routes.js is being included? Should I require() mongoose again in routes.js? What am I missing here?
Variables defined within a module are local only to that module. They are not in the scope of other modules that you require() in with that module. That's why mongoose is not know to your routes module. The require() operation does not insert the code right into the calling module. Instead, it loads that code from disk and then inserts it into its own function and calls that function. This gives each loaded module its own independent scope. It is not inserted into the current scope.
In cases like this, you have several choices:
Require() in the mongoose module again in routes. This is generally preferred when possible because this makes the routes module more self sufficient and easier to reuse as it requires in the things it needs.
Pass in the object you want to share with the routes constructor just like you are passing in app and passport. This method is preferred when the item needed by the other module is not just the result of a simple module load. For example, app is the result of calling a constructor function so the only way for another module to use the same app instance is for you to pass it.
You can have routes call out to some other module to request information. For example, since you've already passed the app object to routes, you could put the mongoose object as either a property on the app object so it could be referenced that way or you could add a method to the app object to retrieve it via the method call.
In this case, since mongoose is just a cached module, it probably makes the most sense to just require() it in again, but any one of the three methods above would work.
The modules that are included is on a file are not visible on another file. Here you can find a list of the global objects that are available on every module that you create:
https://nodejs.org/api/globals.html
All the other objects/variables that you define within a file they are defined within the context of this file. Otherwise, this could create huge problems with variables that overwrite other variables in other files and creating a mess within a project. You can think of a file like a function that includes all your code and everything that is defined in there, is not available to the global namespace.
In your case, you have to require('mongoose') in the files that you need it, and it is built like that so that can maintain the existing connection to the database.

Webpack-dev-server and isomorphic react-node application

I've managed to properly use webpack dev server alongside with a node server (express), using the plugin section inside webpack's config.
It all works fine but now I'm trying to go isomorphic and use client-side components inside the express application.
So far the only problem I'm encountering is that without webpack 'parsing' my server-side code I get to a situation where I require components but the paths are not solved
I.E.
Inside a component
'use strict';
import React from 'react';
import { RouteHandler, Link } from 'react-router';
import Header from 'components/header/main'; // <-- This line causes the error because webpack is not working when parsing this JSX server-side
export default React.createClass({
displayName: 'App',
render() {
return ( // ... More code
Shall I configure webpack in another way or do I have to change all the imports to be valid server-side?
the codebase is here in case you want to see the actual state https://github.com/vshjxyz/es6-react-flux-node-quickstart
In order to be able to require components in a way such as require('components/Header.js'); and avoid using long relative paths such as require('../../../../../../Header.js'); you can add this code to your node app before any require() calls:
process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();
However, since this relies on a private Node.js core method, this is
also a hack that might stop working on the previous or next version of
node.
Other possible solutions to this problem can be found at https://gist.github.com/branneman/8048520
I see 2 options:
Compile client code with webpack as well. If client's entry
point is in the same dir as server's - it should work with your
present code. This looks natural to me.
Use relative paths i.e.
import Header from './components/header/main'

Resources