--- title: Use import.meta.glob for Dynamic Component Registration in Vite impact: MEDIUM impactDescription: require.context from Webpack doesn't work in Vite projects type: gotcha tags: [vue3, component-registration, vite, dynamic-import, migration, webpack] --- # Use import.meta.glob for Dynamic Component Registration in Vite **Impact: MEDIUM** - When migrating from Webpack to Vite or starting a new Vite project, the `require.context` pattern for dynamically registering components won't work. Vite uses `import.meta.glob` instead. Using the wrong approach will cause build errors or runtime failures. ## Task Checklist - [ ] Replace `require.context` with `import.meta.glob` in Vite projects - [ ] Update component registration patterns when migrating from Vue CLI to Vite - [ ] Use `{ eager: true }` for synchronous loading when needed - [ ] Handle async components appropriately with `defineAsyncComponent` **Incorrect (Webpack pattern - doesn't work in Vite):** ```javascript // main.js - WRONG for Vite import { createApp } from 'vue'; import App from './App.vue'; const app = createApp(App); // This Webpack-specific API doesn't exist in Vite const requireComponent = require.context('./components/base', false, /Base[A-Z]\w+\.vue$/); requireComponent.keys().forEach((fileName) => { const componentConfig = requireComponent(fileName); const componentName = fileName .split('/') .pop() .replace(/\.\w+$/, ''); app.component(componentName, componentConfig.default || componentConfig); }); app.mount('#app'); ``` **Correct (Vite pattern):** ```javascript // main.js - Correct for Vite import { createApp } from 'vue'; import App from './App.vue'; const app = createApp(App); // Vite's glob import - eager loading for synchronous registration const modules = import.meta.glob('./components/base/Base*.vue', { eager: true }); for (const path in modules) { // Extract component name from path: './components/base/BaseButton.vue' -> 'BaseButton' const componentName = path.split('/').pop().replace('.vue', ''); app.component(componentName, modules[path].default); } app.mount('#app'); ``` ## Lazy Loading with Async Components ```javascript // main.js - Lazy loading variant import { createApp, defineAsyncComponent } from 'vue'; import App from './App.vue'; const app = createApp(App); // Without { eager: true }, returns functions that return Promises const modules = import.meta.glob('./components/base/Base*.vue'); for (const path in modules) { const componentName = path.split('/').pop().replace('.vue', ''); // Wrap in defineAsyncComponent for lazy loading app.component(componentName, defineAsyncComponent(modules[path])); } app.mount('#app'); ``` ## Glob Pattern Examples ```javascript // All .vue files in a directory (not recursive) import.meta.glob('./components/*.vue', { eager: true }); // All .vue files recursively import.meta.glob('./components/**/*.vue', { eager: true }); // Specific naming pattern import.meta.glob('./components/Base*.vue', { eager: true }); // Multiple patterns import.meta.glob(['./components/Base*.vue', './components/App*.vue'], { eager: true }); // Exclude patterns import.meta.glob('./components/**/*.vue', { eager: true, ignore: ['**/*.test.vue', '**/*.spec.vue'], }); ``` ## TypeScript Support ```typescript // main.ts - with proper typing import { createApp, Component } from 'vue'; import App from './App.vue'; const app = createApp(App); const modules = import.meta.glob<{ default: Component }>('./components/base/Base*.vue', { eager: true, }); for (const path in modules) { const componentName = path.split('/').pop()!.replace('.vue', ''); app.component(componentName, modules[path].default); } app.mount('#app'); ``` ## Migration Checklist (Webpack to Vite) | Webpack | Vite | | ---------------------------------------- | ------------------------------------ | | `require.context(dir, recursive, regex)` | `import.meta.glob(pattern, options)` | | Synchronous by default | Use `{ eager: true }` for sync | | `.keys()` returns array | Returns object with paths as keys | | Returns module directly | Access via `.default` for ES modules | ## Reference - [Vite - Glob Import](https://vitejs.dev/guide/features.html#glob-import) - [Vue.js Component Registration](https://vuejs.org/guide/components/registration.html)