Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at Scotch On The Rock (SOTR) 2010 (Brussels) with: Cyril Hanquez and Steven Peeters
Ben Nadel at Scotch On The Rock (SOTR) 2010 (Brussels) with: Cyril Hanquez@Fitzchev ) and Steven Peeters@aikisteve )

You Can Use require() To Load JSON (JavaScript Object Notation) Files In Node.js

By Ben Nadel on

At InVision App, we're hiring a lot of Node.js developers. Which means, I get to look at a lot of Node.js sample code. And, one odd thing, that I keep seeing over and over again, is developers using JavaScript modules to define static JSON (JavaScript Object Notation) configuration files. I think maybe they do this because they don't know that you can require() a JSON file in Node.js. As such, I wanted to put together a quick demo.


 
 
 

 
 
 
 
 

The require() function, in Node.js, can read in both .js and .json files. If a file ends with .js, the file is parsed and interpreted as a JavaScript file and is expected to use the module syntax. And, if the file ends with .json, the file is parsed and interpreted as a JSON text file and is expected to adhere to the JSON syntax.

To see this in action, let's create two configuration files: config.js and config.json. The first - config.js - is what I keep seeing in submitted Node.js code samples:

  • module.exports = {
  • server: "localhost",
  • port: 1234,
  • timeout: 10
  • };

Here, you can see the developer is using the module syntax; but, is really only exposing static configuration data. Now, let's create another file - config.json - which contains truly static configuration data:

  • {
  • "server": "localhost",
  • "port": 1234,
  • "timeout": 10
  • }

Ok, now let's try to read in both of these files using the require() method and log the result out to see what Node.js is doing:

  • // When loading a configuration file, we have the choice to load either .js file,
  • // which will be interpreted as a JavaScript module file, with the "exports" being
  • // returned from the require; or, we can load a .json file, which will be parsed as
  • // JavaScript Object Notation (JSON) with the result being returned from the require.
  •  
  • // Load configuration as JSON.
  • console.log( "JSON File:" );
  • console.log( require( "./config.json" ) );
  •  
  • // Load configuration as module.
  • console.log( "MODULE File:" );
  • console.log( require( "./config.js" ) );

When we run this code, we get the following terminal output

ben$ node explicit-ext.js
JSON File:
{ server: 'localhost', port: 1234, timeout: 10 }
MODULE File:
{ server: 'localhost', port: 1234, timeout: 10 }

As you can see, both approaches - requiring a .js and requiring a .json file - result in the same outcome: exposure of a JavaScript hash of configuration information.

At this point, you might be thinking that being able to require a .json file is nice; but, that you don't want to paint yourself into a "static" corner. Sure, you might start out with static configuration files; but, down the road, you might need to do a little post-read "data massaging."

This is no problem. All we have to do is omit the file extension and Node.js will look for a .js file first and then, if not found, look for a .json file. This means that we can start off using a completely static .json file, move to a .js file later on, and the calling code doesn't have to change at all.

To see this in action, let's try to require() a .json file without an explicit file extension:

  • // When loading a configuration file, we don't have to lock ourselves into a particular
  • // type of file. If we exclude the file-extension, Node will automatically try to look
  • // for a *.js and then, if not found, a *.json file. This means that we can start out
  • // using a .json file; then, if we need to add a programmatic aspect to the config file,
  • // we can transparently change it over to a "module" style file. The take-away here is
  • // that there is absolutely no reason to NOT start out with a .json file if your module
  • // just returns a static hash.
  •  
  • // Load configuration as UNKNOWN file type.
  • // --
  • // NOTE: On disk, it is "config.json". But, we're going to make Node.js look for it.
  • console.log( "UNKNOWN File:" );
  • console.log( require( "./config" ) );

Here, we're using the require() method to read in a file without an obvious file extension, although we do have a .json file on disk. And, when we run this code, we get the following terminal output:

ben$ node implicit-ext.js
UNKNOWN File:
{ server: 'localhost', port: 1234, timeout: 10 }

As you can see, it worked perfectly. This means that we can start out with a .json file. Then, over time, if we needed to make the application configuration more dynamic, we could seamlessly and transparently switch over to using a .js file. Such is the power of the require() method in Node.js.



Looking For A New Job?

Ooops, there are no jobs. Post one now for only $29 and own this real estate!

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader Comments

I have a few things that need to be configured for almost every application I create: loggers, email server, databases, errorhandlers etc and also a few application specific items like application name, port.

I created a node module dvconfigure and published it as an npm private package. It exposes one function which takes the path to two json files (common,and application) and an app object.
I use nconf to grab those config files and attach them to the app object.

When I start an application I just use:

require("@donvawter/dvconfigure")app,__dirname+"/common_config.json",__dirname+"/app_config.json")
.then(....)
.catch(...)

From the command line I often use the require method to validate a json file.
Just get in node REPL with node <ENTER>
and then type
foo=require("./package.json")
If I forgot a comma somewhere I know it immediately.

@Don,

Very interesting! I haven't done too much "production" node.js stuff yet; but, I think our team uses something similarish. I think we have a "core" node module that we sort of use as the bootstrap for all of the applications. It sets up things like what you mention - loggers, mongoDB connectors, etc.

But, I haven't had a chance to really dig into that stuff yet.

I didn't know this and used it the other day when I was testing stuff out in the REPL and had a .json file I wanted to walk through. Definitely saves a few steps requiring the .json file as opposed to requiring fs and reading the file in, especially when messing around in the REPL

On the plus side, using a ".js" file means you don't have to use strict JSON format. Hence:

{
foo: 'blah',
bar: foo + '/blah.html' // this must be an HTML file
}

rather than

{
"foo": "blah",
"bar": "blah/blah.html"
}

Hello, I'm new with this kind of things. I have two files .js running, one on port 3000 and the other on the 4000. The one running on the port 4000 has a json message that I want to receive in the 3000 console.

3000:
... var request = require('request-json');
var client = request.createClient('http://localhost:4000/'); ...

4000:
app.get('/Teste2', function(req, res){
var jsonmsg= {"MSg":"teste"};
res.json(jsonmsg);
})

Can someone give me an advice please?

Ya it is working for .js file.... but in requiring json file to console log it is showing a lot of error. Please suggest if you have any about this. I had followed your all steps but only working for js file.

@Moses,

Without seeing the actual file(s) that you are accessing, I might guess that your json file may not be pure JSON. A reason that I use .js files even for static configuration is that I can add comments.