---
url: /guide/features.md
---
# 特性
在最基本的层面上,使用 Vite 进行开发与使用静态文件服务器并没有太大不同。然而,Vite 在原生 ESM 导入之上提供了许多增强功能,以支持通常在基于打包器的设置中看到的各种特性。
## npm 依赖解析和预构建
原生 ES 导入不支持如下所示的裸模块导入:
```js
import { someMethod } from 'my-dep'
```
上述导入会在浏览器中抛出错误。Vite 会在所有提供的源文件中检测此类裸模块导入,并执行以下操作:
1. [预构建](./dep-pre-bundling) 它们以提高页面加载速度,并将 CommonJS / UMD 模块转换为 ESM。预构建步骤使用 [Rolldown](https://rolldown.rs/) 执行,使得 Vite 的冷启动时间比任何基于 JavaScript 的打包器都快得多。
2. 将导入重写为有效的 URL,如 `/node_modules/.vite/deps/my-dep.js?v=f3sf2ebd`,以便浏览器可以正确导入它们。
**依赖项被强缓存**
Vite 通过 HTTP 头缓存依赖请求,因此如果你希望在本地编辑/调试依赖项,请按照 [这里](./dep-pre-bundling#browser-cache) 的步骤操作。
## 热模块替换
Vite 在原生 ESM 之上提供了 [HMR API](./api-hmr)。具有 HMR 能力的框架可以利用该 API 提供即时、精确的更新,而无需重新加载页面或清除应用状态。Vite 为 [Vue 单文件组件](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue) 和 [React 快速刷新](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react) 提供了官方 HMR 集成。还有通过 [@prefresh/vite](https://github.com/JoviDeCroock/prefresh/tree/main/packages/vite) 提供的 Preact 官方集成。
请注意,你不需要手动设置这些——当你 [通过 `create-vite` 创建应用](./) 时,所选的模板已经为你预配置好了这些。
## TypeScript
Vite 支持开箱即用地导入 `.ts` 文件。
### 仅转译
请注意,Vite 仅对 `.ts` 文件执行转译,**不**执行类型检查。它假设类型检查由你的 IDE 和构建过程负责。
Vite 不在转换过程中执行类型检查的原因是,这两项工作从根本上说是不同的。转译可以基于每个文件进行,并与 Vite 的按需编译模型完美契合。相比之下,类型检查需要了解整个模块图。强行将类型检查塞入 Vite 的转换管道将不可避免地损害 Vite 的速度优势。
Vite 的工作是尽快将你的源模块转换为可以在浏览器中运行的形式。为此,我们建议将静态分析检查与 Vite 的转换管道分开。这一原则也适用于其他静态分析检查,例如 ESLint。
* 对于生产构建,你可以在 Vite 的构建命令之外运行 `tsc --noEmit`。
* 在开发期间,如果你需要比 IDE 提示更多的功能,我们建议在单独的进程中运行 `tsc --noEmit --watch`,或者如果你更喜欢直接在浏览器中报告类型错误,可以使用 [vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker)。
Vite 使用 [Oxc Transformer](https://oxc.rs/docs/guide/usage/transformer.html) 将 TypeScript 转译为 JavaScript,这比原生 `tsc` 更快,HMR 更新可以在 50 毫秒内在浏览器中反映出来。
使用 [仅类型导入和导出](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export) 语法以避免潜在问题,例如仅类型导入被错误地打包,例如:
```ts
import type { T } from 'only/types'
export type { T }
```
### TypeScript 编译器选项
默认情况下,Vite 会尊重 `tsconfig.json` 中的一些选项,并设置相应的 Oxc Transformer 选项。对于每个文件,Vite 会使用与该文件匹配的最近父级 `tsconfig.json`,或者使用其 [`references`](https://www.typescriptlang.org/tsconfig/#references) 字段中引用的、与该文件匹配的配置。当文件满足配置中的 [`files`](https://www.typescriptlang.org/tsconfig/#files)、[`include`](https://www.typescriptlang.org/tsconfig/#include) 和 [`exclude`](https://www.typescriptlang.org/tsconfig/#exclude) 字段时,Vite 会将该配置视为与该文件匹配。
当选项同时在 Vite 配置和 `tsconfig.json` 中设置时,Vite 配置中的值优先。
`tsconfig.json` 中 `compilerOptions` 下的一些配置字段需要特别注意。
#### `isolatedModules`
* [TypeScript 文档](https://www.typescriptlang.org/tsconfig#isolatedModules)
应设置为 `true`。
这是因为 Oxc transformer 仅执行转译而不包含类型信息,它不支持某些功能,如 const enum 和隐式仅类型导入。
你必须在 `tsconfig.json` 的 `compilerOptions` 下设置 `"isolatedModules": true`,这样 TS 会针对不与隔离转译一起工作的功能向你发出警告。
如果某个依赖项与 `"isolatedModules": true` 配合不佳,你可以使用 `"skipLibCheck": true` 暂时抑制错误,直到上游修复。
#### `useDefineForClassFields`
* [TypeScript 文档](https://www.typescriptlang.org/tsconfig#useDefineForClassFields)
如果 TypeScript 目标是 `ES2022` 或更新版本(包括 `ESNext`),默认值将为 `true`。这与 [TypeScript 4.3.2+ 的行为](https://github.com/microsoft/TypeScript/pull/42663) 一致。
其他 TypeScript 目标默认为 `false`。
`true` 是标准的 ECMAScript 运行时行为。
如果你使用的库严重依赖类字段,请注意该库的预期用法。
虽然大多数库期望 `"useDefineForClassFields": true`,但如果你的库不支持它,你可以显式地将 `useDefineForClassFields` 设置为 `false`。
#### `target`
* [TypeScript 文档](https://www.typescriptlang.org/tsconfig#target)
Vite 会忽略 `tsconfig.json` 中的 `target` 值,遵循与 [esbuild](https://esbuild.github.io/) 相同的行为。
要在开发中指定目标,可以使用 [`oxc.target`](/config/shared-options.html#oxc) 选项,该选项默认为 `esnext` 以实现最小化转译。在构建中,[`build.target`](/config/build-options.html#build-target) 选项优先于 `oxc.target`,如果需要也可以设置。
#### `emitDecoratorMetadata`
* [TypeScript 文档](https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata)
此选项仅部分支持。完整支持需要 TypeScript 编译器进行类型推断,而这并不受支持。详情请参见 [Oxc Transformer 的文档](https://oxc.rs/docs/guide/usage/transformer/typescript.html#decorators)。
#### `paths`
* [TypeScript 文档](https://www.typescriptlang.org/tsconfig/#paths)
[`resolve.tsconfigPaths: true`](/config/shared-options.md#resolve-tsconfigpaths) 可以指定,以告诉 Vite 使用 `tsconfig.json` 中的 `paths` 选项来解析导入。
请注意,此功能有性能开销,并且 [TypeScript 团队不推荐使用此选项来更改外部工具的行为](https://www.typescriptlang.org/tsconfig/#paths:~:text=Note%20that%20this%20feature%20does%20not%20change%20how%20import%20paths%20are%20emitted%20by%20tsc%2C%20so%20paths%20should%20only%20be%20used%20to%20inform%20TypeScript%20that%20another%20tool%20has%20this%20mapping%20and%20will%20use%20it%20at%20runtime%20or%20when%20bundling.)。
#### 其他影响构建结果的编译器选项
* [`extends`](https://www.typescriptlang.org/tsconfig#extends)
* [`importsNotUsedAsValues`](https://www.typescriptlang.org/tsconfig#importsNotUsedAsValues)
* [`preserveValueImports`](https://www.typescriptlang.org/tsconfig#preserveValueImports)
* [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax)
* [`jsx`](https://www.typescriptlang.org/tsconfig#jsx)
* [`jsxFactory`](https://www.typescriptlang.org/tsconfig#jsxFactory)
* [`jsxFragmentFactory`](https://www.typescriptlang.org/tsconfig#jsxFragmentFactory)
* [`jsxImportSource`](https://www.typescriptlang.org/tsconfig#jsxImportSource)
* [`experimentalDecorators`](https://www.typescriptlang.org/tsconfig#experimentalDecorators)
::: tip `skipLibCheck`
Vite 入门模板默认将 `"skipLibCheck": true`,以避免对依赖进行类型检查,因为它们可能只支持 TypeScript 的特定版本和配置。你可以在 [vuejs/vue-cli#5688](https://github.com/vuejs/vue-cli/pull/5688) 了解更多。
:::
### 客户端类型
Vite 的默认类型是针对其 Node.js API 的。为了补充 Vite 应用中客户端代码的环境,你可以在 `tsconfig.json` 内的 `compilerOptions.types` 中添加 `vite/client`:
```json [tsconfig.json]
{
"compilerOptions": {
"types": ["vite/client", "some-other-global-lib"]
}
}
```
请注意,如果指定了 [`compilerOptions.types`](https://www.typescriptlang.org/tsconfig#types),则只有这些包将包含在全局作用域中(而不是所有可见的 "@types" 包)。自 TS 5.9 以来推荐这样做。
::: details 使用三斜杠指令
或者,你可以添加一个 `d.ts` 声明文件:
```typescript [vite-env.d.ts]
///
```
:::
`vite/client` 提供以下类型补充:
* 资源导入(例如导入 `.svg` 文件)
* `import.meta.env` 上 Vite 注入的 [常量](./env-and-mode#env-variables) 的类型
* `import.meta.hot` 上 [HMR API](./api-hmr) 的类型
::: tip
要覆盖默认类型,添加一个包含你的类型定义的类型定义文件。然后,在 `vite/client` 之前添加类型引用。
例如,要使 `*.svg` 的默认导入成为 React 组件:
* `vite-env-override.d.ts`(包含你的类型定义的文件):
```ts
declare module '*.svg' {
const content: React.FC>
export default content
}
```
* 如果你使用 `compilerOptions.types`,确保文件包含在 `tsconfig.json` 中:
```json [tsconfig.json]
{
"include": ["src", "./vite-env-override.d.ts"]
}
```
* 如果你使用三斜杠指令,更新包含对 `vite/client` 引用的文件(通常是 `vite-env.d.ts`):
```ts
///
///
```
:::
## HTML
HTML 文件在 Vite 项目中占据 [核心位置](/guide/#index-html-and-project-root),作为应用的入口点,使得构建单页和 [多页应用](/guide/build.html#multi-page-app) 变得简单。
项目根目录中的任何 HTML 文件都可以通过其各自的目录路径直接访问:
* `/index.html` -> `http://localhost:5173/`
* `/about.html` -> `http://localhost:5173/about.html`
* `/blog/index.html` -> `http://localhost:5173/blog/index.html`
HTML 元素(例如 `