分层与主题
Layer 能把一组 Nuxt 配置、组件、composable、服务端路由和资源打包成一个可复用的单元 —— 本地目录、npm 包,或 Git 源都行。可以把它当作“可继承的功能”。
为什么用 Layer?
- 跨项目复用配置预设(
nuxt.config、app.config)。 - 用
app/components/搭建组件库。 - 用
app/composables//app/utils/发布工具函数。 - 发布带默认值的 Nuxt 模块套装。
- 在 monorepo 里按领域拆分(DDD),每层只管自己那片。
- 做主题和脚手架模板。
Layer 的目录结构跟 Nuxt 应用本身一模一样,写 layer 就像写个小号 Nuxt 项目。
两种引入方式
自动注册 ~~/layers/*
从 Nuxt 3.12 起,~~/layers/ 下的任何目录都会被自动注册:
my-app/
├── layers/
│ ├── base/
│ └── admin/
├── app/
└── nuxt.config.ts
Nuxt 也会暴露别名,例如 #layers/admin,指向该 layer 的 srcDir。
显式 extends
项目外、npm 包、Git 上的 layer 用 extends:
export default defineNuxtConfig({
extends: [
'../base', // 相对路径
'@my-themes/awesome', // npm 包
'github:my-themes/awesome#v1', // Git 分支/tag
['github:my-themes/private-awesome',
{ auth: process.env.GITHUB_TOKEN }], // 私有仓库
],
})
远程 layer 由 unjs/giget 下载,配置合并由 unjs/c12 负责。
也可以改 layer 的别名:
export default defineNuxtConfig({
extends: [
['github:my-themes/awesome',
{ meta: { name: 'my-awesome-theme' } }],
],
})
优先级与覆盖顺序
多个 layer 定义同一个文件时,Nuxt 按以下优先级合并(高 → 低):
- 你自己项目的文件
- 自动扫描的
~~/layers/*(字母序,Z > A) extends中的条目(靠前 > 靠后)
用数字前缀控制顺序:
layers/
├── 1.base/ # layer 中优先级最低
├── 2.features/
└── 3.admin/ # layer 中优先级最高
项目自身的文件始终优先,除非显式不覆盖。
编写一个 Layer
一个 layer 就是迷你版 Nuxt 项目。比如一个 admin layer:
layers/admin/
├── app/
│ ├── components/AdminNav.vue
│ └── composables/useAdmin.ts
├── nuxt.config.ts
└── app.config.ts
// layers/admin/nuxt.config.ts
export default defineNuxtConfig({
css: ['~/assets/admin.css'],
})
Layer 中声明的一切都会合入消费端:组件自动导入、app/pages/ 下的路由加入路由表、routeRules 一并合并。
发布 Layer
-
package.json暴露nuxt.config.ts:{ "name": "@me/nuxt-awesome", "type": "module", "exports": { ".": { "import": "./nuxt.config.ts" } } } -
用户安装后注册:
export default defineNuxtConfig({ extends: ['@me/nuxt-awesome'], }) -
记得把对外 API 写进文档:暴露的组件、composable、模块选项、需要的环境变量。
Layer、Module、Plugin 的差别
- Layer:整块的应用切片(页面、组件、composable、配置、服务端路由)。适合复用面向用户的功能。
- Module:程序式扩展 Nuxt 构建(注入别名、追加模块、修改配置)。适合配置其他 layer 或集成外部库。
- Plugin:运行时代码(客户端/服务端),启动时执行。适合在运行时提供服务。
一个大产品往往三者都有:Layer 提供业务 UI,Module 把它自动接上,Plugin 做运行时胶水。
值得抄作业的场景
- 同一个 monorepo 里把「营销站 → 文档站 → 产品应用」拆成三个 layer。
- 把登录(中间件、登录页、composable)打包成可复用 layer。
- 跨项目共用设计系统,用
app.config下发 token。 - 面向公司定制的内部主题,所有 Nuxt 项目都来继承。
Layer 让 Nuxt 从“框架”进化成“你们团队的平台”。