Skip to main content
The import() syntax enables dynamic module loading and is webpack’s primary mechanism for code splitting.

Syntax

import(modulePath)
import(modulePath, options)

Parameters

modulePath
string
required
Path to the module to import. Can be a string literal or template literal.
import('./module.js')
import(`./locale/${language}.js`)
options
object
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 Magic Comments

Webpack supports special comments to configure chunk behavior:
import(
  /* webpackChunkName: "my-chunk" */
  /* webpackMode: "lazy" */
  /* webpackPrefetch: true */
  /* webpackPreload: true */
  './module.js'
)

Available Magic Comments

webpackChunkName
string
Name for the generated chunk.
import(/* webpackChunkName: "lodash" */ 'lodash')
// Generates: lodash.bundle.js
webpackMode
string
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')
webpackPrefetch
boolean
Prefetch the chunk when browser is idle.
import(/* webpackPrefetch: true */ './future-feature.js')
// Adds: <link rel="prefetch" href="future-feature.js">
webpackPreload
boolean
Preload the chunk in parallel with parent chunk.
import(/* webpackPreload: true */ './critical.js')
// Adds: <link rel="preload" href="critical.js">
webpackInclude
RegExp
Include only modules matching this pattern.
import(
  /* webpackInclude: /\.json$/ */
  `./data/${file}`
)
webpackExclude
RegExp
Exclude modules matching this pattern.
import(
  /* webpackExclude: /\.test\.js$/ */
  `./components/${name}.js`
)
webpackExports
string | array
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.

Performance Considerations

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