--- 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 元素(例如 ` ``` 要禁用某些元素的 HTML 处理,你可以在元素上添加 `vite-ignore` 属性,这在引用外部资源或 CDN 时很有用。 ## 框架 所有现代框架都维护着与 Vite 的集成。大多数框架插件由各自的框架团队维护,除了由 vite 组织维护的官方 Vue 和 React Vite 插件: * 通过 [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue) 支持 Vue * 通过 [@vitejs/plugin-vue-jsx](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue-jsx) 支持 Vue JSX * 通过 [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react) 支持 React * 通过 [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react-swc) 支持使用 SWC 的 React * 通过 [@vitejs/plugin-rsc](https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-rsc) 支持 [React 服务端组件(RSC)](https://react.dev/reference/rsc/server-components) 查看[插件指南](/plugins/)以获取更多信息。 ## JSX `.jsx` 和 `.tsx` 文件也开箱即用地受支持。JSX 转译同样通过 [Oxc Transformer](https://oxc.rs/docs/guide/usage/transformer.html) 处理。 你选择的框架已经开箱即用地配置了 JSX(例如,Vue 用户应该使用官方的 [@vitejs/plugin-vue-jsx](https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx) 插件,它提供了 Vue 3 特定功能,包括 HMR、全局组件解析、指令和插槽)。 如果在自己的框架中使用 JSX,可以使用 [`oxc` 选项](/config/shared-options.md#oxc) 配置自定义 `jsxFactory` 和 `jsxFragment`。例如,Preact 插件将使用: ```js twoslash [vite.config.js] import { defineConfig } from 'vite' export default defineConfig({ oxc: { jsx: { importSource: 'preact', }, }, }) ``` 更多详情见 [Oxc Transformer 文档](https://oxc.rs/docs/guide/usage/transformer/jsx.html)。 你可以使用 `jsxInject`(这是 Vite 独有的选项)注入 JSX 辅助函数,以避免手动导入: ```js twoslash [vite.config.js] import { defineConfig } from 'vite' export default defineConfig({ oxc: { jsxInject: `import React from 'react'`, }, }) ``` ## CSS 导入 `.css` 文件会通过 `