🔥 构建与性能改进
🍫 增强的 Chunk 稳定性
通过 import map 技术显著提升了构建的稳定性(#33075)。这能够避免由于小改动导致的大范围构建散列哈希变化:
<!-- 自动注入的 import map -->
<script type="importmap">{"imports":{"#entry":"/_nuxt/DC5HVSK5.js"}}</script>
在 Vite 构建中,生成的 JS chunk 默认会被哈希处理,这意味着它们可以被不可变地缓存。但这会带来一个重大问题:单个组件的改动可能导致 所有 哈希文件失效,大大增加 404 错误的风险。
简而言之:
- 组件轻微变动 —— 该组件 JS chunk 的哈希变更
- 使用该组件的页面需更新以引用新的文件名
- entry 文件因动态导入该页面而哈希随之改变
- 导入 entry 的 其他所有文件 哈希都被改变
显然,这种情况并不理想。开启此新特性后,导入 entry 的其他未变更文件的哈希将不会受到影响。
该功能默认启用,有助于在生产环境中提升缓存效率。它依赖于 原生 import map 支持,如果你配置了 vite.build.target
包含不支持 import map 的浏览器,Nuxt 会自动禁用此功能。
当然,你也可以根据需要手动禁用:
export default defineNuxtConfig({
experimental: {
entryImportMap: false
}
})
🦀 实验性 Rolldown 支持
Nuxt 现已实验性支持 rolldown-vite
(#31812),这是一款基于 Rust 的打包工具,可带来更快的构建速度。
在 Nuxt 项目中尝试使用 Rolldown,需要通过包覆盖来替换默认的 Vite 版本,因为 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"
}
}
添加覆盖后,重新安装依赖。Nuxt 会自动检测 Rolldown 的可用性,并相应调整构建配置。
有关 Rolldown 集成的更多详情,请参阅 Vite Rolldown 指南。
🧪 改进的懒加载水合(Lazy Hydration)
懒加载水合宏现支持无自动导入的使用情况(#33037),提升了组件自动发现被禁用时的可靠性:
<script setup>
// 即使 components 配置为 false 也可正常工作
const LazyComponent = defineLazyHydrationComponent(
'visible',
() => import('./MyComponent.vue')
)
</script>
这保证了即便组件未通过 Nuxt 自动“发现”(例如配置中 components: false
),仍可在懒加载水合宏中使用。
📄 强化的页面规则
如果开启了实验性的路由规则提取,这些规则现在会暴露在 NuxtPage
对象上的专属 rules
属性中(#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。
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
文件应提交到版本控制)
🙈 增强的文件解析
resolveFiles
新增 ignore
选项(#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 工具
多个 kit 工具得到改进,优化开发体验:
addServerImports
现在支持单条导入参数(#32289):
// 以前:必须传数组
addServerImports([{ from: 'my-package', name: 'myUtility' }])
// 现在:可直接传单个对象
addServerImports({ from: 'my-package', name: 'myUtility' })
🔥 性能优化
本次发布包括以下内部性能提升:
🐛 重要修复
- 优化
useFetch
钩子类型定义(#32891) - 更好地处理页面元数据中的 TypeScript 表达式(#32902, #32914)
- 路由匹配与同步增强(#32899)
- 减少开发环境中 Vue 服务器警告的冗余信息(#33018)
<NuxtTime>
中相对时间计算的改进(#32893)
✅ 升级指南
照旧,我们推荐的升级操作是:
npx nuxt upgrade --dedupe
这将刷新你的锁文件,并拉取所有 Nuxt 依赖,尤其是 unjs 生态相关的最新内容。
📦 Nuxt 3.19
上述功能同样适用于 Nuxt 3.19,它与 v4.1 同步发布。作为对 v3 分支的承诺,我们持续回移兼容的 v4 特性,确保 v3 用户同样能受益最新改进。
如果你仍在使用 Nuxt 3,可升级至 v3.19,以在稳定的 v3 系列中享用全部这些新特性。
完整发行说明
感谢所有贡献者!我们期待看到你利用这些新功能创造出精彩作品。❤️