Why use Node modules?
While figuring out how to make some application work, it’s common to write helper functions and separate blocks of responsibility in the same file. It’s tempting for new developers to continue trying to write out their application using the same patterns from their initial proof of concept. Unfortunately for organization sake this quickly makes the project convoluted and not maintainable. Node modules are a way to separate and organize your code.
When should you abstract code into a module?
- You’re copying and pasting helper functions into different files.
- Common complicated patterns are used repeatedly.
- A 3rd party module implementation is over-complicating your logic.
- You’re using a class or logic that isn’t explicitly tied to the code in the file.
- The size or complexity of a file is becoming overwhelming.
- You want to write tests
- You care about your code and want it to be maintainable.
Splitting your code into modules isn’t just for the server side of things. It’s also extremely useful when building a front-end application. Building your projects with webpack requires intimate use of modules to stay organized.
Require vs Import
Require() is a function in Node that can import either an installed NPM module by module name, or an exported module using a file path.
Import is an ES6 feature for fetching exported functions, objects, and primitives from another file. Browser compatibility is limited at the time of reading this and requires Babel in your build pipeline. To use these natively in node, you’ll have to either run your server code through a build process, or enable harmony modules at run time. I like to use import when building front-end applications, but I stick with require in Node.
In these examples, I’m going to stick with require()
Building a module
Splitting code into a module is easy.
- Create a new file.
- Move code into the new file.
- Organize so that it can be exported as a single object
- set module.exports equal to whatever you want to export.
Here are examples of exporting a function, or an object. Note that you can only have one module.exports per file.
Importing the function into another file is also simple. use require(path) to return the exported variable.
Examples of exporting
Define functions and export their references in a single object. This method makes it very easy to see exactly what is being exported. It also gives you a way to rename the variables.
Define functions and variables in place within the exported object.
Export a class.
You will often find the need to pass options or references to existing objects into modules. If you want to split configuration code that needs a reference to an existing object (like a reference to an app/server object), you can export a generator function. Immediately invoke the result of the required file and pass in your dependencies.
Exported functions have access to the scope of their defining file. Ultility functions and variables can be hidden from the API by defining them out of the exported scope.