How to Import All Named Exports from a JavaScript File

Abstract image used to represent Import All Exports from a JavaScript File
Image by Andy Li.

In Brief

Use import * as name from './module.js' to group a module's exports on one namespace object. A default export, if present, is available through name.default. Use explicit named imports for individual bindings, and as in the import declaration when you need a different local name.

When import and export statements were introduced into JavaScript as part of the introduction of modules with ES6 in 2015, the way we handle JavaScript development changed in pretty massive ways.

The main bonus, at least for developers was that it allowed for much cleaner and more easily maintainable code to be written because you could split your code into separate files and functions to prevent spaghetti code from forming in one massive, central JavaScript file.

When you're working with export and import, though, there will often be times when you'll want to export multiple functions or variables from a single file and import more than one at a time into another file. So how do we do that?

Well, there are a couple of ways:


Creating a Module Object

If band-functions.js is in the same directory as the importing file, a namespace import looks like this. The ./ makes it a relative file path; a bare name would need a package resolver or other explicit configuration:

import * as band from './band-functions.js';

This creates a module object called band, with each export being accessible as members of that object. You'll be able to access each of the exports like this:

const members = band.getMembers(); 
console.log(members); 
 
const genre = band.getGenre(); 
console.log(genre); 
 
const latestAlbum = band.getAlbum('latest'); 
console.log(latestAlbum); 

This can be handy if you've got a lot of exports that you need to bring in. It's also good for keeping things namespaced, which can help with maintainability and clarity further down the line I'm sure we all know what it's like to come back to a complex codebase after a week off work and feel as though you're looking at somebody else's work!


Individual Named Imports

The other way to do this, which is much more commonly found in the wild, is to name the exports you want. The braces resemble object destructuring, but these are module import declarations: they create readonly live bindings to the exports, rather than copying the current values out of an object.

import { getMembers, getGenre, getAlbum } from './band-functions.js'; 

This is helpful for getting a clear idea of what you're actually importing at a glance at the very top of the file you're working in.

These imports are not set up as a module object, so you don't need to access them as members you just access them straight, like this:

const members = getMembers(); 
console.log(members); 
 
const genre = getGenre(); 
console.log(genre); 

As a pattern, this is my preferred method although it can add a little additional confusion as it removes the 'namespaced' aspect of those imported functions: when looking at the code it isn't always immediately obvious where the function comes from.

Two modules can export the same name. The conflict occurs if you try to declare that name twice in the importing scope, so resolve it in the import declaration itself.

For example, alongside the getMembers import above, add import { getMembers as otherGetMembers } from './other-band-functions.js'; and call otherGetMembers() for the second module. The as keyword chooses the local name; the export in the other file is still called getMembers.


A Note About Default Exports

If the module that you're trying to import from has a default export, you'll have to bear that in mind with both of these methods. With the first method (the module object), you'll be able to access this default export by using the default member, like so:

const bandName = band.default();
console.log(bandName);

This is what the default export will be called, regardless of what the function may be called in the original file. For instance, with the above statement, your export might look like this:

export default function getBandName(id) {
  return name(id);
}

Alternatively, if you're working with explicitly named imports, you'll need to name your default import outside of the brackets check out this example, using the same export function as above:

import getBandName, { getMembers, getGenre, getAlbum } from './band-functions.js'; 
 
const bandName = getBandName(); 
console.log(bandName); 

The Wrap‑up

Ultimately, JavaScript modules are great for keeping your code concise, clear, and clean. If you're not already using them, you should absolutely start; they can seriously help in cutting down the time you spend untangling code!

If you're looking for a howto guide on this functionality from the other side, check out How to Handle Multiple Named Exports in One JavaScript File.


Need a senior engineer involved?

I can work directly in the codebase, review the architecture, or support the team through delivery when the work needs more than extra hands.