A great program is always divided into modules. But what do we call a module ? A module is just few lines of code, that can be called upon to do some action . A good module is highly self contained, with it’s precise functionality. It should be easy to add, shuffle or delete, without affecting the functionality of the whole.
But what makes a modular program a great program ?
MaintainabilityA modular project is easy to maintain. If you want to make some changes, you have to update the relevant module of the program. And this won’t affect the whole program. You don’t have to update each and every file in the project to implement a small thing. This makes a developer’s live super easy.
ReusabilityIn any non-modular project, you can see lot’s of code copy pasted and repeated. In a modular project, following the DRY (Don’t repeat yourself) principle becomes easy. Whenever you feel like a chunk of code can be generalized and used at multiple locations, create a module for that and use it everywhere.
Cleaner Global spaceIn a modular, most of the variables are private and are not accessible in the global namespace. This helps us in keeping our global namespace cleaner and hence less buggy code.
How to make your program modular in JS ?
Enter module bundlers
When you write modular code, you have to organize them in separate files. We cannot serve these many files to the final user. A tool is required to ‘concatenate’ all your modules into one single file. Hence our number of requests would be reduced drastically. But there are lot more optimizations can be done to improve performance. Like dead code removal, minification etc.
There are different types of module bundlers. For commonJs, we have browserify, for AMD modules we have requireJs.
Webpack is a new bundler in the town. It allows users to bundle not just commonJs and AMD modules, but also ES6 modules. Other than this, it also provides many great features like code-splitting and hot reloading. One of the best features that we will be using is that webpack can load almost everything like a js module. Be it be css, sass, images or even fonts.
But why would we want to load files like css, sass or images as modules. Scroll up and read what a good module should be. A “Highly self contained” module should have it’s images and css as it’s dependencies, just like other modules as it’s dependencies.
Slowly we are overlapping the difference between a module and a React component. But shouldn’t every component have all the qualities that a great module has ? It should be self-contained, easy to add, or delete.
Shaping our directory structure
Finally after understanding what a great component/module should be, we can finally shape our directory structure.
There are usually three types of dependencies for a web module:
Usually we used to handle this by creating three folders in our app directory.
But as the project grows, the number of files increases. When we have to remove / change a page, we need to find three files on three different folders. Which is a pain for any new dev. Also the problem increases if same CSS file is being used by two different HTML files.
So earlier if you used to do:
Which becomes much cleaner and maintainable.
Now this helps in making a much better folder structure. Which is:
/src /components /component1 component1.jsx // the template component1.css // the template's css file component1Logo.png // the image required for this module /component2 component2.jsx component2.css myImage.png
If you see now, if you want read a component, you can get all it’s stuff that in that same folder. This makes our code super easy to understand and browse. If you want to remove some component, just delete that folder and all the references to that module in the code. And that module is removed from the system without any effect on rest of the project.
But what about the common static files ? If many modules require the same image file / css, we cannot add it in each and every module’s folder.
Files that needs to be shared between the components, should be kept in a static folder
/src/static . So the new structure looks like this:
/src /components /component1 /component2 /static /css /images /fonts
In this way, no files will be repeated, also deleting a module won’t affect other modules. That’s sweet. But how do you structure things like
webpack config ?
Every project has a bunch of parameters that are being used across the app and shouldn’t be committed in the code. For example GA id or maybe new-relic key. These needs to be added in a folder
So it’ll be something like this :
/app /components /config config.js
When building a universal app, we need two builds, one for the server and one for the browser. Two builds also means tw different configs for webpack. Hence the
/webpack directory has both the config files.
Here now we have a basic structure of a React app. This helps in better code readability, maintainability and above all, promotes writing modular code.