Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як працюють auto-imports в Nuxt?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Auto-imports в Nuxt** сканують директорії `~/composables` і `~/components` під час збірки і вставляють їхні експорти в кожен `.vue` файл через віртуальний модуль `#imports`. ```ts const { data } = await useFetch('/api/users') // import не потрібен const route = useRoute() // теж авто-імпорт ``` **Головне:** сканування відбувається один раз під час збірки; рантайм - звичайні JS-модулі без додаткових витрат.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Auto-imports в Nuxt** - функція на рівні збірки, яка робить composables, компоненти та утиліти доступними в кожному файлі застосунку без жодного рядка `import`. ## Теорія ### TL;DR - Nuxt сканує `~/composables`, `~/components`, `~/utils` під час збірки і вставляє їхні експорти в кожен `.vue` файл - Аналогія: кухня в готелі, де всі інструменти лежать у спільних ящиках - кухар просто бере потрібне, не питаючи - Ніяких рядків `import`; Vite-плагін усе робить через віртуальний модуль `#imports` - Вимкнути: `autoImports: false` в `nuxt.config.ts` ### Швидкий приклад ```vue <!-- pages/users.vue - жодного рядка import --> <script setup> // useFetch і useRoute приходять з авто-згенерованого модуля #imports const { data: users } = await useFetch('/api/users') const route = useRoute() </script> <template> <!-- ~/components/UserList.vue підхоплюється автоматично --> <UserList v-for="user in users" :key="user.id" :user="user" /> </template> ``` `useFetch`, `useRoute` і `UserList` вставляються без жодного рядка import. Nuxt вирішує це під час збірки, а не в рантаймі. ### Як це працює зсередини Vite-плагін Nuxt сканує директорії під час збірки і генерує віртуальний модуль `#imports`, який експортує все знайдене: composables, утиліти, компоненти. Цей модуль автоматично потрапляє в скоп кожного `.vue` файлу. На рівні рантайму це звичайні JS-модулі. Жодного оверхеду. Сканування і вставка відбуваються один раз під час збірки, і результат такий самий, ніби ти написав усі імпорти вручну. Директорії за замовчуванням: `~/composables`, `~/components`, `~/utils`, `~/plugins`, `~/server/composables` (з Nuxt 3.8+). Додати свої можна через `imports.dirs` в `nuxt.config.ts`. ### Client vs server авто-імпорти Client composables (авто-імпорти для клієнта) живуть в `~/composables/`. Серверні - в `~/server/composables/`. Суфікси `.client.ts` і `.server.ts` кажуть Nuxt, в яку збірку включати файл. Використовуєш client composable в server API route - Nuxt кине "not defined". Серверна збірка ніколи не сканує `~/composables/`. Це найчастіша причина помилок авто-імпорту в Nuxt-проєктах, яку я бачив. Переміщення в `~/server/composables/` вирішує проблему. ### Коли використовувати - Нова сторінка або composable: просто створюєш файл, він одразу доступний скрізь - Спільна логіка між компонентами: кладеш в `~/composables/`, і все - Великий monorepo або контроль за бандлом: вимикай через `autoImports: false`, додавай ручні імпорти ### Типові помилки **Client composable в серверному роуті:** ```ts // server/api/orders.get.ts - НЕПРАВИЛЬНО // ~/composables/ не сканується під час серверної збірки const data = useMyClientUtil() // кидає: not defined // ПРАВИЛЬНО - перемісти в ~/server/composables/useMyServerUtil.ts ``` **Назва composable збігається з вбудованим Nuxt:** ```ts // ~/composables/useRoute.ts // Перекриває Nuxt-івський useRoute і ламає роутинг по всьому застосунку // Перейменуй: useAppRoute, usePageRoute - головне не те саме ім'я ``` **Авто-імпорт всередині `defineNuxtPlugin`:** ```ts // Плагіни запускаються до завершення сканування авто-імпортів export default defineNuxtPlugin(() => { const util = useMyUtil() // undefined - сканування ще не відбулось // Рішення: вставляй через provide return { provide: { myUtil: () => 'works' } } }) ``` ### Де зустрічається - Nuxt Content: `queryContent('/')` авто-імпортується для MDX-блогів (nuxt/content v2.6+) - Nuxt UI: `<UButton />` доступний скрізь з `~/components/Ui` (nuxt/ui v2.8) - Supabase Nuxt: `useSupabaseClient()` і `useSupabaseUser()` для авторизації - Vitest + Nuxt: тестовий setup авто-мокає модуль `#imports` ### Питання на співбесіді **Q:** Які директорії Nuxt сканує за замовчуванням? **A:** `~/composables`, `~/components`, `~/utils`, `~/plugins`, `~/server/composables`. Свої додаєш через `imports.dirs` в `nuxt.config.ts`. **Q:** Як додати кастомну директорію? **A:** `imports: { dirs: ['~/logic'] }` в `nuxt.config.ts`. Кожна функція з тієї папки стане авто-імпортованою. **Q:** Чим відрізняються client і server авто-імпорти? **A:** Client composables в `~/composables/`, серверні в `~/server/composables/`. Суфікс `.client.ts` або `.server.ts` обмежує файл конкретною збіркою. **Q:** Чи покращує вимкнення авто-імпортів розмір бандлу? **A:** Авто-імпортований код вже проходить через tree-shaking, невикористані composables не потрапляють в бандл. Вимикати варто для явності залежностей у великому monorepo, а не заради розміру. **Q:** Чим відрізняється від Vue `globalProperties`? **A:** Авто-імпорти - це модульні експорти з tree-shaking і TypeScript-підказками. `globalProperties` - об'єкти рантайму, прив'язані до екземпляру застосунку, без tree-shaking і зі слабкою підтримкою типів. ## Приклади ### Базовий: composable і компонент на сторінці ```vue <!-- pages/dashboard.vue --> <script setup> const route = useRoute() // авто-імпорт const { data: orders } = await useFetch('/api/orders', { params: { userId: route.params.id } }) </script> <template> <!-- ~/components/OrderTable.vue - авто-імпорт --> <OrderTable :orders="orders" /> </template> ``` `useFetch`, `useRoute` і `OrderTable` Nuxt підтягує під час збірки. Перейменуєш файл компонента - оновиться і ім'я тегу в шаблоні. ### Проміжний: серверний composable vs клієнтський ```ts // ~/server/composables/useDb.ts - доступний тільки в server/api/ роутах export const useDb = () => { return { query: (sql: string) => db.execute(sql) } } // server/api/users.get.ts export default defineEventHandler(async () => { const { query } = useDb() // авто-імпорт з ~/server/composables/ return query('SELECT * FROM users') }) // ~/composables/useUsers.ts - доступний тільки в pages/ і components/ export const useUsers = () => { const users = ref([]) const load = async () => { users.value = await $fetch('/api/users') } return { users, load } } ``` Серверна і клієнтська збірки мають окремий скоп авто-імпортів. Їх змішування - звідси і беруться помилки "X is not defined".Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.