What Is This JavaScript "Require"

What is this JavaScript require ?

So what is this "require?"

require() is not part of the standard JavaScript API. But in Node.js, it's a built-in function with a special purpose: to load modules.

Modules are a way to split an application into separate files instead of having all of your application in one file. This concept is also present in other languages with minor differences in syntax and behavior, like C's include, Python's import, and so on.

One big difference between Node.js modules and browser JavaScript is how one script's code is accessed from another script's code.

  • In browser JavaScript, scripts are added via the <script> element. When they execute, they all have direct access to the global scope, a "shared space" among all scripts. Any script can freely define/modify/remove/call anything on the global scope.

  • In Node.js, each module has its own scope. A module cannot directly access things defined in another module unless it chooses to expose them. To expose things from a module, they must be assigned to exports or module.exports. For a module to access another module's exports or module.exports, it must use require().

In your code, var pg = require('pg'); loads the pg module, a PostgreSQL client for Node.js. This allows your code to access functionality of the PostgreSQL client's APIs via the pg variable.

Why does it work in node but not in a webpage?

require(), module.exports and exports are APIs of a module system that is specific to Node.js. Browsers do not implement this module system.

Also, before I got it to work in node, I had to do npm install pg. What's that about?

NPM is a package repository service that hosts published JavaScript modules. npm install is a command that lets you download packages from their repository.

Where did it put it, and how does Javascript find it?

The npm cli puts all the downloaded modules in a node_modules directory where you ran npm install. Node.js has very detailed documentation on how modules find other modules which includes finding a node_modules directory.

Functionality of require() in nodeJS

require returns whatever the module defined. Sometimes, the module defines a single function:

exports = function request(/*...*/);

...and so when you import the module, that's what you get.

Sometimes, modules export objects (exports refers to a blank object initially when the module is loaded, and then modules add to or replace that object):

exports._ = {
// ...
};

...and so when you import the module, that's what you get.

It's up to the module. It's a very simple system. More in the Modules documentation (not to be confused with the ECMAScript (JavaScript) Modules documentation; JavaScript's own modules work slightly differently from Node.js's).

What happens when using require() in Node.js?

It's just loading a library or a module into your script. It is not instantiating a new object. It's just making the loaded module's functions etc available to your current script. Here is a good writeup that I found,
http://fredkschott.com/post/2014/06/require-and-the-module-system/
I hope that helps answer your question.

what is use of require('.') in node.js

It will import index file in the folder where you are running your file will empty require statement. Javascript require module will try to find index.js file if you do not specify any file name(only provide folder reference) in the require() argument.

Basically it's an alias for const foo = require('./index.js');

index.js

module.exports = 1;

foo.js

const foo = require('.');
console.log({ foo });

If both files are in the same folder then it will print

{ foo: 1 }

What does require() actually return, the file or the function

The require(...) function returns the module.exports value from the "required" module, and in the case its the Profile function.



As an aside, I have no idea what "return the file" or "the Profile is the profile.js itself" means.

When to use import and when to use require in Node.JS

Summary

import is the future of the Javascript language in both nodejs and the browser and is used in ECMAScript modules (ESM modules) for loading other modules, either statically or dynamically.

require() is the original way that nodejs loaded modules and is used in CommonJS modules. require() is natively supported in nodejs, but not in browsers (though there are some 3rd party libraries that have require-like module loaders for the browser).

Pick One

You will generally want to pick one mechanism and use it for your whole project as it complicates things to mix/match. import had some growing pains for awhile in nodejs, but the implementation is fairly complete now. Either way, you will probably run into some modules that are not of the type you chose for your project and will have to learn how to deal with that.

If I was starting a new project that I expected to last awhile and be working on it for years, I would pick ESM modules with import as that is the present/future architecture for modules in Javascript.

If I was writing a quick "get it done" kind of script that relied on a bunch of scripts that are only available in CommonJS, I would probably use CommonJS require().

If I was writing modules I wanted to share between nodejs and browsers, I'd pick ESM because it is supported in both.

Your Questions

When I look at the documentation for Node.JS for the file system "fs" module it doesn't make any mention of doing the const fs = require('fs); instead it talks about using the import method import { mkdir } from 'fs'

The current version of the fs documentation lets you pick whether you want the code examples to show CJS or ESM module syntax. You were apparently looking at the doc when it was showing ESM syntax. You can switch it. Either will work.

When you see this image Sample Image in the documentation, that lets you toggle the sample code in the doc from CJS to ESM or back.

SyntaxError: Cannot use import statement outside a module

In nodejs, you have to tell nodejs in some way whether your top level module is CJS or ESM. By default, a .js file is treated as CJS and an .mjs file is treated as ESM. If nodejs thinks you have a CJS file, you cannot use import (that is only for ESM modules).

You can also modify the package.json file that controls your particular script (by adding "type": "module" and force your file to an ESM module if you want (which allows you to use .js files as ESM modules).

Using const fs = require('fs'); works just fine

Yes, if nodejs thinks you are using a CJS module.

I want to make sure my code is consistent/correct so which one do I use and why?

See my previous explanation for when I'd choose each module type. If you are just learning, I would suggest you learn how to tell nodejs you're using ESM modules and use import since that is the future direction of the language. require() isn't going to go away anytime soon, but I would not be surprised if we start to see new NPM packages (shareable modules) that only support the newer ESM syntax and can only be loaded from ESM modules. It is possible (with some careful work) to make a shareable module that can be loaded by either an ESM module or a CJS module.

Also, ESM modules are getting some features (such as top-level await) that CJS modules will never get.

More Details

For more details, I suggest reading this article:

Node Modules at War - Why CommonJS and ESM Modules Can't Get Along



Related Topics



Leave a reply



Submit