2022-04-23 13:26:53 +01:00
---
tags:
- Programming_Languages
- backend
- node-js
- node-modules
---
2022-08-01 19:30:05 +01:00
# Modules
2022-04-23 13:26:53 +01:00
2022-08-01 19:30:05 +01:00
> Modules are partitioned files where we define our variables and functions. Values defined in modules are scoped to that specific module, constituting a unique name space. This avoids name clashes in large programs.
2022-04-23 13:26:53 +01:00
* Every file in a Node application is considered a module.
* The variables and methods in a module are equivalent to `private` properties and methods in object-oriented programming.
* If you wish to use a function or variable defined in a module outside of its modular container you need to explicitly export it and make it public.
## Structure of a module
Node keeps an internal record of the properties of a module. To see this we can log the property `module` to the console.
2022-08-01 19:30:05 +01:00
```js
2022-04-23 13:26:53 +01:00
// index.js
console.log(module)
2022-08-01 19:30:05 +01:00
```
2022-04-23 13:26:53 +01:00
This gives us:
2022-08-01 19:30:05 +01:00
```plaintext
2022-04-23 13:26:53 +01:00
Module {
id: '.',
path: '/home/thomas/repos/node-learning',
exports: {},
filename: '/home/thomas/repos/node-learning/index.js',
loaded: false,
children: [],
paths: [
'/home/thomas/repos/node-learning/node_modules',
'/home/thomas/repos/node_modules',
'/home/thomas/node_modules',
'/home/node_modules',
'/node_modules'
]
}
2022-08-01 19:30:05 +01:00
```
2022-04-23 13:26:53 +01:00
## Exports
* Whenever we export a property or method from a module we are directly targeting the `exports` property of the module object.
* Once we add exports to a file they will be displayed under that property of the module object.
* We can export the entire module itself as the export (typically used when the module is a single function or class) or individual properties.
### Exporting a whole module
*The example below is a module file that consists in a single function*
````js
module.exports = function (...params) {
// function body
}
````
Note the module is unnamed. We would name it when we import:
````js
const myFunction = require('./filenme')
````
### Exporting sub-components from a module
In the example below we export a variable and function from the same module. Note only those values prefixed with `exports` are exported.
````js
exports.myFunc = (...params) => {
// function bod[]()y
}
exports.aVar = 321.3
var nonExportedVar = true
````
This time the exports are already name so we would import with the following:
````js
const { myFunc, aVar } = require("./filename");
````
We can also do the exporting at the bottom when the individual components are named:
````js
const myNamedFunc = (val) => {
return val + 1;
};
function anotherNamedFunc(val) {
return val * 2;
}
// This time we export at the bottom
exports.myNamedFunc = myNamedFunc;
exports.differentName = anotherNamedFunc; // We can use different names
// Or we could export them together
module.exports = { myNamedFunc, anotherNamedFunc };
````
The import is the same:
````js
const { myNamedFunc, anotherNamedFunc } = require("./modules/multiExports");
````
## Structuring modules
The techniques above are useful to know but generally you would want to enforce a stricter structure than a mix of exported and private values in the one file. The best way to do this is with a single default export.
Here the thing exported could be a composite function or an object that basically acts like a class with methods and properties.
*Export a composite single function*
2022-08-01 19:30:05 +01:00
```js
2022-04-23 13:26:53 +01:00
module.exports = () => {
foo() {...}
bar() {...}
}
2022-08-01 19:30:05 +01:00
```
2022-04-23 13:26:53 +01:00
*Export an object*
2022-08-01 19:30:05 +01:00
```js
2022-04-23 13:26:53 +01:00
module.exports = {
foo : () => {...},
bar: () => {...}
}
2022-08-01 19:30:05 +01:00
```
2022-04-23 13:26:53 +01:00
**Both of these structures would be referred to in the same way when importing and using them**
Or you could export an actual class as the default. This is practically the same as the two above other than that you would have to use `new` to initiate an instance of the class.
2022-08-01 19:30:05 +01:00
```js
2022-04-23 13:26:53 +01:00
export default class {
foo() {}
bar() {}
}
2022-08-01 19:30:05 +01:00
```