shared

使用 shared/ 目录在 Vue 应用和 Nitro 服务器之间共享功能。

shared/ 目录允许你共享可同时用于 Vue 应用和 Nitro 服务器的代码。

shared/ 目录在 Nuxt v3.14+ 中可用。
shared/ 目录中的代码不能导入任何 Vue 或 Nitro 代码。

为什么不能混合编写 Vue 和 Nitro 代码

Nuxt 会构建两个独立的打包产物:Vue 应用(客户端和服务器端渲染)以及 Nitro 服务器(API 路由、服务器中间件、服务器插件)。它们是独立打包并在不同上下文中运行的。shared/ 目录中的代码会被这两个产物同时使用,因此它不能从任何一方导入代码。

在 Nitro 中使用 Vue 应用代码

组件和组合式函数需要 Vue 应用的运行时,并且通常需要 Nuxt 上下文(例如 useNuxtApp()useRoute()),而这些在 Nitro 中都不存在。将它们导入服务器代码会导致构建或运行时错误,并可能将 Vue 应用的依赖项引入你的服务器打包产物中。

在 Vue 应用中使用 Nitro 代码

仅限服务器运行的代码(如 Node API、Nitro 工具函数或服务器路由处理程序)绝不能在浏览器中运行。将其导入你的应用可能会破坏客户端构建、导致浏览器中的运行时错误,或者将服务器逻辑泄露到客户端打包产物中。

仅类型导入

import type 在编译时会被擦除,不会将运行时代码引入另一个产物中,因此跨边界仅导入类型可能看起来可行。即便如此,仍建议将共享类型(如 API 响应类型)放在 shared/types/ 中,它们会在两种上下文中被自动导入。这能保持边界清晰,避免以后不小心将类型导入变成值导入,并且符合 Nuxt 针对应用、服务器和共享代码的独立 类型上下文

使用

方法 1:具名导出

shared/utils/capitalize.ts
export const capitalize = (input: string) => {
  return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}

方法 2:默认导出

shared/utils/capitalize.ts
export default function (input: string) {
  return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}

现在你可以在 Nuxt 应用和 server/ 目录中使用 自动导入的 工具函数了。

app/app.vue
<script setup lang="ts">
const hello = capitalize('hello')
</script>

<template>
  <div>
    {{ hello }}
  </div>
</template>
server/api/hello.get.ts
export default defineEventHandler((event) => {
  return {
    hello: capitalize('hello'),
  }
})

文件是如何被扫描的

只有 shared/utils/shared/types/ 目录中的文件会被自动导入。这些目录的子目录中嵌套的文件将不会被自动导入,除非你将这些目录添加到 imports.dirsnitro.imports.dirs 中。

shared/utilsshared/types 的自动导入工作方式及扫描方式与 app/composables/app/utils/ 目录完全相同。
阅读更多内容,请参见 文档 > 4 X > 目录结构 > App > Composables#how Files Are Scanned
目录结构
-| shared/
---| capitalize.ts        # Not auto-imported
---| formatters
-----| lower.ts           # Not auto-imported
---| utils/
-----| lower.ts           # Auto-imported
-----| formatters
-------| upper.ts         # Not auto-imported
---| types/
-----| bar.ts             # Auto-imported

你在 shared/ 文件夹中创建的任何其他文件,都必须使用 #shared 别名(由 Nuxt 自动配置)进行手动导入

从 #shared 导入
// For files directly in the shared directory
import capitalize from '#shared/capitalize'

// For files in nested directories
import lower from '#shared/formatters/lower'

// For files nested in a folder within utils
import upper from '#shared/utils/formatters/upper'

该别名可确保整个应用程序中的导入保持一致,无论导入文件的位置在哪里。

文档 > 4 X > 指南 > 概念 > 自动导入中了解更多信息。