Lzh on GitHub

Authoring Nuxt Layers

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

Nuxt Layers 是一个强大的特性,你可以使用它在 monorepo 中或从 git 仓库或 npm 包中共享和重用部分 Nuxt 应用程序。Layers 的结构几乎与标准的 Nuxt 应用程序完全相同,这使得它们易于编写和维护。

Read more in Docs > Getting Started > Layers.

一个最简化的 Nuxt Layer 目录应该包含一个 nuxt.config.ts 文件来表明它是一个 Layer。

base/nuxt.config.ts
export default defineNuxtConfig({})

此外,Layer 目录中的某些其他文件将被 Nuxt 自动扫描并用于扩展此 Layer 的项目。

基础示例

export default defineNuxtConfig({
  extends: [
    './base'
  ]
})

启动模板

要开始使用,你可以使用 nuxt/starter/layer 模板 初始化一个 Layer。这将创建一个你可以构建的基本结构。在终端中执行以下命令以开始:

Terminal
npm create nuxt -- --template layer nuxt-layer

请按照 README 中的说明进行后续步骤。

发布 Layers

你可以通过使用远程源或 npm 包来发布和共享 Layers。

Git 仓库

你可以使用 git 仓库来共享你的 Nuxt Layer。一些示例:

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    'github:username/repoName',        // GitHub Remote Source
    'github:username/repoName/base',   // GitHub Remote Source within /base directory
    'github:username/repoName#dev',    // GitHub Remote Source from dev branch
    'github:username/repoName#v1.0.0', // GitHub Remote Source from v1.0.0 tag
    'gitlab:username/repoName',        // GitLab Remote Source example
    'bitbucket:username/repoName',     // Bitbucket Remote Source example
  ]
})
如果要扩展私有远程源,你需要添加环境变量 GIGET_AUTH=<token> 来提供令牌。
如果要从自托管的 GitHub 或 GitLab 实例扩展远程源,你需要使用 GIGET_GITHUB_URL=<url>GIGET_GITLAB_URL=<url> 环境变量提供其 URL,或者直接使用 nuxt.config 中的 auth 选项 进行配置。
请记住,如果将远程源作为 Layer 扩展,你将无法在 Nuxt 之外访问其依赖项。例如,如果远程 Layer 依赖于一个 eslint 插件,则该插件在你的 eslint 配置中将不可用。这是因为这些依赖项将位于一个特殊的位置 (node_modules/.c12/layer_name/node_modules/),你的包管理器无法访问该位置。
当使用 git 远程源时,如果 Layer 有 npm 依赖项并且你希望安装它们,可以通过在 Layer 选项中指定 install: true 来完成。
nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    ['github:username/repoName', { install: true }]
  ]
})

npm 包

你可以将 Nuxt Layers 作为 npm 包发布,其中包含你想要扩展的文件和依赖项。这允许你与他人共享你的配置,在多个项目中使用它或私下使用它。

要从 npm 包扩展,你需要确保该模块已发布到 npm 并作为 devDependency 安装在用户的项目中。然后你可以使用模块名称来扩展当前的 nuxt 配置:

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    // Node Module with scope
    '@scope/moduleName',
    // or just the module name
    'moduleName'
  ]
})

要将 Layer 目录作为 npm 包发布,你需要确保 package.json 中填写了正确的属性。这将确保在发布包时包含这些文件。

package.json
{
  "name": "my-theme",
  "version": "1.0.0",
  "type": "module",
  "main": "./nuxt.config.ts",
  "dependencies": {},
  "devDependencies": {
    "nuxt": "^3.0.0"
  }
}

确保在 Layer 中导入的任何依赖项都 显式 添加到 dependencies 中。nuxt 依赖项以及任何仅在发布前用于测试 Layer 的依赖项应保留在 devDependencies 字段中。

现在你可以继续将模块发布到 npm,无论是公开还是私下。

当将 Layer 作为私有 npm 包发布时,你需要确保登录以通过 npm 进行身份验证,从而下载 node 模块。

提示

命名 Layer 别名

自动扫描的 Layers(来自你的 ~~/layers 目录)会自动创建别名。例如,你可以通过 #layers/test 访问你的 ~~/layers/test Layer

如果想为其他 Layers 创建命名 Layer 别名,可以在 Layer 的配置中指定一个名称。

nuxt.config.ts
export default defineNuxtConfig({
  $meta: {
    name: 'example',
  },
})

这将生成一个指向你的 Layer 的别名 #layers/example

相对路径和别名

在 Layer 的组件和 composables 中使用全局别名(例如 ~/@/)进行导入时,请注意这些别名是相对于用户项目的路径解析的。作为一种解决方法,你可以 使用相对路径 导入它们,或使用命名的 Layer 别名。

此外,当在 Layer 的 nuxt.config 文件中使用相对路径时(嵌套的 extends 除外),它们是相对于用户的项目而不是 Layer 解析的。作为一种解决方法,请在 nuxt.config 中使用完整的解析路径:

nuxt.config.ts
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'

const currentDir = dirname(fileURLToPath(import.meta.url))

export default defineNuxtConfig({
  css: [
    join(currentDir, './assets/main.css')
  ]
})

Nuxt 模块的多层支持

你可以使用内部数组 nuxt.options._layers 来支持你的模块的自定义多层处理。

modules/my-module.ts
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 支持。查看文档和源代码以了解更多信息。

查看我们在 GitHub 上进行的持续开发,以进一步改进对 Layers 的支持。