Nuxt 层是一个强大的功能,可以让你在 monorepo 内部,或者从 git 仓库或 npm 包中共享和重用部分 Nuxt 应用。层的结构几乎与标准的 Nuxt 应用相同,使其易于编写和维护。
一个最小的 Nuxt 层目录应该包含一个 nuxt.config.ts 文件,以标明它是一个层。
export default defineNuxtConfig({})
此外,层目录中的某些其他文件将会被 Nuxt 自动扫描,并用于扩展此层的项目。
components/* - 扩展默认组件composables/* - 扩展默认组合式函数layouts/* - 扩展默认布局middleware/* - 扩展默认中间件pages/* - 扩展默认页面plugins/* - 扩展默认插件server/* - 扩展默认服务器端点和中间件utils/* - 扩展默认工具函数nuxt.config.ts - 扩展默认 Nuxt 配置app.config.ts - 扩展默认应用配置export default defineNuxtConfig({
extends: [
'./base',
],
})
<template>
<BaseComponent />
</template>
export default defineNuxtConfig({
// 继承自 base nuxt.config.ts!
app: {
head: {
title: '扩展配置很有趣!',
meta: [
{ name: 'description', content: '我正在使用 Nuxt 的 extends 功能!' }
],
}
}
})
<template>
<h1>扩展组件很有趣!</h1>
</template>
当从多个层扩展时,理解覆盖顺序非常重要。定义相同文件或组件时,优先级较高的层会覆盖优先级较低的层。
优先级从高到低为:
~~/layers 目录的自动扫描层 - 按字母顺序排序(Z 的优先级比 A 高)extends 层 - 第一项优先级高于第二项extends - 用于外部依赖(npm 包、远程仓库)或项目目录外的层~~/layers 目录 - 用于项目内部的本地层~/layers/1.z-layer,~/layers/2.a-layer。这样 2.a-layer 的优先级会高于 1.z-layer。export default defineNuxtConfig({
extends: [
// 项目外部的本地层
'../base',
// NPM 包
'@my-themes/awesome',
// 远程仓库
'github:my-themes/awesome#v1',
],
})
如果你同时有 ~~/layers/custom,优先级顺序为:
~~/layers/custom../base@my-themes/awesomegithub:my-themes/awesome#v1(最低)这意味着你的项目文件会覆盖任何层,~~/layers/custom 会覆盖 extends 中的任何内容。
要开始使用,你可以通过 nuxt/starter/layer 模板 初始化一个层。这将创建一个基本结构供你构建。打开终端执行以下命令开始:
npm create nuxt -- --template layer nuxt-layer
接着按照 README 中的说明执行下一步操作。
你可以通过远程资源或 npm 包来发布和分享层。
你可以使用 git 仓库来共享你的 Nuxt 层。示例如下:
export default defineNuxtConfig({
extends: [
'github:username/repoName', // GitHub 远程源
'github:username/repoName/base', // GitHub 远程源中的 /base 目录
'github:username/repoName#dev', // 来自 dev 分支的 GitHub 远程源
'github:username/repoName#v1.0.0', // 来自 v1.0.0 标签的 GitHub 远程源
'gitlab:username/repoName', // GitLab 远程源示例
'bitbucket:username/repoName', // Bitbucket 远程源示例
],
})
GIGET_AUTH=<token> 来提供访问令牌。GIGET_GITHUB_URL=<url> 或 GIGET_GITLAB_URL=<url> 提供其 URL,或者在你的 nuxt.config 中直接配置 auth 选项。node_modules/.c12/layer_name/node_modules/),你的包管理器无法访问。install: true。export default defineNuxtConfig({
extends: [
['github:username/repoName', { install: true }],
],
})
你可以将 Nuxt 层作为一个包含你想扩展的文件和依赖的 npm 包发布。这样可以与你人共享配置,在多个项目中使用,或私人使用。
要从 npm 包扩展,需要确保该模块已经发布至 npm 并作为 devDependency 安装在用户项目中。然后你就可以使用模块名称来扩展当前的 Nuxt 配置:
export default defineNuxtConfig({
extends: [
// 带作用域的模块
'@scope/moduleName',
// 或者仅模块名称
'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 指向你的层。
在层的组件和组合函数中使用全局别名(如 ~/ 和 @/)进行导入时,注意这些别名是相对于用户项目路径解析的。作为解决方法,你可以使用相对路径导入,或者使用命名层别名。
此外,在层的 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, './assets/main.css'),
],
})
你可以使用 Nuxt Kit 的 getLayerDirectories 工具,为你的模块支持自定义多层处理。
import { defineNuxtModule, getLayerDirectories } from 'nuxt/kit'
export default defineNuxtModule({
setup (_options, nuxt) {
const layerDirs = getLayerDirectories()
for (const [index, layer] of layerDirs.entries()) {
console.log(`Layer ${index}:`)
console.log(` Root: ${layer.root}`)
console.log(` App: ${layer.app}`)
console.log(` Server: ${layer.server}`)
console.log(` Pages: ${layer.appPages}`)
// ... 其他目录
}
},
})
注意事项:
配置加载和 extends 支持由 unjs/c12 负责,合并使用 unjs/defu,远程 git 源支持使用了 unjs/giget。查看文档和源代码以了解更多信息。