---
title: "shared"
description: "使用 shared/ 目录在 Vue 应用和 Nitro 服务器之间共享功能。"
canonical_url: "https://nuxt.zhcndoc.com/docs/4.x/directory-structure/shared"
---
# shared

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

`shared/` 目录允许你共享可在 Vue 应用和 Nitro 服务器中使用的代码。

::note
`shared/` 目录在 Nuxt v3.14+ 中可用。
::

::important
`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 为应用、服务器和共享代码分别设置的[类型上下文](https://nuxt.zhcndoc.com/docs/4.x/guide/concepts/typescript#project-references)保持一致。

只在一个上下文中使用的类型也可以放在对应上下文旁边：`app/types/` 只会在 Vue 应用中自动导入，[`server/types/`](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/server#server-types) 只会在 Nitro 服务器中自动导入。需要在两者中使用的类型则放在 `shared/types/` 中。

::video-accordion{title="观看 Vue School 关于在应用和服务器之间共享工具函数与类型的视频" videoId="nnAR-MO3q5M"}
::

## 用法

**方法 1：** 命名导出

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

**方法 2：** 默认导出

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

现在，你可以在 Nuxt 应用和 `server/` 目录中使用[自动导入](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/shared)的工具函数。

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

<template>
  <div>
    {{ hello }}
  </div>
</template>
```

```ts [server/api/hello.get.ts]
export default defineEventHandler((event) => {
  return {
    hello: capitalize('hello'),
  }
})
```

## 文件如何被扫描

只有位于 `shared/utils/` 和 `shared/types/` 目录下的文件会被自动导入。位于这些目录子目录中的文件不会被自动导入，除非你将这些子目录添加到 `imports.dirs` 和 `nitro.imports.dirs`。

::tip
`shared/utils` 和 `shared/types` 的自动导入工作方式及扫描方式，与 [`app/composables/`](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/composables) 和 [`app/utils/`](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/utils) 目录完全相同。
::

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/composables#how-files-are-scanned"}
::

```bash [Directory Structure]
-| shared/
---| capitalize.ts        # 不会自动导入
---| formatters
-----| lower.ts           # 不会自动导入
---| utils/
-----| lower.ts           # 自动导入
-----| formatters
-------| upper.ts         # 不会自动导入
---| types/
-----| bar.ts             # 自动导入
```

你在 `shared/` 文件夹中创建的其他任何文件，都必须使用 `#shared` 别名手动导入（该别名由 Nuxt 自动配置）：

```ts [Importing From #shared]
// For files directly in the shared directory
import capitalize from '#shared/capitalize'

// 对于位于子目录中的文件
import lower from '#shared/formatters/lower'

// 对于 utils 内某文件夹中的文件
import upper from '#shared/utils/formatters/upper'
```

此别名确保无论导入文件位置在哪里，导入路径都保持一致。

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/guide/concepts/auto-imports"}
::


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
