neuromancer neuromancer - 7 months ago 35
Javascript Question

What is this Javascript "require"?

I'm trying to get Javascript to read/write to a PostgreSQL database. I found this project on github. I was able to get the following sample code to run in node.

var pg = require('pg'); //native libpq bindings = `var pg = require('pg').native`
var conString = "tcp://postgres:1234@localhost/postgres";

var client = new pg.Client(conString);
client.connect();

//queries are queued and executed one after another once the connection becomes available
client.query("CREATE TEMP TABLE beatles(name varchar(10), height integer, birthday timestamptz)");
client.query("INSERT INTO beatles(name, height, birthday) values($1, $2, $3)", ['Ringo', 67, new Date(1945, 11, 2)]);
client.query("INSERT INTO beatles(name, height, birthday) values($1, $2, $3)", ['John', 68, new Date(1944, 10, 13)]);

//queries can be executed either via text/parameter values passed as individual arguments
//or by passing an options object containing text, (optional) parameter values, and (optional) query name
client.query({
name: 'insert beatle',
text: "INSERT INTO beatles(name, height, birthday) values($1, $2, $3)",
values: ['George', 70, new Date(1946, 02, 14)]
});

//subsequent queries with the same name will be executed without re-parsing the query plan by postgres
client.query({
name: 'insert beatle',
values: ['Paul', 63, new Date(1945, 04, 03)]
});
var query = client.query("SELECT * FROM beatles WHERE name = $1", ['John']);

//can stream row results back 1 at a time
query.on('row', function(row) {
console.log(row);
console.log("Beatle name: %s", row.name); //Beatle name: John
console.log("Beatle birth year: %d", row.birthday.getYear()); //dates are returned as javascript dates
console.log("Beatle height: %d' %d\"", Math.floor(row.height/12), row.height%12); //integers are returned as javascript ints
});

//fired after last row is emitted
query.on('end', function() {
client.end();
});


Next I tried to make it run on a webpage, but nothing seemed to happen. I checked on the Javascript console and it just says "require not defined."

So what is this "require?" Why does it work in node but not in a webpage?

Also, before I got it to work in node, I had to do
npm install pg
. What's that about? I looked in the directory and didn't find a file pg. Where did it put it, and how does Javascript find it?

Answer

require() is not part of your standard JavaScript. In context to your question and tags, require() is built into Node.js to load modules. The concept is similar to C/Java/Python/[insert more languages here] imports or includes.

The concept of modules is similar to just adding small bits of JavaScript code via a <script> tags. Unlike adding a <script> tag, it doesn't leak the file into the global scope. The file has its own scope, essentially trapping everything you define in that file, unless you decide to expose functionality. require returns a value, depending on what the module exposes using exports or module.exports. Another post explains how require() works in conjunction with exports.

In your code, it loads the pg module, which I guess is a PostgreSQL driver for NodeJS. The part where you do npm install pg downloads the pg module from npm (a package repository for NodeJS modules) and makes it available to your project via require('pg');.


Just in case you were wondering why I mentioned "in context to your question", there are 3rd-party libraries that also use a function named require to do something. It's handy to identify which is which.

  • RequireJS exposes a function called require, along with define to load dependencies before running the code provided. The syntax is in AMD format.

  • Neuter, which concatenates js files, also exposes a function named require. This one acts much closer to PHP's import.

  • Browserify uses require on the browser, allowing scripts on the browser to be written NodeJS style (CommonJS module syntax).