Modules
JavaScript modules allow you to break up your code into separate files.
This makes it easier to maintain the code-base.
JavaScript modules rely on the import
and export
statements.
Export
You can export a function or variable from any file.
Let us create a file named person.js
, and fill it with the things we want to export.
There are two types of exports: Named and Default.
Named Exports
You can create named exports two ways. In-line individually, or all at once at the bottom.
In-line individually:
person.js
export const name = "Jesse";
export const age = 40;
All at once at the bottom:
person.js
const name = "Jesse";
const age = 40;
export {name, age};
Default Exports
Let us create another file, named message.js
, and use it for demonstrating default export.
You can only have one default export in a file.
Example
message.js
const message = [] => {
const name = "Jesse";
const age = 40;
return name + ' is ' + age + 'years old.';
};
export default message;
Import
You can import modules into a file in two ways, based on if they are named exports or default exports.
Named exports are constructed using curly braces. Default exports are not.
Import from named exports
Import named exports from the file person.js:
import { name, age } from "./person.js";
Try it Yourself »
Import from default exports
Import a default export from the file message.js:
import message from "./message.js";
Try it Yourself »
Note
Modules only work with the HTTP[s] protocol.
A web-page opened via the file:// protocol cannot use import / export.
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 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’ moduleto 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’. 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. 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"; The parameters used in the above code snippet: Refers to the name that will
indicate the default export from the module. 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.An Overview of Importing in JavaScript
Dynamic import[] Function
Import Syntaxes
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"];defaultExport
module-name
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