Understanding import and export statements in JavaScript

Understanding import and export statements in JavaScript

Coming from the ReactJS perspective, I'm sure you'd have come across these terms/statements imports and exports in your React codebase (basically, create-react-app) and how they make things work the way they should.

In this article, we're going to see how these statements actually work in "JavaScript".

But first of all, what is a module? because that's basically among the fundamental items we're going to be looking at. For a/an import or export statement to be complete, it has to be fetching/getting data from a module. see the example below.

import React from 'react'

Contents:

What is a module

A module is just a file containing a script (the contents of the script could either be a single block function, an array or multiple arrays, an object, and so on).

The content of a module isn't limited to functions and arrays alone, it can contain class declaration/expressions, string literals etcetera.

Getting access to the functionalities of a particular module now requires us to use these statements, the "import" and "export" statements. The example above, where we imported React from 'react'. "React" in this case, could be a function, an object, or string literal that we're getting access to because we used the import keyword to get the functionality from the module, 'react'.

If you want to see, exactly what React is, you can check the node_modules folder in your app directory and search for "react", you'd see a folder named "react", open it.

The export keyword

The export statement/keyword identifies the variables, functions, or objects that should be accessible outside the current module (the current file).

Let's say we have a module called greetings.js and what we want the module to contain is different types of greet functions

// greetings.js
export function hello(who) {
   alert(`Hello ${who}, it is nice meeting you.`)
}

export function hello(who) {
   console.log(`Hello ${who}, it is nice meeting you.`)
}

We can also export arrays in our module(s)

export let names = ["Wazowski", "Theo", "Jane", "Daniel", "ionware"]

Let's modify the greetings module to have some additional functions too. Instead of having to put the export keyword before every declaration, you can just go ahead to make your function declarations first, then you export all of them.

// greetings.js
...
function helloPlanets(which) {
   console.log(`Hey ${which}, what's popping`)
}

function fullName(firstname, lastname) {
   console.log(`Hey there ${firstname} ${lastname}, How are you?`)
}

export { helloPlanets, fullName }

The import keyword

The import keyword/statement allows you to have access to the functionalities in a particular module to be available outside it.

Recall the first example we saw here? The functions are almost alike. But the difference is, one would be executed in the browser and the other in the console (terminal/node).

Okay, now let's import only the hello function from the greetings module.

// index.js
import { hello } from './greetings.js'

hello('Jack') // Hello Jack, it is nice meeting you.

If you try running the snippet above, you'd get an error saying SyntaxError: Cannot use import statement outside a module. The reason is, you haven't specified that you want the file (i.e greeting.js) to be treated as a module. So to fix that, you have to add a type attribute to your script tag and set it to "module".

<script type="module" src="path/to/module"></script>

To execute this function in your terminal/console, you'd need to have this npm package called esm installed. Once installed, you need to add the -r esm flag after the node keyword.

node -r esm index.js

In some cases where we would want many functions/data from a module, wrapping these functions in curly {...} braces can sometimes be stressful and time-consuming

import { func1, func2, arr1, arr2, obj1, string1, string8 ... } from './module'

This syntax below helps in mitigating the time spent in trying to access all these functionalities.

import * as salutation from './greetings.js'

By using this syntax, we have literally placed all the exported functions in a javascript object, and accessing them wouldn't be an issue, we'd just perform a dot notation operation on them.

const salutation = {
   hello: function hello(who) {
      console.log(`Hello ${who}, it is nice meeting you`)
   },
   helloPlanets: function helloPlanets(which) {
      console.log(`Hey ${which}, what's popping!`)
   },
   fullName: function fullName(firstname, lastname) {
      console.log(`Hey there ${firstname} ${lastname}, How are you?`)
  }
}

What we simply do, when we import the module into our index file is to access each function by the unique keys associated with them.

import * as salutation from './greetings.js'

salutation.helloPlanets("Jupiter") // Hey Jupiter, what's popping!
salutation.fullName("Jane", "Bullish") // Hey there Jane Bullish, How are you?
salutation.hello("people") // Hello people, it is nice meeting you

The default export

The default export is the simplest export to be imported into another module/file, you can export a function, a class, an object, or an array as default in a module.

A module can only contain only one default export statement... Take for example the App component in a react app.

function App() {
   return <h3>default app component</h3>
}

export default App

Conclusion

The explicit definition of functions to be exported from a module, called " named exports", is a very good way to export several values from a module. It helps a great deal when importing such values from the modules, as they would be the same name containing the same value.

import { hello } from './greetings.js' 

import { Hello } from './greetings.js' // this will never work.

Unlike the " default export" where the name that it was exported as could be changed by the developer(s) working on a particular project. Consider this illustration

import LoginButton from './buttons.js' // this would work

import loginButton from './buttons.js' // this too would work.

Most teams prefer to go with named exports, as they name exactly what they import.

Thank you for reading this article. I hope it has helped you understand the topic, if it has, kindly like and share it among your colleagues.