Ultimate Guide to Importing in JavaScript

Today, we’ll learn about importing in Javascript. A single file application doesn’t exist. Even if you build smaller applications, importing all the other dependencies can make your code look messy. It will become really hard to find which files are imported, and debugging the code.

Fortunately, we have import and export features in JavaScript.

An Overview of Importing in JavaScript

An import statement in JavaScript is used when you want to import or want to use bindings that exist in some other file or module. This is an ES6 Syntax.

We just cannot have an application written within a single file. Hence, we must export parts of our code and use them in different modules/files by importing them.

It is easier to understand, manage and debug bite-sized and separated code rather than boatloads of it altogether in a single file ending up in a never-ending scroll! That’d be a nightmare!

The core idea behind this import feature is to keep files compact and focus on minimal tasks and components at a time.

Normally, you could be using the ‘require’ module to import files and module.exports to export chunks of your code. Since this is an ES6 Syntax, importing is done via the import statement, and export is done via export default or export statement.

The idea, however, is the same. Moreover, the embedded scripts that you are trying to import, must have a type = ‘module’.

Dynamic import() Function

With the dynamic import() function, you do not need your scripts to be a type = ‘module’.

Dynamic import is used in situations when you want to import a module based on a condition or on-demand.

Import Syntaxes

Below are the many import syntaxes provided by the Official MDN Docs. These vary as per the number of contents we’re importing from a module.

import defaultExport from "module-name";
import * as name from "module-name";
import { export1 } from "module-name";
import { export1 as alias1 } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export1 [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";
const promise = import("module-name");

The parameters used in the above code snippet:

defaultExport

Refers to the name that will indicate the default export from the module.

module-name

Refers to the file/module to import from. This could be a relative or an absolute path of the .js file which will consist of our module. Make sure you only use single or double-quoted strings here.

name

Refers to the name of the module object. This will be more like a namespace when the imports are referred.

exportN

Refers to the specific exports you want to import.

aliasN

Refers to the name of the named imports.

import * as name

This will import all exports from a module.

Clarifying Each Syntax with Examples

Importing Entire Contents of a Module

This will insert sampleModule into the current scope and will contain all the exports from the module in the file located in the path: /modules/sample-module.js.

import * as sampleModule from '/modules/sample-module.js';

In this case, accessing exports refer to using the module name, ‘sampleModule’ in this case, as a namespace. Suppose, sampleModule exports giveMeANumber(), we may then call it like this:

sampleModule.giveMeANumber();

Importing a Single Export from a Module

Let’s say an object or value with the name sampleExport has been exported from sample-module.js module, implicitly (using export * from ‘something.js’) or explicitly (using the export statement), will be inserted into the current scope.

import {sampleExport} from '/modules/sample-module.js';

Importing Multiple Exports from a Module

This will import both carrotRecipes and beetRecipes into the current scope, like this:

import {carrotRecipes, beetRecipes} from '/modules/sample-module.js';

Importing an Export with a More Convenient Alias

With this syntax, you can rename an export while importing it. Let’s have a look at an example:

import {whyIsThisSoLongModuleExportName as cuteName}
  from '/modules/sample-module.js';

Rename Multiple Exports while Importing

With the help of this syntax, we can rename multiple exports while we import, with convenient aliases.

import {
  whyIsThisSoLongModuleExportName as cuteName,
  thisIsStillLongModuleName as short
} from '/modules/sample-module.js';

Importing a Module for its Side Effects

You only want the side-effects of an entire module, but don’t want to import it. You can simply use this way to work it out. This will just run the global code of the module and won’t actually import any values!

import '/modules/sample-module.js';

You may also use it with dynamic imports:

(async () => {
  if (thisIsTrue) {
    // import module just for side effects
    await import('/modules/sample-module.js');
  }
})();

Importing Defaults

You might have a default export such as an object, a class, a function, etc. The import statement will help you import your defaults easily.

The simplest and direct way to import defaults:

import customDefault from '/modules/sample-module.js';

we may also make use of the syntaxes we’ve had a look at a while ago. Make sure you declare the default import first.

import customDefault, * as sampleModule from '/modules/sample-module.js';
// sampleModule shall be used as a namespace

OR

import customDefault, {carrotRecipes, beetRecipes} from '/modules/sample-module.js';
// specific, named imports

When you want to import a default export using dynamic imports, this will be a bit different. You must first destructure the default and rename the “default” key from the returned object.

(async () => {
  if (thisIsTrue) {
    const { default: customDefault, carrotRecipes, beetRecipes } = await import('/modules/sample-module.js');
  }
})();

Dynamic Imports

In situations when you wish to import conditionally or on-demand, you may use dynamic import.

To do this, the import keyword may be called a function. This will then return a promise.

import('/modules/sample-module.js')
  .then((module) => {
    // Your custom function.
  });

This form is also compatible with the await keyword.

const module = await import('/modules/sample-module.js');

Conclusion

A single file application doesn’t exist. When you build even smaller applications, you just cannot type all those thousands of lines of code in one single file!

Fortunately, we have import and export features in JavaScript, which I have discussed in this post.

Noteworthy References

Import in JavaScript – MDN Official Docs

JavaScript Import Statement – AppDividend

Aneesha S
Aneesha S
Articles: 174