跳到主要内容

Layers

Nuxt 提供了一套强大的系统,允许你扩展默认文件、配置以及更多内容。

Nuxt 的核心特性之一是对 layers(层)和扩展的支持。你可以扩展默认的 Nuxt 应用来复用组件、工具函数(utils)和配置。layer 的结构与标准 Nuxt 应用几乎一致,因此很容易编写和维护。

使用场景(Use Cases)

  • 使用 nuxt.configapp.config 在多个项目间共享可复用的配置预设
  • 使用 app/components/ 目录创建组件库
  • 使用 app/composables/app/utils/ 目录创建工具函数与 composable 库
  • 创建 Nuxt 模块预设
  • 在多个项目间共享标准设置
  • 创建 Nuxt 主题
  • 通过实现模块化架构并支持大型项目中的领域驱动设计(DDD)模式来增强代码组织

用法(Usage)

默认情况下,你项目中 ~~/layers 目录内的任何 layer 都会自动注册为项目中的 layer。

layer 自动注册功能在 Nuxt v3.12.0 中引入。

此外,会自动为每个 layer 的 srcDir 创建命名的 layer 别名。例如,你将能够通过 #layers/test 访问 ~~/layers/test 这个 layer。

命名 layer 别名功能在 Nuxt v3.16.0 中引入。

此外,你可以通过向 nuxt.config 文件添加 extends 属性来从一个 layer 扩展。

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    // 从本地 layer 扩展
    '../base',
    // 从已安装的 npm 包扩展
    '@my-themes/awesome',
    // 从 git 仓库扩展
    'github:my-themes/awesome#v1',
  ],
})

如果你从私有的 GitHub 仓库扩展,也可以传入认证令牌:

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    // 每个 layer 的配置
    ['github:my-themes/private-awesome', { auth: process.env.GITHUB_TOKEN }],
  ],
})
如果未指定分支,将克隆 main 分支。
你可以通过在 layer 源旁边的 options 中指定别名来覆盖该 layer 的别名。
nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    [
      'github:my-themes/awesome',
      {
        meta: {
          name: 'my-awesome-theme',
        },
      },
    ],
  ],
})

Nuxt 使用 unjs/c12unjs/giget 来扩展远程 layer。请查看文档以获取更多信息和所有可用选项。

Layer 优先级(Layer Priority)

使用多个 layer 时,理解覆盖顺序很重要。当它们定义了相同的文件或组件时,优先级更高的 layer 会覆盖优先级更低的 layer。

优先级顺序(Priority Order)

从高到低:

  1. 你的项目文件 - 始终具有最高优先级
  2. 来自 ~~/layers 目录的自动扫描 layer - 按字母顺序排序(Z 优先级高于 A)
  3. extends 配置中的 layer - 第一个条目优先级高于第二个

实际示例(Practical Example)

考虑多个 layer 定义了相同的组件:

Directory structure
layers/
  1.base/
    app/components/Button.vue    # 基础按钮样式
  2.theme/
    app/components/Button.vue    # 主题按钮(覆盖基础)
app/
  components/Button.vue          # 项目按钮(覆盖所有 layer)

在这种情况下:

  • 如果只有 layer 存在,会使用 2.theme/Button.vue(字母顺序更靠后)
  • 如果你的项目中存在 app/components/Button.vue,它会覆盖所有 layer

控制优先级(Controlling Priority)

你可以给 layer 目录加数字前缀来控制顺序:

Directory structure
layers/
  1.base/        # 最低优先级
  2.features/    # 中等优先级
  3.admin/       # 最高优先级(在 layer 中)
这种模式适用于创建带有默认值的基础 layer,然后由更具体的 layer 逐步覆盖。

另外,你可以通过在 nuxt.configextends 中引用 ~~/layers 目录,来控制它们的顺序,而无需重命名目录。这些条目像其他 extends layer 一样排序,第一个条目优先级最高

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    '~~/layers/admin', // 最高优先级
    '~~/layers/features',
    '~~/layers/base', // 最低优先级(在列出的 layer 中)
  ],
})

~~/...(推荐)和 ~/... 别名形式以及相对路径(./layers/admin)都受支持。任何你在 ~~/layers 中没有列出的 layer 会保留其字母自动扫描顺序,排名低于你在 extends 中列出的 layer。

何时使用哪种(When to Use Each)

  • ~~/layers 目录 - 用于属于你项目的本地 layer
  • extends - 用于外部依赖(npm 包、远程仓库)或项目目录之外的 layer

完整的 extends 示例(Full Example with extends

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    '../base', // 项目外的本地 layer
    '@my-themes/awesome', // npm 包
    'github:my-themes/awesome#v1', // 远程仓库
  ],
})

如果你还有 ~~/layers/custom,优先级顺序是:

  • 你的项目文件(最高)
  • ~~/layers/custom
  • ../base
  • @my-themes/awesome
  • github:my-themes/awesome#v1(最低)

了解关于 layers/ 目录 的内容,以在组织与共享可复用代码、组件、composable 和配置方面组织你的 Nuxt 应用。

Layer 作者指南 中阅读更多关于 layer 的内容。