Last updated: Mar 6, 2024
Reading timeยท10 min
To import a class from another file in JavaScript:
A
, e.g. export class Employee {}
.B
as import {Employee} from './another-file.js'
.B
.Here is an example of exporting a class from a file called another-file.js
.
// ๐๏ธ named export export class Employee { constructor(name, salary) { this.name = name; this.salary = salary; } increaseSalary() { this.salary += 100; } }
Here is how we would import the Employee
class
in a file called index.js
.
// ๐๏ธ named import import {Employee} from './another-file.js'; const employee = new Employee('Alice', 100); console.log(employee.name); // ๐๏ธ 'Alice' console.log(employee.salary); // ๐๏ธ 100 employee.increaseSalary(); console.log(employee.salary); // ๐๏ธ 200
Make sure to correct the path that points to the another-file.js
module if you
have to.
The example assumes that another-file.js
and index.js
are located in the
same directory.
For example, if another-file.js
was located one directory up, you'd have to
import as import {Employee} from '../another-file.js'
.
named
import.The import/export syntax is called JavaScript modules.
The example above uses a named export and a named import.
The main difference between named
and default
exports and imports is that
you can have multiple named
exports per file, but you can only have a single
default
export.
Let's look at an example of how we would import a class that was exported using a default export.
Here are the contents of another-file.js
.
// ๐๏ธ default export export default class Employee { constructor(name, salary) { this.name = name; this.salary = salary; } increaseSalary() { this.salary += 100; } }
IMPORTANT: If you are exporting a variable (or an arrow function) as a default export, you have to declare it on 1 line and export it on the next.
You can't declare and default export a variable on the same line.
And here is how we would import the class using a default import.
// ๐๏ธ default import import Employee from './another-file.js'; const employee = new Employee('Alice', 100); console.log(employee.name); // ๐๏ธ 'Alice' console.log(employee.salary); // ๐๏ธ 100 employee.increaseSalary(); console.log(employee.salary); // ๐๏ธ 200
Notice that we didn't wrap the import in curly braces.
We could have also used a different name when importing the class, e.g.
FooBar
.
// ๐๏ธ default import import FooBar from './another-file.js'; const employee = new FooBar('Alice', 100); console.log(employee.name); // ๐๏ธ 'Alice' console.log(employee.salary); // ๐๏ธ 100 employee.increaseSalary(); console.log(employee.salary); // ๐๏ธ 200
This works but is confusing and should be avoided.
In my experience, most real-world codebases exclusively use named exports and imports, because they make it easier to leverage your IDE for auto-completion and auto-imports.
You also don't have to think about which members are exported with default
or
named
export.
You can also mix and match. Here is an example of a file that uses both a default and a named export.
// ๐๏ธ default export export default class Employee { constructor(name, salary) { this.name = name; this.salary = salary; } increaseSalary() { this.salary += 100; } } // ๐๏ธ named export export class Person { constructor(name, age) { this.name = name; this.age = age; } increaseAge() { this.age += 1; } }
And here is how you would import the two classes.
// ๐๏ธ default and named imports import Employee, {Person} from './another-file.js'; const employee = new Employee('Alice', 100); console.log(employee.name); // ๐๏ธ 'Alice' console.log(employee.salary); // ๐๏ธ 100 employee.increaseSalary(); console.log(employee.salary); // ๐๏ธ 200 const person = new Person('Bob', 30); person.increaseAge(); console.log(person.age); // ๐๏ธ 31
We used a default import to import the Employee
class and a named import to
import the Person
class.
Note that you can only have a single default export per file, but you can have as many named exports as necessary.
To import a function from another file in JavaScript:
A
, e.g. export function sum() {}
.B
as import {sum} from './another-file.js'
.B
.Here is an example of exporting functions from a file called another-file.js
.
// ๐๏ธ named export export function sum(a, b) { return a + b; } // ๐๏ธ named export export function multiply(a, b) { return a * b; } // (arrow function) // export const sum = (a, b) => { // return a + b; // };
The syntax is the same when using arrow functions. All you have to do is use the
export
keyword.
Here is how we would import the functions in a file called index.js
.
// ๐๏ธ named import import {sum, multiply} from './another-file.js'; console.log(sum(35, 65)); // ๐๏ธ 100 console.log(multiply(5, 5)); // ๐๏ธ 25
Make sure to correct the path that points to the another-file.js
module if you
have to.
The example assumes that another-file.js
and index.js
are located in the
same directory.
For example, if another-file.js
was located one directory up, you'd have to
import as import {sum} from '../another-file.js'
.
named
import.The import/export syntax is called JavaScript modules.
named
or default
export.The example above uses a named
export and a named
import.
The main difference between named and default exports and imports is that you can have multiple named exports per file, but you can only have a single default export.
default
export and a default
importLet's look at an example of how we would import a function that was exported using a default export.
Here are the contents of another-file.js
.
// ๐๏ธ default export export default function sum(a, b) { return a + b; } // (arrow function) // const sum = (a, b) => { // return a + b; // }; // export default sum;
And here is how we would import the function using a default
import.
// ๐๏ธ default import import sum from './another-file.js'; console.log(sum(35, 65)); // ๐๏ธ 100
Notice that we didn't wrap the import in curly braces.
We could have also used a different name when importing the function, e.g.
foo
.
// ๐๏ธ default import import foo from './another-file.js'; console.log(foo(35, 65)); // ๐๏ธ 100
This works but is confusing and should be avoided.
IMPORTANT: If you are exporting a variable (or an arrow function) as a default export, you have to declare it on 1 line and export it on the next.
You can't declare and default export a variable on the same line.
const sum = (a, b) => { return a + b; }; // ๐๏ธ default export export default sum;
You also don't have to think about which members are exported with default
or
named
export.
default
and named
exports and importsYou can also mix and match, here is an example of a file that uses both a default and a named export.
// ๐๏ธ default export export default function sum(a, b) { return a + b; } // ๐๏ธ named export export const multiply = (a, b) => { return a * b; };
And here is how you would import the two functions.
// ๐๏ธ default and named imports import sum, {multiply} from './another-file.js'; console.log(sum(35, 65)); // ๐๏ธ 100 console.log(multiply(10, 10)); // ๐๏ธ 100
We used a default import to import the sum
function and a named import to
import the multiply
function.
Note that you can only have a single default export per file, but you can have as many named exports as necessary.
To import a variable from another file in JavaScript:
A
, e.g. export const str = 'Hello world'
.B
as import { str } from './another-file.js'
.Here is an example of exporting two variables from a file called
another-file.js
.
// ๐๏ธ named export export const str = 'Hello world'; // ๐๏ธ named export export const str2 = 'one two three';
Here is how we would import the variables in a file called index.js
.
// ๐๏ธ named import import {str, str2} from './another-file.js'; console.log(str); // ๐๏ธ "Hello world" console.log(str2); // ๐๏ธ "one two three"
Make sure to correct the path that points to the another-file.js
module if you
have to. The example assumes that another-file.js
and index.js
are located
in the same directory.
For example, if another-file.js
was located one directory up, you'd have to
import as import {str} from '../another-file.js'
.
The syntax we're using to export and import variables is called JavaScript modules.
The example above uses a named
export and a named
import.
The main difference between named and default exports and imports is that you can have multiple named exports per file, but you can only have a single default export.
default
export and a default
importLet's look at an example of how we would import a variable that was exported
using a default
export.
Here are the contents of another-file.js
.
const str = 'Hello world'; // ๐๏ธ default export export default str;
And here is how we would import the variable using a default import.
// ๐๏ธ default import import str from './another-file.js'; console.log(str); // ๐๏ธ "Hello world"
Notice that we didn't wrap the import in curly braces.
We could have also used a different name when importing the variable, e.g.
fooBar
.
// ๐๏ธ default import import fooBar from './another-file.js'; console.log(fooBar); // ๐๏ธ "Hello world"
This works but is confusing and should be avoided.
If you are exporting a variable (or an arrow function) as a default export, you have to declare it on 1 line and export it on the next. You can't declare and default export a variable on the same line.
You also don't have to think about which members are exported with default
or
named
export.
You can also mix and match. Here is an example of a file that uses both a default and a named export.
const str = 'Hello world'; // ๐๏ธ default export export default str; // ๐๏ธ named export export const num = 100;
And here is how you would import the two variables.
// ๐๏ธ default and named imports import str, { num } from './another-file.js'; console.log(str); // ๐๏ธ "Hello world" console.log(num); // ๐๏ธ 100
We used a default import to import the str
variable and a named import to
import the num
variable.
Note that you can only have a single default
export per file, but you can have
as many named
exports as necessary.
To re-export values from another file in JavaScript, make sure to export the
name exports as export {myFunction, myConstant} from './another-file.js
and
the default export as export {default} from './another-file.js'
.
The values can be imported from the file that re-exported them.
Here is an example of a file that has 2 named exports and a default export.
// ๐๏ธ named export export function increaseSalary(salary) { return salary + 100; } // ๐๏ธ named export export const department = 'accounting'; // ๐๏ธ default export export default function multiply(a, b) { return a * b; }
Here is how you would re-export the exported members of another-file.js
from a
file called index.js
.
export {increaseSalary, department, default} from './another-file.js';
The example above directly re-exports the 2 named exports and the default export.
increaseSalary
, department
and the default export in the index.js
file because we haven't imported them, we directly re-exported them.If you have to use the values in the file, you would also have to import them.
// ๐๏ธ import (only if you need to use them in index.js) import multiply, {increaseSalary, department} from './another-file.js'; // ๐๏ธ re-export export {increaseSalary, department, default} from './another-file.js'; console.log(multiply(5, 5)); // ๐๏ธ 25 console.log(department); // "accounting" console.log(increaseSalary(100)); // ๐๏ธ 200
The syntax for re-exporting members of another module is:
// ๐๏ธ re-export NAMED exports export {increaseSalary, department} from './another-file.js' // ๐๏ธ re-export DEFAULT export export {default} from './another-file.js'
The two lines from the example above can be combined into a single line if you're re-exporting members of the same file.
// ๐๏ธ re-export NAMED exports export {increaseSalary, department} from './first-file.js' // ๐๏ธ re-export default export export {default} from './second-file.js'
You could then import the re-exported members from the same module.
// ๐๏ธ default and named imports (all from index.js) import multiply, {increaseSalary, department} from './index.js'; console.log(multiply(10, 10)); // ๐๏ธ 100 console.log(increaseSalary(100)); // ๐๏ธ 200 console.log(department); // ๐๏ธ "accounting"
The pattern you often see is - re-export members of different files from a file
called index.js
. The name index.js
is important because you don't have to
explicitly specify the name index
when importing (in some environments).
'./index.js'
and are not allowed to import from './
.In general, it's better to be explicit and import from './utils/index.js'
,
rather than ./utils
because this syntax is supported in more environments and
is more obvious and direct.
Many of the files you use might make use of multiple utility functions that have
been extracted into separate files, and you might not want to have 5 lines of
imports just for utility functions or constants - this is when re-exporting from
an index.js
file comes in.
You can learn more about the related topics by checking out the following tutorials: