Директория shared/ позволяет использовать один и тот же код и во Vue-приложении, и на сервере Nitro.
shared/ доступна в Nuxt v3.14+.shared/ не может импортировать код Vue или Nitro.Почему нельзя смешивать код Vue и Nitro
Nuxt собирает два отдельных бандла: Vue-приложение (клиент и SSR) и Nitro-сервер (API routes, server middleware, server plugins). Они бандлятся независимо и работают в разных контекстах. Код в shared/ используется в обоих бандлах, поэтому не может импортировать ни из одного из них.
Код Vue-приложения в Nitro
Компонентам и composables нужен runtime Vue-приложения и часто контекст Nuxt (например useNuxtApp() или useRoute()), ни того, ни другого в Nitro нет. Импорт в server code может вызвать ошибки сборки или рантайма и подтянуть зависимости Vue-приложения в server bundle.
Код Nitro во Vue-приложении
Server-only код (Node API, утилиты Nitro, server route handlers) не должен выполняться в браузере. Импорт в app может сломать клиентскую сборку, вызвать ошибки в браузере или утянуть server logic в client bundle.
Type-only импорты
import type стирается при компиляции и не подтягивает runtime в другой бандл, поэтому импорт только типов через границу может казаться рабочим. Тем не менее общие типы (например типы ответов API) лучше держать в shared/types/, где они автоимпортируются в обоих контекстах. Это сохраняет границу, не даёт случайно превратить type import в value import и соответствует отдельным type contexts Nuxt для app, server и shared.
Использование
Способ 1: именованный экспорт
export const capitalize = (input: string) => {
return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}
Способ 2: экспорт по умолчанию
export default function (input: string) {
return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}
Утилиты из shared/ автоимпортируются в приложении Nuxt и в директории server/.
<script setup lang="ts">
const hello = capitalize('hello')
</script>
<template>
<div>
{{ hello }}
</div>
</template>
export default defineEventHandler((event) => {
return {
hello: capitalize('hello'),
}
})
Как сканируются файлы
Автоимпортируются только файлы из shared/utils/ и shared/types/. Файлы во вложенных поддиректориях не автоимпортируются, если не добавить эти директории в imports.dirs и nitro.imports.dirs.
shared/utils и shared/types такой же, как для app/composables/ и app/utils/.-| shared/
---| capitalize.ts # Не автоимпортируется
---| formatters
-----| lower.ts # Не автоимпортируется
---| utils/
-----| lower.ts # Автоимпортируется
-----| formatters
-------| upper.ts # Не автоимпортируется
---| types/
-----| bar.ts # Автоимпортируется
Остальные файлы в shared/ нужно импортировать вручную через алиас #shared (настраивается Nuxt):
// Файлы прямо в shared
import capitalize from '#shared/capitalize'
// Файлы во вложенных директориях
import lower from '#shared/formatters/lower'
// Файлы в папке внутри utils
import upper from '#shared/utils/formatters/upper'
Так импорты остаются единообразными в любом месте приложения.