Exporting and Importing Using ES6 Modules

Hero image for Exporting and Importing Using ES6 Modules. Image by Pawel Czerwiński.
Hero image for 'Exporting and Importing Using ES6 Modules.' Image by Pawel Czerwiński.

In JavaScript, a module is simply a reusable piece of code that can be imported and used in other parts of your code. This makes it easier to organise your code into smaller, more manageable pieces and allows you to share code between different parts of your application.

Before the introduction of modules in ES6, developers had to rely on various techniques like Immediately Invoked Function Expressions (IIFE), CommonJS, and AMD to achieve modularity. However, with the introduction of modules in ES6, developers can now use a standardised and more convenient way of organising and sharing code.


Exporting Modules

In order to make a module available for use in other parts of your code, you need to export it. In JavaScript, you can export any object, function, or variable by adding the export keyword before it. For example:

// maths.jsexport function add(a, b) {  return a + b;}


This is a very basic example where we've defined a function called add, and then used the export keyword to make it available for use in other parts of our application. You can also use the export keyword to export multiple objects, functions, or variables from the same module:

// maths.jsexport function add(a, b) {  return a + b;}export const pi = 3.1416;

Now our maths.js file has two available exports: the add function, and the constant pi, both exported from the same module.


Importing Modules

Now that we have some exports available in maths.js, it's time to import them and put them to use in another part of the application. We achieve this using the import keyword. For example, importing our add function from the example above would look something like this:

// app.jsimport { add } from './math.js';console.log(add(2, 3));  //=> 5

Here we've imported the add function from our math module and used it to add 2 and 3 together. Note that we've specified the path to our math module using a relative path ('./math.js'). You can also import multiple objects, functions, or variables from the same module:

// app.jsimport { add, pi } from './math.js';console.log(add(2, 3));  //=> 5console.log(add(2, pi));  //=> 5.1416

Now, we've imported both the add function and the pi constant from our math module, and used them both.


Default Exports

Whilst you can explicitly name your exports, you can also export a single default value from a module using the export default syntax:

// math.jsexport default function add(a, b) {  return a + b;}

Now, we've defined a function add and used the export default syntax to make it the default export of our math module. You can then import a default export using any name you want, like this:

// app.jsimport addFunction from './math.js';console.log(addFunction(2, 3));  //=> 5

Here, we've imported the default export from our math module and given it the name addFunction. As you might have noticed, there's no need for curly braces ({}) when importing a default export. Admittedly, it is unlikely that you would want the default import from a module called maths to be addition, but it serves well for example purposes.


Mixing Named and Default Exports

You can of course also mix named and default exports in the same module. Here's an example:

// math.jsexport function add(a, b) {  return a + b;}export default function multiply(a, b) {  return a * b;}

This time around we've exported both a named function (add) and a default function (multiply) from our math module. These can be imported and used like this:

// app.jsimport multiplyFunction, { add } from './math.js';console.log(multiplyFunction(2, 3));  //=> 6console.log(add(2, 3));  //=> 5

Issues with Modules


Whilst modules are a powerful and convenient feature of ES6, there are some potential issues you may come across when working with them. Here are a few of the more common ones:

Browser Compatibility

Not all browsers support ES6 modules (yet), so if you want to use them in your application you may need to use a bundler like webpack or Rollup to compile your code into a format that browsers can understand. As with any recent addition in frontend development, it takes time for the browsers to catch up.

Circular Dependencies

If you have two or more modules that depend on one other, you may run into circular dependency issues. This can happen when Module A depends on Module B, but Module B also depends on Module A. To avoid this, try to organise your code in a way that avoids circular dependencies, or use a module loader that can handle them.

Naming Conflicts

If you're importing multiple modules that have objects or functions with the same name, you may run into naming conflicts. To avoid this, try to give your objects and functions unique names, or use namespace objects to group related objects and functions together.

You can also rename when importing from a module using the as keyword:

import { pi as piNumber } from './maths.js';

Here we import the pi constant from maths.js but also renamed it to piNumber. This will avoid conflicts you have another constant called pi in this particular area of your application, but really you would be better off refactoring one or the other to avoid confusion.


The Wrapup

Modules are a powerful and convenient way to organise and share code in JavaScript. By using named exports, default exports, and a combination of both, you can easily create reusable pieces of code that can be imported and used in other parts of your application. While there are some potential issues you may come across when working with modules, these can be easily overcome with a bit of planning and organisation. With modules, you can write cleaner, more modular code that's easier to maintain and share with others.


Categories:

  1. ES6
  2. Front‑End Development
  3. JavaScript