# Modules, Exports, and Require

### Modules:

* Reusable block of code whose existence doesn't accidentally impact other code.
* Code that doesnt affect the rest of the node framework

greet.js

```javascript
var greet = function() {
    console.log('hello');
};

greet();
```

app.js

```javascript
require('./greet.js')
```

commandline

```
node app.js // hello
```

* Tells where to look
* Allows us to individualize files or modules
* Notice that this doesnt allow us to use any of the functionalities in app.js (its not an #include).
  * This is by design by module, the file is protected and self contained.
  * But there is a way to make it available

greet.js

```javascript
var greet = function() {
    console.log('hello');
};

module.exports = greet;
```

app.js

```javascript
var greet = require('./greet.js')

greet();
```

commandline

```
node app.js // hello
```

### How does it really work?

* Modules use the advantages in variable scope within functions / immediately invoked functions.
* Require:
  * Wraps the code you write within a function expression.
  * Everything you write in a node module is wrapped within a function expression
  * Require returns the module that you write.
    * Within your own module, if you've exported anything, you basically are changing back your own module that eventually becomes returned.

### Require more than one object

* Build a new folder than the require that folder, which can contain multiple contents.

app2.js

```javascript
var greet = function() {
    console.log('hello');
};

module.exports = greet;
```

app3.js

```javascript
var greet = function() {
    console.log('hola');
};

module.exports = greet;
```

index.js

```javascript
var english = require("./app2.js");
var spanish = require("./app3.js");

module.exports = {
    english: english,
    spanish: spanish
};
```

app.js

```javascript
var greet = require('./multiple')

greet.english();
greet.spanish();
```

commandline

```
node app.js
// hello
// hola
```

### Incorporating JSON with Require

app2.js

```javascript
var greetings = require("./data.json")

var greet = function() {
    console.log(greetings.en);
};

module.exports = greet;
```

app3.js

```javascript
var greetings = require("./data.json")

var greet = function() {
    console.log(greetings.es);
};

module.exports = greet;
```

```javascript
{
    "en": "Hello",
    "es": "Hola"
}
```

index.js

```javascript
var english = require("./app2.js");
var spanish = require("./app3.js");

module.exports = {
    english: english,
    spanish: spanish
};
```

app.js

```javascript
var greet = require('./multiple')

greet.english();
greet.spanish();
```

commandline

```
node app.js
// hello
// hola
```

## Module Patterns

#### Pattern 1

* We can also do something like

```
module.exports = function(){
  console.log("hello world");
}
```

```
module.exports.greet = function(){
  console.log("hello world!!");
}
```

```
var greet = require("./multiple/app2.js");
greet();

var greet2 = require("./multiple/app3.js").greet;
greet2();
```

```
hello world
hello world!!
```

* Here we're essentially building off the require object that is returned.

#### Pattern 2

app4.js

```javascript
function Greet() {
    this.greeter = "Hello world!!!!";
    this.greet = function () {
        console.log(this.greeter);
    }
}

module.exports = new Greet();
```

app.js

```javascript
var greet3 = require("./multiple/app4.js");
greet3.greet(); // Hello world!!!! 

greet3.greeter = "Changed Hello World";

var greet3b = require("./multiple/app4.js");
greet3b.greet(); // Changed Hello World
```

* Notice that even though we've created a new object, the modifications made to greet3 as an object, affected all subsequent call for newly created objects. The all essentially become the same object.
  * This is because the changes are cached within the require function.

**To Avoid This**

* Simply return the function constructor entirely and avoid creating new objects there

app4.js

```javascript
function Greet() {
    this.greeter = "Hello world!!!!";
    this.greet = function () {
        console.log(this.greeter);
    }
}

module.exports = Greet;
```

```javascript
var greet3 = require("./multiple/app4.js");
var test = new greet3();
test.greet(); // Hello world!!!! 
test.greeter = "Changed Hello World";

var greet3b = require("./multiple/app4.js");
var test2 = new greet3b();
test2.greet(); // Hello world!!!!
```

### Pattern 3

app4.js

```
var greeting = 'hello'

function greet() {
    console.log(greeting);
}

module.exports = {
    greet:greet
}
```

app.js

```
var foo = require("./multiple/app4.js");

foo.greet(); // hello
```

* Why this is useful:
  * greeting is encapsulating within app4.js, and the only thing we export is the greeter function.
  * This means we do not have access to greeting. The variable essentially becomes private to the module - which is good because it wouldn't be a good idea to change it within the application.

## Require Core Native Modules

* There are already modules that are built within node that are native to the functionality of node.js itself. AKA node api.
  * Some are global
  * Others require 'includes'
* All of this can be found within the api documentation for node.js

```javascript
var util = require("util"); // including lib

var name = 'Dan'
var greeting = util.format("Hello, %s", name); // C style
util.log(greeting); // 14 May 16:00:52 - Hello, Dan
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://maksimdan.gitbook.io/javascript/nodejs/modules-_exports-_and_require.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
