🔥 Сборка и производительность
🍫 Стабильность чанков
Стабильность сборки улучшена за счёт import maps (#33075): меньше каскадных смен хешей при небольших изменениях:
<!-- Автоматически подставляемый import map -->
<script type="importmap">{"imports":{"#entry":"/_nuxt/DC5HVSK5.js"}}</script>
Чанки Vite по умолчанию хешируются и могут кэшироваться неизменяемо. Но изменение одного компонента могло инвалидировать все хеши и приводить к 404.
Кратко:
- Меняется компонент — меняется хеш его чанка
- Страница, которая его импортирует, ссылается на новый файл
- У entry тоже меняется хеш из-за динамического импорта страницы
- Хеш меняется у всех файлов, импортирующих entry
С новой фичей хеш неизменённых файлов, импортирующих entry, не трогается.
Фича включена по умолчанию и улучшает кэш в production. Нужна поддержка import maps в браузере; если в vite.build.target указан браузер без поддержки, Nuxt отключит её сам.
При необходимости можно отключить вручную:
export default defineNuxtConfig({
experimental: {
entryImportMap: false
}
})
🦀 Экспериментальная поддержка Rolldown
Добавлена экспериментальная поддержка rolldown-vite (#31812) — бандлинг на Rust для более быстрой сборки.
Чтобы попробовать Rolldown в Nuxt, нужно подменить Vite на версию на Rolldown (Vite — зависимость Nuxt). Добавьте в package.json:
{
"overrides": {
"vite": "npm:rolldown-vite@latest"
}
}
{
"pnpm": {
"overrides": {
"vite": "npm:rolldown-vite@latest"
}
}
}
{
"resolutions": {
"vite": "npm:rolldown-vite@latest"
}
}
{
"overrides": {
"vite": "npm:rolldown-vite@latest"
}
}
После добавления override переустановите зависимости. Nuxt сам определит наличие Rolldown и подстроит конфиг сборки.
Подробнее: руководство Vite по Rolldown.
🧪 Улучшенная отложенная гидрация
Макросы отложенной гидрации работают без автоимпортов (#33037) — надёжнее при отключённом автообнаружении компонентов:
<script setup>
// Работает даже при components: false
const LazyComponent = defineLazyHydrationComponent(
'visible',
() => import('./MyComponent.vue')
)
</script>
Компоненты, не «обнаруженные» Nuxt (например, при components: false), можно использовать в макросах ленивой гидрации.
📄 Правила страниц
При включённом экспериментальном извлечении route rules они доступны в свойстве rules у объектов NuxtPage (#32897) — удобнее для модулей и архитектуры:
// В вашем модуле
nuxt.hook('pages:extend', pages => {
pages.push({
path: '/api-docs',
rules: {
prerender: true,
cors: true,
headers: { 'Cache-Control': 's-maxage=31536000' }
}
})
})
Функция defineRouteRules ведёт себя как раньше, но даёт модулям больше возможностей для интеграции.
🚀 Разработка модулей
Зависимости и интеграция модулей
Модули могут указывать зависимости и менять опции других модулей (#33063) — лучше интеграция и порядок инициализации:
export default defineNuxtModule({
meta: {
name: 'my-module',
},
moduleDependencies: {
'some-module': {
// Ограничение версии зависимости
version: '>=2',
// По умолчанию модули из moduleDependencies ставит Nuxt; optional: true отключает это
optional: true,
// Конфиг, переопределяющий nuxt.options
overrides: {},
// Значения по умолчанию (перебивают дефолты модуля, но не nuxt.options)
defaults: {}
}
},
setup (options, nuxt) {
// Логика инициализации модуля
}
})
Вместо устаревшего installModule — явные зависимости с версиями и слиянием конфигов.
🪝 Хуки жизненного цикла модуля
Доступны два хука: onInstall и onUpgrade (#32397) — дополнительная настройка при первой установке и при обновлении:
export default defineNuxtModule({
meta: {
name: 'my-module',
version: '1.0.0',
},
onInstall(nuxt) {
// Выполняется при первой установке модуля
console.log('Первоначальная настройка my-module!')
},
onUpgrade(inlineOptions, nuxt, previousVersion) {
// Выполняется при обновлении модуля
console.log(`Обновление my-module с v${previousVersion}`)
}
})
Хуки вызываются только при указанных в метаданных модуля name и version. Nuxt использует файл .nuxtrc для отслеживания версий и вызова нужных хуков. (Файл .nuxtrc рекомендуется коммитить.)
🙈 Расширенное разрешение файлов
Опция ignore в resolveFiles (#32858) позволяет исключать файлы по glob-паттернам:
// Найти все .vue, кроме тестов
const files = await resolveFiles(srcDir, '**/*.vue', {
ignore: ['**/*.test.vue', '**/__tests__/**']
})
📂 Утилита директорий слоёв
Утилита getLayerDirectories (#33098) даёт доступ к директориям слоёв без использования внутренних API:
import { getLayerDirectories } from '@nuxt/kit'
const layerDirs = await getLayerDirectories(nuxt)
// Основные директории:
// layerDirs.app — по умолчанию /app/
// layerDirs.appPages — по умолчанию /app/pages
// layerDirs.server — по умолчанию /server
// layerDirs.public — по умолчанию /public
✨ Удобство разработки
🎱 Упрощённые утилиты Kit
addServerImportsподдерживает одиночный импорт (#32289):
// Раньше: только массив
addServerImports([{ from: 'my-package', name: 'myUtility' }])
// Теперь: можно передать объект
addServerImports({ from: 'my-package', name: 'myUtility' })
🔥 Производительность
- Улучшено кэширование route rules (#32877)
- Оптимизирован watch за app manifest (#32880)
- Лучше обработка TypeScript для метаданных страниц (#32920)
🐛 Важные исправления
- Улучшена типизация хука
useFetch(#32891) - Корректнее обработка TypeScript-выражений в метаданных страниц (#32902, #32914)
- Улучшены сопоставление и синхронизация маршрутов (#32899)
- Меньше шума от предупреждений Vue server в dev (#33018)
- Корректнее расчёт относительного времени в
<NuxtTime>(#32893)
✅ Обновление
Рекомендуем выполнить:
npx nuxt upgrade --dedupe
Команда обновит lockfile и подтянет зависимости Nuxt, в том числе из экосистемы unjs.
📦 Nuxt 3.19
Те же возможности есть в Nuxt 3.19, вышедшем вместе с v4.1. Мы продолжаем бэкпортить совместимые фичи v4 в v3.
Если вы ещё на Nuxt 3, обновитесь до v3.19, чтобы получить эти улучшения, оставаясь на стабильной ветке v3.
Полный список изменений
Спасибо всем контрибьюторам! Интересно, что вы сделаете с новыми возможностями. ❤️