The import() syntax enables dynamic module loading and is webpack’s primary mechanism for code splitting.
Syntax
import(modulePath)
import(modulePath, options)
Parameters
Path to the module to import. Can be a string literal or template literal.import('./module.js')
import(`./locale/${language}.js`)
Import attributes (formerly assertions) for the module.import('./data.json', { assert: { type: 'json' } })
Return Type
Returns: Promise<Module>
Returns a Promise that resolves to the module namespace object.
Basic Usage
Simple Dynamic Import
// Dynamically load a module
import('./math.js')
.then(module => {
console.log(module.add(2, 3)); // 5
})
.catch(err => {
console.error('Failed to load module:', err);
});
With Async/Await
async function loadModule() {
try {
const module = await import('./math.js');
console.log(module.add(2, 3)); // 5
} catch (err) {
console.error('Failed to load module:', err);
}
}
Named Exports
// math.js
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// app.js
const { add, multiply } = await import('./math.js');
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
Default Export
// logger.js
export default class Logger {
log(message) {
console.log(message);
}
}
// app.js
const { default: Logger } = await import('./logger.js');
const logger = new Logger();
logger.log('Hello!');
Code Splitting
Webpack supports special comments to configure chunk behavior:
import(
/* webpackChunkName: "my-chunk" */
/* webpackMode: "lazy" */
/* webpackPrefetch: true */
/* webpackPreload: true */
'./module.js'
)
Name for the generated chunk.import(/* webpackChunkName: "lodash" */ 'lodash')
// Generates: lodash.bundle.js
Mode for resolving dynamic imports.Values: lazy (default) | lazy-once | eager | weak// Create separate chunk for each module
import(/* webpackMode: "lazy" */ `./locale/${lang}.js`)
// Bundle all possible modules into one chunk
import(/* webpackMode: "lazy-once" */ `./locale/${lang}.js`)
// No separate chunk, include in main bundle
import(/* webpackMode: "eager" */ './module.js')
Prefetch the chunk when browser is idle.import(/* webpackPrefetch: true */ './future-feature.js')
// Adds: <link rel="prefetch" href="future-feature.js">
Preload the chunk in parallel with parent chunk.import(/* webpackPreload: true */ './critical.js')
// Adds: <link rel="preload" href="critical.js">
Include only modules matching this pattern.import(
/* webpackInclude: /\.json$/ */
`./data/${file}`
)
Exclude modules matching this pattern.import(
/* webpackExclude: /\.test\.js$/ */
`./components/${name}.js`
)
Import only specific exports to reduce bundle size.import(
/* webpackExports: ["add", "subtract"] */
'./math.js'
)
Advanced Patterns
Lazy Loading Routes
const routes = [
{
path: '/home',
component: () => import(/* webpackChunkName: "home" */ './Home.vue')
},
{
path: '/about',
component: () => import(/* webpackChunkName: "about" */ './About.vue')
}
];
Conditional Loading
async function loadFeature(featureName) {
if (featureName === 'advanced') {
const module = await import(
/* webpackChunkName: "advanced-features" */
'./features/advanced.js'
);
return module.default;
} else {
const module = await import(
/* webpackChunkName: "basic-features" */
'./features/basic.js'
);
return module.default;
}
}
Dynamic Import with Variables
// Load locale files dynamically
async function loadLocale(language) {
const locale = await import(
/* webpackChunkName: "locale-[request]" */
`./locales/${language}.json`
);
return locale.default;
}
// Usage
const messages = await loadLocale('en-US');
Error Handling with Retry
async function importWithRetry(modulePath, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await import(modulePath);
} catch (err) {
if (i === retries - 1) throw err;
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
// Usage
const module = await importWithRetry('./heavy-module.js');
Import Attributes
Import attributes (formerly assertions) specify the expected module type:
// JSON modules
const config = await import('./config.json', {
assert: { type: 'json' }
});
// CSS modules
const styles = await import('./styles.css', {
assert: { type: 'css' }
});
Import attributes syntax is evolving. Webpack supports both assert and with keywords.
Prefetch vs Preload
// Prefetch: Low priority, loaded when browser is idle
import(/* webpackPrefetch: true */ './optional-feature.js')
// Preload: High priority, loaded in parallel
import(/* webpackPreload: true */ './critical-feature.js')
When to use:
- Prefetch: For features likely to be needed soon (future navigation)
- Preload: For features needed in current navigation
Chunk Grouping
// Group related modules into same chunk
import(/* webpackChunkName: "vendor" */ 'lodash');
import(/* webpackChunkName: "vendor" */ 'axios');
import(/* webpackChunkName: "vendor" */ 'moment');
TypeScript Support
// Type-safe dynamic imports
interface MathModule {
add(a: number, b: number): number;
multiply(a: number, b: number): number;
}
async function loadMath(): Promise<MathModule> {
const module = await import('./math');
return module;
}
// Usage
const math = await loadMath();
const result = math.add(2, 3); // Type-safe
Browser Compatibility
Webpack transforms import() to work in all browsers. Native import() requires:
- Chrome 63+
- Firefox 67+
- Safari 11.1+
- Edge 79+
Webpack’s implementation provides broader compatibility through code transformation.
See Also