Last updated: Mar 7, 2024
Reading time·6 min
You can use the import()
syntax to conditionally import an ES6 Module.
When the import
keyword is used as a function, it returns a Promise that you
can await if a certain condition is met.
If you use Node.js, make sure to set the type
property to module
in your
package.json
file before using the ES6 Modules import/export syntax.
{ "type": "module", "scripts": {}, "dependencies": {}, "devDependencies": {} }
Here is a simple example of conditionally importing a module.
The following file structure is assumed.
my-project/ └── index.js └── another-file.js
Here are the contents of another-file.js
.
// 👇️ named export export function sum(a, b) { return a + b; } // 👇️ named export export function multiply(a, b) { return a * b; } // 👇️ default export export default function greet(name) { return `hello ${name}`; }
The file exports 3 functions. The first 2 functions are exported using named exports and the third function is exported using a default export.
Here is the index.js
file that imports the module conditionally.
const condition = 5 + 5 === 10; if (condition) { import('./another-file.js').then(myModule => { console.log('myModule: ', myModule); console.log(myModule.sum(5, 5)); // 👉️ 10 console.log(myModule.multiply(5, 5)); // 👉️ 25 console.log(myModule.default('bobby hadz')); // hello bobby hadz }); }
If I run the node index.js
command, I can see that the conditional import runs
successfully.
Similarly, if I add an index.html
file with the following contents to the
directory.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <div id="box">bobbyhadz.com</div> <script src="index.js"></script> </body> </html>
And issue the npx serve .
command.
npx serve .
I can see that the conditional import also works in the browser.
Notice that we access the named
exports as attributes on the module object.
const condition = 5 + 5 === 10; if (condition) { import('./another-file.js').then(myModule => { console.log('myModule: ', myModule); console.log(myModule.sum(5, 5)); // 👉️ 10 console.log(myModule.multiply(5, 5)); // 👉️ 25 console.log(myModule.default('bobby hadz')); // hello bobby hadz }); }
We access the default
export using the default
attribute.
// named export called `sum` myModule.sum // default export myModule.default
We check if a certain condition is met before using the import() syntax.
The import()
syntax is called dynamic imports.
The syntax allows you to load an ES6 module asynchronously and dynamically.
When you use a dynamic import()
, it only gets evaluated when needed.
On the other hand, if you use a regular import
statement at the top-level of
the file, it gets evaluated immediately as the module loads.
// 👇️ only evaluated if the condition is met if (condition) { import('./module-b.js').then(moduleB => { console.log(moduleB); }) } // 👇️ gets evaluated immediately as the module loads import a from './module-a.js'
The import()
syntax takes the name of the module or the path to the module as
a parameter.
The previous example uses the .then() method to conditionally import a module.
However, in most cases, it is more convenient to use the async/await
syntax.
The example uses the same another-file.js
module from the previous subheading.
Here is the code in index.js
.
const condition = 5 + 5 === 10; if (condition) { const myModule = await import('./another-file.js'); console.log('myModule: ', myModule); console.log(myModule.sum(5, 5)); // 👉️ 10 console.log(myModule.multiply(5, 5)); // 👉️ 25 console.log(myModule.default('bobby hadz')); // hello bobby hadz }
If I run the node index.js
command, I can see that everything works as
expected.
Make sure you have type
set to module
in your package.json
file,
otherwise, you'd get the
Await is only valid in async functions and the top-level bodies of modules
error.
You can also use the async/await
syntax to conditionally import a module in
the browser.
Here is the code for the index.html
file.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <div id="box">bobbyhadz.com</div> <script type="module" src="index.js"></script> </body> </html>
Notice that the type
attribute on the script
tag is set to module
.
This enables you to use the top-level await
syntax.
Here is the code for the index.js
file.
const condition = 5 + 5 === 10; if (condition) { const myModule = await import('./another-file.js'); console.log('myModule: ', myModule); console.log(myModule.sum(5, 5)); // 👉️ 10 console.log(myModule.multiply(5, 5)); // 👉️ 25 console.log(myModule.default('bobby hadz')); // hello bobby hadz }
I can start a basic server with the npx serve .
command.
npx serve .
If I open the page in my browser, I can see that everything works as expected.
Here is an example that conditionally imports a third-party module in Node.js.
The example uses the uuid module.
# with NPM npm install uuid # or with YARN yarn add uuid
Here is the index.js
file.
const condition = 5 + 5 === 10; if (condition) { import('uuid').then(uuidModule => { console.log(uuidModule.v4()); console.log(uuidModule.v4()); }); }
We import the uuid
module and call the v4()
method.
If I issue the node index.js
command, I can see that everything works as
expected.
The randomly generated unique IDs are printed to the console.
You can also conditionally import a third-party module in the browser in a similar way.
However, you have to pass the ESM build of the module to the import()
keyword.
The CDN URL will likely look similar to the following.
https://cdn.jsdelivr.net/npm/uuid@9.0.0/+esm
You can use a service such as jsdelivr.net
. For example, you can google for
"jsdelivr uuid".
Once you find the module you want to load conditionally:
Copy the URL from the import statement.
Conditionally import the module as follows.
const condition = 5 + 5 === 10; if (condition) { import('https://cdn.jsdelivr.net/npm/uuid@9.0.0/+esm').then( uuidModule => { console.log(uuidModule.v4()); console.log(uuidModule.v4()); }, ); }
Here is the related index.html
file.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <div id="box">bobbyhadz.com</div> <script src="index.js"></script> </body> </html>
I can start a simple server with the npx serve .
command.
npx serve .
If I open my browser, I can see that the module is loaded successfully and the unique IDs are printed to the console.
If you need to determine what module to import conditionally, use the ternary operator.
The example uses the following file structure.
my-project/ └── module-1.js └── module-2.js └── index.js
Here are the contents of module-1.js
.
export default function sum(a, b) { return a + b; }
And here are the contents of the module-2.js
file.
export default function multiply(a, b) { return a * b; }
Finally, this is the index.js
file.
const condition = 5 + 5 === 10; if (condition) { const modulePath = 5 + 5 === 10 ? './module-1.js' : './module-2.js'; console.log(modulePath); // 👉️ ./module-1.js const myModule = await import(modulePath); console.log(myModule.default); // sum(){} console.log(myModule.default(5, 5)); // 10 }
We used the ternary operator to conditionally determine the path of the module that is to be imported.
The ternary operator is very similar to an if/else
statement.
If I run the node index.js
command I can see that the sum
module is imported
conditionally.
I can issue the npx serve .
command to verify that the code works in the
browser as well.
I've also written a detailed guide on how to import and export classes and functions in JavaScript.
You can learn more about the related topics by checking out the following tutorials: