撰写 Nuxt 层
Nuxt 层(layers)是一个强大的特性,允许你在 monorepo 中或从 git 仓库或 npm 包中共享和重用部分 Nuxt 应用。层的结构与标准的 Nuxt 应用几乎相同,这使得它们易于编写和维护。
一个最小的 Nuxt 层目录应包含一个 nuxt.config.ts
文件,以表明它是一个层。
export default defineNuxtConfig({})
此外,层目录中的某些其他文件会被 Nuxt 自动扫描并用于扩展该层的项目。
app/components/*
- 扩展默认组件app/composables/*
- 扩展默认的 composablesapp/layouts/*
- 扩展默认布局app/middleware/*
- 扩展默认中间件app/pages/*
- 扩展默认页面app/plugins/*
- 扩展默认插件app/utils/*
- 扩展默认工具函数app/app.config.ts
- 扩展默认应用配置server/*
- 扩展默认的服务器端点和中间件nuxt.config.ts
- 扩展默认的 nuxt 配置
基本示例
export default defineNuxtConfig({
extends: [
'./base',
],
})
<template>
<BaseComponent />
</template>
export default defineNuxtConfig({
// Extending from base nuxt.config.ts!
app: {
head: {
title: 'Extending Configs is Fun!',
meta: [
{ name: 'description', content: 'I am using the extends feature in Nuxt!' },
],
},
},
})
<template>
<h1>Extending Components is Fun!</h1>
</template>
层优先级
当从多个层扩展时,理解优先级顺序非常重要:
extends
中的层 - 越靠前的条目优先级越高(第一个会覆盖第二个)- 从
~~/layers
目录自动扫描到的本地层,按字母顺序(Z 覆盖 A) - 你的项目 在堆栈中具有最高优先级 — 它始终会覆盖其他层
例如:
export default defineNuxtConfig({
extends: [
// Highest priority (among extends)
'./layers/base',
// Medium priority
'./layers/theme',
// Lower priority
'./layers/custom',
],
// Your project has the highest priority
})
如果你还有像 ~~/layers/a
和 ~~/layers/z
这样的自动扫描层,完整的覆盖顺序将是:base
> theme
> custom
> z
> a
> 你的项目。
启动模板
要开始,你可以使用 nuxt/starter/layer template 初始化一个层。这将创建一个基本结构供你构建。在终端中执行以下命令以开始:
npm create nuxt -- --template layer nuxt-layer
按照 README 中的说明进行下一步操作。
发布层
你可以通过远程源或 npm 包发布并共享层。
Git 仓库
你可以使用 git 仓库来共享你的 Nuxt 层。示例:
export default defineNuxtConfig({
extends: [
// GitHub Remote Source
'github:username/repoName',
// GitHub Remote Source within /base directory
'github:username/repoName/base',
// GitHub Remote Source from dev branch
'github:username/repoName#dev',
// GitHub Remote Source from v1.0.0 tag
'github:username/repoName#v1.0.0',
// GitLab Remote Source example
'gitlab:username/repoName',
// Bitbucket Remote Source example
'bitbucket:username/repoName',
],
})
GIGET_AUTH=<token>
来提供令牌。GIGET_GITHUB_URL=<url>
或 GIGET_GITLAB_URL=<url>
提供其 URL — 或在你的 nuxt.config
中直接使用 the auth
option 进行配置。node_modules/.c12/layer_name/node_modules/
),你的包管理器无法访问该位置。install: true
来实现。export default defineNuxtConfig({
extends: [
['github:username/repoName', { install: true }],
],
})
npm 包
你可以将 Nuxt 层作为一个包含要扩展的文件和依赖项的 npm 包发布。这允许你共享配置,在多个项目中使用它,或私下使用它。
要从 npm 包扩展,需要确保该模块已发布到 npm 并作为 devDependency 安装在使用者的项目中。然后你可以使用模块名称来扩展当前的 nuxt 配置:
export default defineNuxtConfig({
extends: [
// Node Module with scope
'@scope/moduleName',
// or just the module name
'moduleName',
],
})
要将层目录发布为 npm 包,请确保 package.json
中的属性已正确填写。这将确保在发布包时包含所需的文件。
{
"name": "my-theme",
"version": "1.0.0",
"type": "module",
"main": "./nuxt.config.ts",
"dependencies": {},
"devDependencies": {
"nuxt": "^3.0.0"
}
}
dependencies
中。nuxt
依赖以及仅用于在发布前测试层的任何内容,应保留在 devDependencies
字段中。现在你可以继续将模块发布到 npm,公开或私有均可。
提示
命名层别名
自动扫描的层(来自你的 ~~/layers
目录)会自动创建别名。例如,你可以通过 #layers/test
访问 ~~/layers/test
层。
如果你想为其他层创建命名别名,可以在该层的配置中指定一个名称。
export default defineNuxtConfig({
$meta: {
name: 'example',
},
})
这将生成一个指向你层的 #layers/example
别名。
相对路径与别名
在层的组件和 composables 中使用全局别名(例如 ~/
和 @/
)进行导入时,请注意这些别名是相对于使用者项目路径解析的。作为解决方法,你可以使用相对路径来导入它们,或使用命名层别名。
另外,在层的 nuxt.config
文件中使用相对路径时(嵌套 extends
除外),这些路径相对于使用者项目而不是层本身解析。作为解决方法,在 nuxt.config
中使用完整解析后的路径:
import { fileURLToPath } from 'node:url'
import { dirname, join } from 'node:path'
const currentDir = dirname(fileURLToPath(import.meta.url))
export default defineNuxtConfig({
css: [
join(currentDir, './app/assets/main.css'),
],
})
Nuxt 模块的多层支持
你可以使用内部数组 nuxt.options._layers
来为你的模块支持自定义的多层处理。
export default defineNuxtModule({
setup (_options, nuxt) {
for (const layer of nuxt.options._layers) {
// You can check for a custom directory existence to extend for each layer
console.log('Custom extension for', layer.cwd, layer.config)
}
},
})
注意:
_layers
数组中较早的项具有更高优先级,会覆盖后面的项- 使用者的项目是
_layers
数组中的第一项
深入了解
配置加载和 extends 支持由 unjs/c12 处理,合并使用 unjs/defu,远程 git 源则通过 unjs/giget 支持。查看文档和源代码以了解更多信息。