loading...
Cover image for JavaScript's Import/Export Business

JavaScript's Import/Export Business

_adam_barker profile image Adam Barker ・3 min read

JavaScript really stepped into the import and export business with ES Modules.

With ES6, the language introduced the import and export keywords allowing easier modularization and organization of code.

The import keyword supports a number of different syntaxes and is often confusing when first thinking about modules.

Hopefully this article can be a concise explanation of each, and to that end we’ll start with a basic module that exports some things we can use.

const name = "Marley";

class Animal {
  numberOfLegs;
  name;

  constructor(name, numberOfLegs) {
    this.name = name;
    this.numberOfLegs = numberOfLegs;
  }
}

function favoriteAnimal() {
  return new Animal("Dog", 4);
}

export { name as default, Animal, favoriteAnimal };

Here we have a module that exports three items: a string, a class and a function.

Notably, the name is just a string but it’s the module’s default export.

Let’s look at the different ways we can import and use the members from this module.


Importing the default export

We can import as much or as little as we need to use from our module. The simplest import brings in the default export: name.

import name from "./module";

// name === "Marley"

‘Name’ is obviously very broad so we can actually rename this import for use in our module.

import dogsName from "./module";

Now, ‘name’, the default export, has been imported with an alias. We can refer to this variable in our importing module using ‘dogsName’;


Import everything and give it a name

We can import everything from our module and we can give everything that comes in a name that we can use to access what was imported.

import * as animalStuff from "./module";

// animalStuff.name === "Marley";
// animalStuff.favoriteAnimal() = 
//    Animal { name: "Dog", numberOfLegs: 4 }

Importing one or more exports by name

In addition to importing the default export or everything, we can specify the names of the exports we’d like explicitly:

import { Animal, favoriteAnimal } from "./module";

This is the first time we’ve seen the curly brackets. These denote that we’re asking for specific members.


Importing specific exports and giving them an alias

In this example we can import named exports but alias them so we can use a different name in our importing module.

import { Animal as Pet, favoriteAnimal } from "./module";

const dog = new Pet(...);

Importing a module to run side-effects

This is a strange use case in that nothing is actually imported. However, any global code you might have in your module is executed.

Suppose for example, you had an additional file that contained the following code in extend.js, responsible for adding a run method to our Animal class:

import { Animal } from "./module";

Animal.prototype.run = function() {
  console.log(`${this.name} is running!`);
};

Nothing is actually exported here, but if we wanted to use the run method in our importing module, we’d need the side-effects import:

import { Animal as Pet } from "./module";
import "./extend";

const dog = new Pet("Marley", 4);
dog.run();

import is a Promise: Dynamic Imports

Using import as a function returns a promise; these use cases are known as Dynamic Imports.

It allows you to conditionally import a module at run-time:

if (weNeedToRun === true) {
    await import("./extend");
}

Hopefully this brief primer into the import syntax has been useful. Check out the official Mozilla docs for import and export for more examples.

Posted on by:

_adam_barker profile

Adam Barker

@_adam_barker

I'm a developer with (way too) many years of experience, originally from the UK but now in NYC having co-founded a real-estate startup and an AI driven content engine platform.

Discussion

pic
Editor guide