--- tags: - Programming_Languages - backend - node-js - node-modules --- # Modules > 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. * 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. ```js // index.js console.log(module) ``` This gives us: ```plaintext 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'  ] } ``` ## 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* ```js module.exports = () => { foo() {...} bar() {...} } ``` *Export an object* ```js module.exports = { foo : () => {...}, bar: () => {...} } ``` **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. ```js export default class { foo() {} bar() {} } ``` Every method and property within the export will be public by default, whether it is an object, class or function. If you wanted to keep certain methods/properties private, the best approach is to define them as variables and functions within the module file but outside of the `export` block.