The import
and export
statements are one of the most crucial features of JavaScript ES6.
Also known as the EcmaScript Modules (ESM) syntax, it allows you to import and export JavaScript classes, functions, components, constants, any other variables between one JavaScript file and another.
This feature allows you to organize your JavaScript code into small, bite-size files. Making it easier to share, improve, manage, and debug your code as the development phase requires.
This tutorial will help you learn how to export
JavaScript modules, and then how you can import
those exported modules.
How JavaScript export works
You can use a JavaScript export
statement to export any JavaScript variable, function, or class. There is no limit to how many times you can export modules in one JavaScript file:
// example.js
export const user = 'John'
export let days = ['Monday', 'Tuesday', 'Wednesday']
export var countries = ['United States', 'United Kingdom']
export function sayHi() {
console.log('Hello World!')
}
export const greet = name => {
console.log('Hello ' + name + '!')
}
export class User {
constructor(username){
this.username = username
}
}
All of these exports are valid.
Multiple exports in a separate line
The example above can be used to export multiple modules, but you can also export modules in a separate line by using the export { .., .., .. }
syntax:
const user = 'John'
let days = ['Monday', 'Tuesday', 'Wednesday']
var countries = ['United States', 'United Kingdom']
function sayHi() {
console.log('Hello World!')
}
const greet = name => {
console.log('Hello ' + name + '!')
}
class User {
constructor(username){
this.username = username
}
}
export {user, days, countries, sayHi, greet, User}
Notice how user
and User
could be used in one file without any error. JavaScript is case-sensitive, so it treats them as separate variables.
How JavaScript import works
There are multiple ways to import a module in JavaScript. First, you can import specific modules by using the import { .. } from ..
syntax:
import { user, days, countries } from './example'
The from
keyword will tell JavaScript which file to look for the modules. Alternatively, you can import code and run it immediately by omitting the variable name and directly importing the file:
import './example'
sayHi();
Since the entire example.js
code is executed with the import
statement, you can call the sayHi()
function immediately after that.
Named export and import variables
You can rename exported variables with the as
keyword:
export { greet as greetings, user as myUser }
// you need to import with the new names
import { greetings, myUser } from './example'
And the same can be done with imports:
export { greet, user }
import { greet as greetings, user as myUser } from './example'
Default export and import
When you have only one module to export, you can use the export default
statement:
export default class User {
constructor(username){
this.username = username
}
}
// or
class User {
constructor(username){
this.username = username
}
}
export default User
Unlike regular imports, a default import doesn’t use curly braces {}
to wrap its modules:
import User from './example'
Instead of using the default
keyword, default import simply write a variable name followed by from
statement.
Also, the variable name you declared for default import doesn’t need to match the export default
variable name:
class User {
constructor(username){
this.username = username
}
}
export default User
// can be imported like this
import usr from './example'
The example above will be understood as import User as usr
by JavaScript.
@ symbol in JavaScript import statements
As you code and collaborate with others through GitHub and any other medium, you might find some open source code using @
symbol in their import .. from ..
syntax like this:
import Button from '@/components/Button'
// or
import Button from '~/components/Button'
The @
and ~
symbols are custom module loaders that are not part of JavaScript standard specification. Most likely, your project has a configuration file that can understand the symbols when you compile your code (usually through Babel or Webpack).
For example, babel-plugin-root-import treats the symbol as the root path, so you can write @/components
instead of ../../components
.
Note that this is different from npm scoped packages, which also use @
before the package name
Summary
In JavaScript, you can export modules in three different ways:
- by placing the
export
statement before the module:export const ..
syntax - Or in a separate line:
export { a, b, c}
- You can also specify a default export with
export default ..
- And named export with
export {xyz as abc}
Then you can also import these modules as:
- An import all with
import * as x from ..
syntax - A default import with
import x from ..
- Multiple import with
import {x, y, z} from ..
- Named import with
import { x as c } from ..
- Run import code immediately with
import 'x'
JavaScript is case-sensitive, so you might have x is not defined
error if you have a mismatch between your import and export statement.
One of the most common example of this is when React library has ReactDOM is not defined
error.
And that’s how JavaScript ESM syntax works.