1. JavaScript
  2. Fundamentals
  3. Modules

JavaScript Modules

Last updated:

A better way to structure code across multiple files.

Enabled via type="module" in the script tag:

<!-- index.html -->
<html>
  <head>...</head>
  <body>
    ...
    <script src="app.js" type="module"></script>
  </body>
</html>

Default Import/Export

Include functions defined in other files:

// app.js
import f1 from './dependency.js';
...
f1();

… where f1 is exported from within the dependency:

// dependency.js
function f1() {
  ...
}
export { f1 as default };

Named Import/Export

An alternative that is usually used when multiple ‘transfers’ are required is using named export & import:

// dependency.js
function f1() {
  ...
}
function f2() {
  ...
}
export { f1, f2};

On import, the names must match the exact names from export (order not relevant):

// app.js
import {f1, f2} from './dependency.js';
...
f1();

Renamed Export

Function can be renamed as part of the export:

// dependency.js
function f1() {
  ...
}
function f2() {
  ...
}
export { f1, f2 as f3};

Now, it’s imported as f3:

// app.js
import {f1, f3} from './dependency.js';
...
f3();

Renamed Import

Function can also be renamed as part of the import:

// dependency.js
function f1() {
  ...
}
function f2() {
  ...
}
export { f1, f2};

Now, it’s imported as f3:

// app.js
import {f1, f2 as f3} from './dependency.js';
...
f3();

Inline exports

The exports can also happen inline for each function that needs it:

// dependency.js
export function f1() {
  ...
}
export function f2() {
  ...
}

Combined imports: Default & Named

Both of the previous methods can be combined for some interesting results:

// dependency.js
function f1() {
  ...
}
function f2() {
  ...
}
export { f1 as default, f2};

Now, the import might look a bit strange:

// app.js
import f1, {f2} from './dependency.js';

Passthrough Exports

Say we have 2 dependencies and we don’t want to have to import both.

Given a second dependency:

// dependency2.js
function f2() {
  ...
}
export { f2 };

We can simply “pass it through” in the first dependency:

// dependency1.js
function f1() {
  ...
}
export { f1 };
export { f2 } from './dependency2.js';

Now app.js will only have to import from one dependency:

// app.js
import {f1, f2} from './dependency1.js';

Import all

A great technique that sames keystrokes on import is the ability to import all functions together.

Given:

// dependency.js
function f1() {
  ...
}
function f2() {
  ...
}
export { f1, f2};

All exports can be imported together, but the usage is slightly different:

// app.js
import * as dependant from './dependency.js';
dependant.f1();