# 0.5.1: Node Modules

## Learning Objectives

1. Node Modules define code that can be grouped together and imported from other files
2. How to import and export functions from Node Modules
3. We can only access imported variables and variables defined in the current module
4. Understand the difference between named and default exports

## Introduction

Node Modules (aka ES Modules) define code that can be grouped together and imported from other files. This helps clarify business logic by abstracting implementation details into separate files.

Setting up the environment:

1. Create a new directory named `npm_modules`
2. Change directory to `npm_modules`
3. Run the command `npm init -y` to initialise an npm directory&#x20;
4. You should see a new file has been generated, the package.json
5. To run the scripts you will need to alter this file as below:

```
{
  "name": "npm_modules",
  "version": "1.0.0",
  "description": "modules",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
  }
}
```

Alter this file by adding in a new key and value pair.

```
{
  "type": "module",
  "name": "npm_modules",
  "version": "1.0.0",
  "description": "modules",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
  }
}
```

Now you can run your scrips with node \<scrip-name>

`operations.js` is a Node Module that exports 2 functions: `add` and `subtract`.

{% code title="operations.js" %}

```javascript
export const add = (a, b) => {
  return a + b;
};

export const subtract = (a, b) => {
  return a - b;
};
```

{% endcode %}

`index.js` imports `add` and `subtract` functions from the `operations` module and uses them.

{% code title="index.js" %}

```javascript
import { add, subtract } from "./operations.js";

console.log(add(2, 2));
console.log(subtract(2, 2));
```

{% endcode %}

`conversion.js` is a Node Module that exports functions to convert metric to US units of measurement.

{% code title="conversion.js" %}

```javascript
export const kmToMiles = (numKm) => {
  // Convert KM to miles and return value in miles
};

export const celciusToFahrenheit = (tempInCelsius) => {
  // Convert Celsius to Fahrenheit and return value in Fahrenheit
};

export const kgToPounds = (numKg) => {
  // Convert KG to pounds and return value in pounds
};
```

{% endcode %}

`index.js` imports functions from `conversion` module and uses them without having to worry about implementation details.

{% code title="index.js" %}

```javascript
import {
  kmToMiles,
  celciusToFahrenheit,
  kgToPounds,
} from "./conversion.js";

console.log(kmToMiles(3));
console.log(celciusToFahrenheit(3));
console.log(kgToPounds(3));
```

{% endcode %}

## Module Scope

Node Modules can only access variables explicitly imported or defined in their file. For example, the variable `PI` in the following `circleUtils` module is not accessible in `index.js` because `PI` is not explicitly imported or defined in `index.js`.

{% code title="circleUtils.js" %}

```javascript
const PI = 3.14;

export const getCircleArea = (r) => {
  return PI * (r * r);
};

export const getCirclePerimeter = (r) => {
  return 2 * PI * r;
};
```

{% endcode %}

{% code title="index.js" %}

```javascript
import { getCircleArea } from "./circleUtils.js";

// PI is used "inside" this function
console.log(getCircleArea(2));
// But PI is not accessible as a variable unless explicitly exported and imported
console.log(PI); // Error
```

{% endcode %}

## Named vs Default Exports

There are 2 ways of exporting variables from Node Modules: named and default.

### Named Exports

Named exports allow us to export 0 or more named variables from modules. This is helpful when we want to export more than 1 function from a module.

In the `circleUtils` module, we export `getCircleArea` and `getCirclePerimeter` but not `PI`.

{% code title="circleUtils.js" %}

```javascript
const PI = 3.14;

export const getCircleArea = (r) => {
  return PI * (r * r);
};

export const getCirclePerimeter = (r) => {
  return 2 * PI * r;
};
```

{% endcode %}

In `index.js` we can choose which named exports to import. In this case we only import `getCircleArea`, but we could also import `getCirclePerimeter` if we wanted.

{% code title="index.js" %}

```javascript
import { getCircleArea } from "./circleUtils.js";

console.log(getCircleArea(2));
```

{% endcode %}

### Default Exports

Use default exports when the module only does 1 operation, and all functions in that module exist to support that operation. In general we prefer named exports for clarity of what is exported and imported. Each module can only have 1 default export.

In the `calcHandScore` module, the only function that needs access externally is `calcHandScore`, which we export as a default export.

{% code title="calcHandScore.js" %}

```javascript
const checkFullHouse = (hand) => {
  // Verify if card hand has a full house
};

const checkStraight = (hand) => {
  // Verify if card hand has a straight
};

const calcHandScore = (hand) => {
  let handScore = 0;
  if (checkFullHouse(hand)) {
    // Update handScore for full house
  } else if (checkStraight(hand)) {
    // Update hand score for straight
  }
  return handScore;
};

export default calcHandScore;
```

{% endcode %}

`index.js` imports the `calcHandScore` function, allowing it to calculate the score of a card hand without having to worry about the implementation details of how to calculate it.

Note we do not use curly braces `{}` when importing default exports.

{% code title="index.js" %}

```javascript
// No curly braces around imported default export
import calcHandScore from "./calcHandScore.js";

const hand = ["A", "A", "A", "K", "K"];
const handScore = calcHandScore(hand);
console.log(handScore);
```

{% endcode %}

## Additional Resources

1. [Summary of Node Module usage in 100 seconds](https://youtu.be/qgRUr-YUk1Q)


---

# 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://bc.rocketacademy.co/0-foundations/0.5-node.js/0.5.1-node-modules.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.
