How to dynamically import JavaScript modules
By Flavio Copes
Learn how to dynamically import a JavaScript module when the path is built at runtime, using the await import() syntax instead of a static import statement.
Have you ever felt the need to load a JavaScript module dynamically?
Maybe you’re trying to load something from a folder but you don’t know the name of the folder. You generate it at runtime.
A static import needs a fixed string, because the engine resolves it before running any code. This does not work:
import test from folder + '/test.js'
Neither does this:
import test from `${folder}/test.js`
You need a dynamic import. import() is a function-like call, and you can pass it any string you build at runtime:
const mod = await import(folder + '/test.js')
import() returns a promise, so you await it (inside an async function, or at the top level of an ES module). When it resolves you get a module namespace object with the exports of that file.
If the module has a default export, you read it from .default:
const mod = await import(folder + '/test.js')
const test = mod.default
Named exports sit on the same object, so you can destructure them:
const { formatDate, parseDate } = await import(folder + '/dates.js')
If the path might be wrong or the file missing, wrap the call in try/catch, because the promise rejects:
try {
const mod = await import(folder + '/test.js')
mod.default()
} catch (error) {
console.error('Could not load module', error)
}
Use a static import when you always need the module. Use import() when the path depends on runtime data, or when you want to load some code only after an action, like a click.
import() works in every current browser and in Node.js. I wrote more about it in JavaScript Dynamic Imports.
Want me to talk about your product? You can sponsor this site.
Related posts about js: