In this post I’ll teach you a nifty little trick that you should definitely be using — if you aren’t already — to clean up your JavaScript imports.

I recently made a YouTube video on Sub Rendering React Components which was based off of a blog post that I wrote here. Some cool guy commented on the video because he was being cool by commenting (hint hint, wink wink, nudge nudge). Anyway, shout out to the cool dude who calls himself “Max Equation”. He left this encouraging comment that inspired me to write this blog post:

I’ll talk about integrating TypeScript with ReactJS some other time. But in this post I’d like to address the concept of modularizing JavaScript functions and classes!

What does Modularizing in JavaScript mean?

Well, this is a fancy but simple technique that makes use of the import and export functionality that got shipped with ES6. I use this regularly in my React job but it’s something that can be used in any JavaScript framework.

To explain this concept, we first need run through of how ES6 imports and exports work. Let’s look at an example of a simple stateless functional React component that renders a Header , Content and Footer component. These components are defined in three separate files in a components folder. The components folder is on the same directory level as our simple component that we’ll call MyComponent for demonstration purposes. Here’s our implementation of MyComponent :

import React from 'react';

import Header from './components/header;

import Content from './components/content;

import Footer from './components/footer; const MyComponent = () => (

<>

<Header />

<Content />

<Footer />

</>

); export default MyComponent;

I want to focus on the import section of this component so I’ve kept it really simple. If you’re not familiar with the <>...</> syntax then check out my post about React Fragments.

In the example, the Header , Content and Footer components have a very similar implementation. Let’s focus on the Header component. This Header component is either the default exported function in a file inside the components folder called header.js . Otherwise it’s the default exported function in an index.js file within a folder called header inside the components folder. Okay that was a mouthful… Are you still with me?

Basically the reference to './header' is either a header.js file or an index.js file inside a header folder. Well if you don’t get it now then I’m not sure what else to say. I’ll make a YouTube video in a few days to try explain this. You can subscribe to it using this link.

Exporting default versus Exporting a named function/class

Remember when I said that these imported components are the default export functions of the files that they were exported from? Well, let’s look at the header.js file to see what I mean:

const Header = () => <div>Header</div>; export default Header;

We export default Header; , So when we import it in our main component, we import it like this:

import Header from './components/header';

You don’t always have to export default. However it is a commonly accepted best practice to have one function or class per file and to default export that one function or class. You could also just export the Header function as named export like this:

const Header = () => <div>Header</div>; export Header; // See the 'default' keyword is removed

You can also export it named like this:

export const Header = () => <div>Header</div>;

What does this mean for our implementation of importing Header in the main component? Well, because it’s now a named export, you need to import it using curly brackets like this:

import { Header } from './components/header';

But as I mentioned, it’s recommended to have one class or function per file and that class or function should be default exported.

What’s the point of exporting named functions and classes then?

This is where things get cool. Imagine we were lazy and we decided to not make separate files for our Header , Content and Footer components, #screwbestpractices. What if we just exported all of them as named in an index.js file in our components folder like this example below?

export const Header = () => <div>Header</div>;

export const Content = () => <div>Content</div>;

export const Footer = () => <div>Footer</div>;

Well this is pretty cool, now we can import them in our main component like this:

import { Header, Content, Footer } from './components';

And just for learning purposes, if we did the same thing but exported default Header like this:

const Header = () => <div>Header</div>;

export const Content = () => <div>Content</div>;

export const Footer = () => <div>Footer</div>;

export default Header;

Then we would import it in our main component like this:

import Header, { Content, Footer } from './components';

More little importing and exporting tips:

One last thing. Technically you could import the default exported class as any name you want. For example you could import the same thing like this:

import RandomOtherName, { Content, Footer } from './components';

Or you could name the default export as something else inside the named imports like this:

import { default as Header, Content, Footer } from './components';

That being said, you technically don’t have to name your default export. You could have just default exported your Header component like this:

export const Content = () => <div>Content</div>;

export const Footer = () => <div>Footer</div>;

export default () => <div>Header</div>;

Doing this would still make those importing techniques that I mentioned above work.

Right, I think that’s everything you need to know about importing and exporting JavaScript modules in ES6. But most of these practices aren’t very good when it comes to writing clean and maintainable code. If you’ve read any of my other posts. You’ll know that I’m all about writing clean, readable and maintainable code. So let’s finish off by talking about how we can import and export our components in a clean an efficient manner.

Modularizing Code in Action!

As I’ve been saying over and over again. It’s a commonly accepted best practice to have one file for one function or class. So in our original example where we imported the default exported functions from different files, we were already implementing best practices. It was implemented like this:

import Header from './components/header';

import Content from './components/content';

import Footer from './components/footer';

This is correct, but are you noticing another commonly accepted best practice that we’re neglecting here? If you’re thinking about the term “DRY” then you’d be correct! “DRY” stands of “Don’t Repeat Yourself”. You can probably see a common pattern here. We’re importing multiple functions from the same folder, but they’re in different files. Can we do something here?

If we put all our techniques together with what we have here we can do some magical awesome things! Remember all our functions are in the components folder right? What if keep everything as it is and add an index.js file to our components folder to export all our default functions as named functions in one place? That’s a brilliant idea! And we can do it easily like this:

export { default as Header } from './header';

export { default as Content } from './content';

export { default as Footer } from './footer';

And then you can import them all in the main component like this:

import { Header, Content, Footer } from './components';

This is a much cleaner way of importing and exporting your files in an organized manner. It’s much easier to reference classes and functions using this technique.

Another place where this technique can be used

I find that this trick really comes in handy for splitting many helper functions up into multiple files instead of keeping them all in one file. This makes it easier to find your helper functions when navigating your in your IDE and it’s also much easier to scope your helpers for unit tests.

Conclusion

We’ve covered a lot here and I hope you’ve learnt a lot. If you’ve already known about this technique then I hope you can use this post to teach fellow colleagues and friends.

My inspiration for writing these kinds of posts come from Code Complete: A Practical Handbook of Software Construction, Second Edition. This book has been a catalyst of growth for many developers out there, including myself. If you haven’t got a copy then I highly recommend that you do yourself a favor and get a hold of one!

Anyway! If you liked this post, then leave some likes and claps. And if you’d like keep updated on more of my content, then be sure to follow me on Facebook, Twitter, Medium, YouTube and LinkedIn.

Happy coding!