In addition there is also making modules where a module is used as a way to play with a state that is held in the module itself as a local variable to the module which I would not recommend doing. With that said there is also having modules where a public method is used to create a new independent state object that I use outside of the module that created it, and pass the created object as one of the arguments for many of the public methods of the module.
For starters with this kind of approach to modules design you might start out with an object that has an x and y property, and then have a single method that does something to those properties such as move it by a set of given delta values for example.
This way everything is packed into a single global variable, and can be accessed from outside the the module via that single global variable. This approach works okay in some cases assuming that it is okay that everything can be accessed from outside the module, or in other words that everything is public.
There are also ways of creating an API that can be accessed from outside the module as well by assigning such an API to at least one global variable. A global can be declared from outside the function expression, or the global object can be passed as an argument to the IIFE which is another option that I see in the wild a lot. In other cases the expression can just be used to accomplish some things without polluting the global name space at all when it comes to simple projects in which everything needs to be packed into one of these. However maybe getting into all of that is a matter for another post, or at least another section in this one.
A public API can be returned in the form of an object literal when using an IIFE and a single global variable to create a module. This object literal can be the actual thing that is returned to a global variable, or it can be a variable that contains such an object that was declared elsewhere in the body of the function expression, a pattern that I tend to prefer these days.
So for a basic example of this say I have a global variable called mod, and I am using an IIFE to create a module. In the body of the IIFE I am using the return keyword to return an object literal that will function as the public API for the module in the form of a collection of methods attached as properties for the module. These public methods have access to everything that is inside the IIFE and for this example I have a point state object that can be mutated with the public methods.
lets take yet another look at making a very simple point module, this time I am not doing anything that has to do with having the a state object in the module itself, but something that is to be passed as an argument to every public method. This way I am taking the state object out of the module, and making it so that the state object is something that is create and stored in some code section that is outside of the module.
In addition to pulling the state object out of the module, I am now also using a move method that is more in line with the rules of what is often called a pure function. I will not be getting into functional programing in detail here as that is a subject for a whole other post of course. However I have found that going in the direction of functional programing helps to keep things better organized, and easier to follow and debug.
I have wrote a post on the subject of modules in node, however I think that I should at least have a section on the topic here also. The tired yet true way of loading in modules it to use require to do so, but in more modern versions of node the import keyword can be used also. There are a number of useful built in modules to work with which you should take the time to get solid with before learning how to make your own modules. In this section I will then be going over a few quick examples of some built in modules in nodejs, and then be getting into at least one example of making them.
A very useful module to start out with in nodejs might be the path module. This module is packed with useful method that help with resolving absolute paths to resources on a local file system. It will not load those resources as that is the job of another built in module, however if I want to parse an absolute path to a file with a base path and a relative path from the base path this module is what I would want to use.
In nodejs there is also the process object that will contain the cwd method which will return the current working directly. There are also a number of special global variables such as the __dirname variable that is the path to the current file. So in this example I am loading in the path module, and using the path join method to get an absolute path relative to the cwd, as well as the same path as the file.
This module and the use of the join method will come up in additional examples in this section, so I wanted to get this one out of the way first. When it comes to getting the path to a module that I have sored relative to another script in the same folder it is a good idea to use the __dirname global with a relative path to the module and call the path join method to create an absolute path to the module. More on this when I get to the example where I am making my own nodjes module.
Another built in module to start looking into right away would be the file system module. The path module is what I want to use in order to create an absolute path to something. However in order to read, write, or create that something I will need the file system module. In this example I am loading in the file system module, and the path module which I will both use to read and print out the source code of the file itself just for the sake of having something to read.
Now that I have covered the basics of how to go about loading modules in nodejs there is now the question of how to go about loading a custom made module, and how to go about making such a module to begin with. When it comes to making a module I will want to use the exports property of the module object as a way to export what it is that I want to be pubic for the module. When it comes to loading this module the process is mire or less the same as that of the built in modules it is just that now I need to pass a uri to the module when calling require rather than just a name of a built in module.
Thus far I have wrote about a bunch of simple hello world type examples of modules, but I have not got into any kind of real examples. So then in this section I will not be getting into depth about the source code of various modules that I have made over the years, but I will write about a few of them, and link to additional posts in which I get into the source code in detail.
In this post I am writing about a form of a kind of module that I often custom make for each project that I start. That is that when I start a project I often end up with some methods that I do not know where to go with, so I just dump them in some kind of general utility module. In other words it is a kind of custom made lodash library of sorts, backed with stand alone methods that I am actually using in a specific project.
6.3 - A canvas module
In this post I am going over the source code of a canvas module that I have started. The module has at least some of the basic features that I think should a module should have such a layering and having methods that helper with creating and displaying an a collection of 2d points. However at the time of this writing it was still a fairly new module that I have started and many features that such a module should have may still be missing.