# 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
```
