Add global function to every execution of NodeJS - node.js

In my project folder project I have a file utils.js like this
global.root_path = process.cwd();
global.custom_require = function() {
console.log('custom require called');
}
I would like to include this file in every execution of node so that in every js file in project i can call custom_require, or access global.root_path as I'm doing already with built-in function require.
Do you know if there is a solution (command line options, environment variable or whatever) to achieve this?
UPDATE
I don't want to include utils.js in every file, in that case I wouldn't need to modify global object.
Thanks!

Simply require it. Example app.js:
require('./utils.js');
var express = custom_require('express');
var app = express();
var port = process.env.PORT || 3000;
app.listen(port);
Then, you could just do (in terminal)
node app
As long as you require the code containing the global declarations on it, then you can use those globals from any file that's required after the fact.
You most probably don't want to have a custom "plugin" altering the behavior of all your applications when run locally, thus it'd be best to stay away from that kind of pattern. Instead, you might want to create a module, use npm link on it, and then npm link something in your project's directory, where something is the module name.
Then each project could just add one line like require('something'); at the very beginning. Changing something would immediately impact all the projects which included it, thanks to the behavior in npm link.

Related

How to use `index.js` in a Node.js when creating an Express service?

Hi I am structuring my Node.js project based on this, like so:
Root
product name
index.js: (contains requires for the product and the main export)
productName.js: contains application logic
test
test1.js
test2.js
...
Now I have two questions
What should logically go in index.js? At the moment I have this (would this be a good way to do things and what else might I include in index.js?):
// index.js
var myServer = require('./myServer.js'); // "product name" = "myServer"
module.exports = {
run: myServer.listen
}
Does it matter what I call the object key in module.exports (currently "run")? Why does the server always run when I execute index.js with $ node index.js how does it automatically know to run myServer.listen?
P.S.: I am aware of web structure auto-generation tools, I just wish to understand the logical reason for this suggested structure (the idea of not having any logic in index.js)
As you mentioned this is a Express service, if it is only handling backend of some application or more specifically this is only backend application, I would suggest you change name of your index.js to server.js(Thus explicitly stating that it'll process all service requests).
But if not then even index.js is fine.
Now for
1
What you've put is absolutely fine, apart from this you could require all modules, routes(or controllers whatever you name them) in a way that it serves as entry point to your application. Try not to put any logic in here.
2
Actually the server runs because it executes the script in the file called index.js, the script says myServer.listen, now if you had written console.log("Hello World") and used $ node index.js it would've printed Hello World instead.
Node just expects and executes script that is there in index.js, in your case it is to start the server.
About the logic that why not put anything else in index.js, for me the reasoning I consider good enough is it provides abstraction as it is the entry point I don't want index.js to worry about things like what to do with this data and all. I believe it should provide a base to setup server. Thus following single responsibility to some extent. Also I won't have to touch it ever in projects lifetime unless some major change occurs e.g. I decide to shift from express to something else.
EDIT
Why have a key called run
You seem to have answered it yourself(in comments), you are giving or more proper description would be you're attaching an object to module.exports as it is a object similar to JSON it was supposed to have a key(which could be anything not necessarily run it could've been hii). Now if you don't want to pass a key and export only one thing that is server.listen then you could write same as module.exports = myServer.listen; instead of
module.exports = {
hii: myServer.listen
}
Note that you could export more modules using the way you did. For more details about module.exports refer this or better google about it as this link might expire anytime and does not seem an ideal thing to put on SO.

how can VS code support Go to definition

I have two JavaScript files: config.js, app.js. In app.js I want to use function defined in config.js so I could use require().
config.js
module.exports = {
somefunc: somefunc
}
app.js
var config = require('./config')
But I don't want to input the './' every time so I add a myRequire.js file.
myRequire.js
global.myRequire = function (p){
return require('./' + p)
}
In that case I could use myRequire('config') next time instead of myRequire('./config'), which might looks more concise.
app.js
require("./myRequire")
var config = myRequire('config')
config.somefunc()
But I met a problem, that I cannot use F12(Go to Definition) in VS Code to find the somefunc function. So could someone tell me what should I do to make it work in this case?
You are introducing a lot more problem than what you are trying to achieve. What if you are requiring a file from different file path '../../here', './over/there'.
If you really want to require something without a path. You can create your own npm module so you can require it globally without paths OR you create a folder with index.js in it and you require all the things you need.

What is the best way to separate your code in a Node.js application?

I'm working on a MEAN (Mongo Express.js Angular Node.js) CRUD application. I have it working but everything is in one .js file. The single source code file is quite large. I want to refactor the code so CRUD functionality is in different source code files. Reading through other posts, I've got a working model but am not sure it is the right way in Node using Mongo to get it done.
Here's the code so far:
<pre>
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var path = require('path');
var db;
var connect = 'mongodb://<<mddbconnect string>>;
const MongoClient = require('mongodb').MongoClient;
var ObjectID = require("mongodb").ObjectID;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/'));
// viewed at http://localhost:<<port referecnes in app.listen>>
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'));
});
MongoClient.connect(connect, (err, database) => {
if (err) return console.log(err)
db = database
app.listen(3000, () => {
console.log('listening on 3000' + Date() );
// Here's the require for the search function in another source code file.
var searchroute = require('./serverSearch')(app, db);
})
})
//Handlers
The rest of the CRUD application functions with app.post, app.get. These are other functions I want to move into different source code files, like serverSearch.js.
</pre>
The code I separated right now is the search functionality which is inside of the MongoClient.connection function. This function has to successfully execute to make sure the variable 'db' is valid before passing both variables 'app' and 'db' to the the search function built out in the source code file serverSearch.js.
I could now build out my other CRUD functions in separate files in put them in the same area as 'var searchroute = require('./serverSearch)(app,db);
Is this the best way to separate code in a MEAN application where the main app and db vars need to be instantiated then passed to functions in other source code files?
What you are basically describing is modular coding heading towards "services" perhaps even micro-services. There are a few factors to keep in mind for your system. (I have no doubt that there are many other approaches to this btw). Basically in most NodeJS systems I have worked on (not all) I try to apply the following architecture in development and then bring over as much as possible I to production.
Create a directory under the main one. I usually use some type of name that points to the term functions. In this directory I maintain function and /or class files divided into categories. Function wrappers for DB would be held in DB functions. This file would only contain functions for the DB. Security functions in another file. Helper functions in another. Time manipulation in another. I am sure you get the idea. These are all wrapped in module exports
Now in any file in my project where say I would need DB and helpers I will start it by:
let nhelpers = require("helpfuncs");
let ndb = require("dbfuncs");
Obviously names are different.
And btw I divide all the NPM packages in the same way under an environment directory.
Maintaining that kind of structure allows you to maintain sane order over the code, logical chaining in any decent IDE, and having relevant methods show up in your IDE without having to remember every function name and all the methods within.
It also allows you to write an orderly system of micro-services making sure each part dies exactly what you want and allows for sane debugging.
It took me awhile to settle on this method and refine it.
It paid off for me. Hope this helps.
Edit to clarify for the OP:
When it comes to the process.env variables I became a great fan of dotenv https://www.npmjs.com/package/dotenv
This little package has saved me an incredible amount of headaches. Of course you will have to decide if you include it in production or not. I have seen arguments for both, but i think in a well set up AWS, Google, Azure environment (or in Docker of course) I am of the opinion it can safely be used.
A couple of caveats.
Do not leave your dotenv file in the root. Move it somewhere else in your directory structure. It is simple and I actually put it in the same directory as all my environment files and helper files.
Remember it is simply a text file. So an IDE will not pick up your specific env variables in chaining. (Unless someone knows of a trick which I would love to hear about)
If you put env variables like access info to your DB system or other sensitive stuff, HASH THEM FIRST, put the hash in your env and have a function in your code which specifically just does the hash to the string. Do not under any conditions leave sensitive information in your environment file without hashing it first.
The final Gatcha. These are not PHP magic globals which cannot be overwritten. If you lose track and overwrite one of those process.env variables in your code it will take the new value until you restart your node app and it reads from the dotenv file again. (But then again that is the rule with all environment variables not only user defined ones)
Any typos above excuse me. Done from my cell in the train.

what does var io = require('../..')(server) do?

I've build the project https://github.com/Automattic/socket.io/tree/master/examples/chat locally and it is working great. However, it would be nice to understand a little more about how a socket application works.
In the main startup script one of the modules that is pulled in with require is
var io = require('../..')(server)
what does require('../..') do?
thanks!
When a path to a directory is given to require, it will implicitly look for an index.js in that directory.
In this case, it's the equivalent of
var socket = require("../../index.js");
var io = socket(server);
In the example provided, they're just using some shorthand and throw away the intermediate value returned by the call to require.
Check out the module.require docs for more info.
Here, in your code
require('../..');
Will add File form the path, which have used SOCKET.IO, as you can see that you have not added Socket.io module.
Also, if no specific path give for file or folder, Module require will try to load index.js or index.node. if no such file exist then it will give error.

How to reference local files in a npm module?

I wrote a simple npm module to precompile my handlebars templates when using django compressor to do post-processing for some client side components and found that I need to ship the npm module with a few js files.
Currently I just assume no one is installing this with the global flag because I've "hard coded" the path to these dependencies in the npm module itself
example layout of my npm module
/
* /bin
* /lib/main.js
* /vendor/ember.js
Now inside main.js I want to use the ember.js file ... currently my hard coded approach looks like this
var emberjs = fs.readFileSync('node_modules/django-ember-precompile/vendor/ember.js', 'utf8');
Again -this only works because I assume you install it local but I'd like to think node.js has a more legit way to get locally embedded files
Anyone know how I can improve this to be more "global" friendly?
What you can do is get the directory of the current file and make your file paths relative to that.
var path = require('path')
, fs = require('fs');
var vendor = path.join(path.dirname(fs.realpathSync(__filename)), '../vendor');
var emberjs = fs.readFileSync(vendor + '/ember.js', 'utf8');
Hope that helps!
One of the great strengths of Node.js is how quickly you can get up and running. The downside to this approach is that you are forced to fit the design patterns it was build around.
This is an example where your approach differs too much from Nodes approach.
Node expects everything in a module to be exposed from the modules exports, including templates.
Move the readFileSync into the django-ember-precompile module, then expose the returned value via a module export in lib/main.js.
Example:
package.json
{
"name": "django-ember-precompile",
"main": "lib/main.js"
}
lib/main.js
module.exports.ember = readFileSync('vendor/ember.js')
vendor/ember.js
You obtain your template via
var template = require('django-ember-precompile').ember
This example can be refined, but the core idea is the same.

Resources