编写 Nuxt 层

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

Nuxt 层是一项强大的功能,您可以用它在单一代码库中的部分 Nuxt 应用间共享和重用,或者从 git 仓库或 npm 包中共享。层的结构几乎与标准 Nuxt 应用相同,这使得它们易于编写和维护。

Read more in Docs > Getting Started > Layers.

一个最小的 Nuxt 层目录应该包含一个 nuxt.config.ts 文件,以指示这是一个层。

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

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

基本示例

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

启动模板

要开始,您可以通过 nuxt/starter/layer 模板 初始化一个层。这将创建一个基本结构,您可以在其上进行构建。在终端中执行此命令以开始:

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

请遵循 README 中的说明进行下一步。

发布层

您可以通过使用远程源或 npm 包来发布和分享层。

Git 仓库

您可以使用 git 仓库来共享您的 Nuxt 层。以下是一些示例:

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    'github:username/repoName',        // GitHub 远程源
    'github:username/repoName/base',   // GitHub 远程源,在 /base 目录中
    'github:username/repoName#dev',    // GitHub 远程源,从 dev 分支
    'github:username/repoName#v1.0.0', // GitHub 远程源,从 v1.0.0 标签
    'gitlab:username/repoName',        // GitLab 远程源示例
    'bitbucket:username/repoName',     // Bitbucket 远程源示例
  ]
})
如果您想要扩展一个私有远程源,需要添加环境变量 GIGET_AUTH=<token> 以提供令牌。
如果您想要扩展一个来自自托管 GitHub 或 GitLab 实例的远程源,您需要用 GIGET_GITHUB_URL=<url>GIGET_GITLAB_URL=<url> 环境变量提供其 URL - 或直接在 nuxt.config 中使用 auth 选项 进行配置。
请注意,如果您作为层扩展远程源,您将无法在 Nuxt 外部访问其依赖项。例如,如果远程层依赖于 eslint 插件,这将在您的 eslint 配置中无法使用。因为这些依赖项将位于一个特殊位置 (node_modules/.c12/layer_name/node_modules/),该位置对您的包管理器不可访问。
使用 git 远程源时,如果一个层具有 npm 依赖项,您希望安装它们,可以通过在层选项中指定 install: true 来实现。
nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    ['github:username/repoName', { install: true }]
  ]
})

npm 包

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

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

nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    // 带作用域的节点模块
    '@scope/moduleName',
    // 或者只是模块名称
    'moduleName'
  ]
})

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

package.json
{
  "name": "my-theme",
  "version": "1.0.0",
  "type": "module",
  "main": "./nuxt.config.ts",
  "dependencies": {},
  "devDependencies": {
    "nuxt": "^3.0.0"
  }
}
确保在层中导入的任何依赖项都明确添加dependenciesnuxt 依赖项以及任何仅用于发布前测试层的内容应保留在 devDependencies 字段中。

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

当将层作为私有 npm 包发布时,您需要确保您已登录,以便通过 npm 进行身份验证以下载节点模块。

提示

命名层别名

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

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

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

这将生成 #layers/example 的别名,指向您的层。

相对路径和别名

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

同样,在层的 nuxt.config 文件中使用相对路径时(嵌套 extends 的情况除外),它们是相对于用户项目解析,而不是层。作为一种解决方法,请在 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) {
      // 您可以检查每层是否存在自定义目录以扩展
      console.log('', layer.cwd, layer.config, '提供自定义扩展')
    }
  }
})

注意事项:

  • _layers 数组中的较早项优先级更高,并会覆盖后面的项
  • 用户项目是 _layers 数组中的第一个项

深入了解

配置加载和扩展支持由 unjs/c12 处理,通过 unjs/defu 进行合并,远程 git 源使用 unjs/giget 进行支持。查看文档和源代码以了解更多信息。

查看我们在 GitHub 上正在进行的开发,以带来更多层支持的改进。