JavaScript tutorials > Object-Oriented JavaScript > Encapsulation and Modules > How do you use export and import in JavaScript?
How do you use export and import in JavaScript?
This tutorial explains how to use export
and import
in JavaScript to create modular and reusable code. We'll cover different types of exports, importing specific members, aliasing, and best practices for organizing your JavaScript projects.
Introduction to ES Modules
Before ES Modules, JavaScript relied on script tags and other module systems like CommonJS (used in Node.js) or AMD. ES Modules, introduced in ES6 (ECMAScript 2015), provide a standardized way to organize and share JavaScript code. They offer better performance, reusability, and maintainability compared to traditional methods.
Named Exports
Named exports allow you to export multiple functions, variables, or classes from a module. Each export has a name, and you can import these names individually. In the math_functions.js
file, we export two functions, add
and subtract
. In app.js
, we import only the functions we need, explicitly specifying them within curly braces.
/* math_functions.js */
export function add(x, y) {
return x + y;
}
export function subtract(x, y) {
return x - y;
}
/* app.js */
import { add, subtract } from './math_functions.js';
console.log(add(5, 3)); // Output: 8
console.log(subtract(5, 3)); // Output: 2
Default Exports
Default exports allow you to export a single value from a module. This could be a function, a class, an object, or any other JavaScript value. Unlike named exports, you don't use curly braces when importing a default export, and you can choose any name you like for the imported variable. In the my_module.js
file, we export myVariable
as the default export. In app.js
, we import it as myVar
.
/* my_module.js */
const myVariable = 42;
export default myVariable;
/* app.js */
import myVar from './my_module.js';
console.log(myVar); // Output: 42
Combining Named and Default Exports
You can combine both named and default exports within a single module. This is useful when you have a primary value to export (default) along with additional utilities or constants (named exports). In utils.js
, we export PI
as the default export and formatDate
as a named export. In app.js
, we import both, using the correct syntax for each type of export.
/* utils.js */
export function formatDate(date) {
return date.toLocaleDateString();
}
const PI = 3.14159;
export default PI;
/* app.js */
import PI, { formatDate } from './utils.js';
console.log(PI); // Output: 3.14159
console.log(formatDate(new Date())); // Output: (current date in local format)
Importing All Named Exports with *
You can import all named exports from a module into a single object using the * as
syntax. This is useful when you want to access multiple named exports without explicitly listing them all. In helpers.js
, we have two named exports: capitalize
and reverseString
. In app.js
, we import all of them into the helpers
object. We can then access each function using dot notation (e.g., helpers.capitalize
).
/* helpers.js */
export function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
export function reverseString(str) {
return str.split('').reverse().join('');
}
/* app.js */
import * as helpers from './helpers.js';
console.log(helpers.capitalize('hello')); // Output: Hello
console.log(helpers.reverseString('world')); // Output: dlrow
Aliasing Exports and Imports
You can rename exports and imports using the as
keyword. This is helpful when you want to avoid naming conflicts or use more descriptive names in your current module. In api.js
, we export getData
as fetchData
. In app.js
, we import fetchData
as getApiData
.
/* api.js */
function getData() {
// ... fetch data from API ...
return 'Data from API';
}
export { getData as fetchData };
/* app.js */
import { fetchData as getApiData } from './api.js';
console.log(getApiData()); // Output: Data from API
Dynamic Imports
Dynamic imports allow you to load modules asynchronously, on demand. This can improve performance by only loading the code that's needed when it's needed. Dynamic imports return a promise that resolves to the module's exports. Dynamic imports are especially useful for lazy-loading modules or loading modules based on user interactions or conditions. This is the only way to import modules in non-module environments.
async function loadModule() {
const module = await import('./my_dynamic_module.js');
module.myFunction();
}
loadModule();
concepts behind the snippet
The key concepts behind export
and import
are:
Real-Life Use Case Section
Consider a large web application with numerous features. Using export
and import
can help organize the codebase into separate modules for each feature (e.g., user authentication, product catalog, shopping cart). Each module can export its specific functions, classes, or components, which can then be imported and used by other modules as needed. This makes the application easier to develop, test, and maintain.
Best Practices
Interview Tip
When discussing export
and import
in an interview, be sure to demonstrate your understanding of the different types of exports, how to import them, and the benefits of using ES modules for code organization and maintainability. Explain the difference between named and default exports, and when to use each one. Also, be prepared to discuss module bundlers and their role in optimizing JavaScript code for production.
When to use them
Use export
and import
in JavaScript when you want to:
Memory footprint
ES modules can help reduce the memory footprint of your application by only loading the code that's needed. Module bundlers can also perform tree shaking, which eliminates unused code from your bundle. Dynamic imports can further reduce the initial load time and memory usage by loading modules on demand.
alternatives
Alternatives to ES Modules (though generally not recommended for modern projects) include:
window
object (not recommended due to potential naming conflicts and lack of encapsulation).
pros
cons
FAQ
-
What is the difference between named and default exports?
Named exports allow you to export multiple values from a module, each with a specific name. You import these values by their names, enclosed in curly braces. Default exports allow you to export a single value from a module. You import this value without curly braces and can choose any name for the imported variable.
-
Do I need a module bundler to use
export
andimport
?
While modern browsers are increasingly supporting native ES modules, a module bundler like Webpack, Parcel, or Rollup is still recommended for most projects. Bundlers provide features like tree shaking, code minification, and polyfills, which can significantly improve performance and compatibility. Without a bundler, you might face challenges with older browsers or complex dependency graphs.
-
Can I use
export
andimport
in Node.js?
Yes, you can use
export
andimport
in Node.js, but you'll need to configure your project to use ES modules. This typically involves setting the"type": "module"
property in yourpackage.json
file or using the.mjs
file extension for your JavaScript files.