diff --git a/.vitepress/config.ts b/.vitepress/config.ts index 6b26570d..b753356b 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -194,6 +194,10 @@ export default defineConfig({ { text: 'Releases', link: '/releases' }, { items: [ + { + text: 'Mastodon', + link: 'https://elk.zone/m.webtoo.ls/@vite', + }, { text: 'Twitter', link: 'https://twitter.com/vite_js', diff --git a/config/dep-optimization-options.md b/config/dep-optimization-options.md index 07f000a1..9b5ccbaa 100644 --- a/config/dep-optimization-options.md +++ b/config/dep-optimization-options.md @@ -8,7 +8,7 @@ 默认情况下,Vite 会抓取你的 `index.html` 来检测需要预构建的依赖项(忽略了`node_modules`、`build.outDir`、`__tests__` 和 `coverage`)。如果指定了 `build.rollupOptions.input`,Vite 将转而去抓取这些入口点。 -如果这两者都不合你意,则可以使用此选项指定自定义条目——该值需要遵循 [fast-glob 模式](https://github.com/mrmlnc/fast-glob#basic-syntax) ,或者是相对于 Vite 项目根目录的匹配模式数组。当显式声明了 `optimizeDeps.entries` 时默认只有 `node_modules` 和 `build.outDir` 文件夹会被忽略。如果还需忽略其他文件夹,你可以在模式列表中使用以 `!` 为前缀的、用来匹配忽略项的模式。 +如果这两者都不合你意,则可以使用此选项指定自定义条目——该值需要遵循 [fast-glob 模式](https://github.com/mrmlnc/fast-glob#basic-syntax) ,或者是相对于 Vite 项目根目录的匹配模式数组。当显式声明了 `optimizeDeps.entries` 时默认只有 `node_modules` 和 `build.outDir` 文件夹会被忽略。如果还需忽略其他文件夹,你可以在模式列表中使用以 `!` 为前缀的、用来匹配忽略项的模式。如果你不想忽略 `node_modules` 和 `build.outDir`,你可以选择直接使用字符串路径(不使用 fast-glob 模式)。 ## optimizeDeps.exclude {#optimizedeps-exclude} diff --git a/config/shared-options.md b/config/shared-options.md index b26aace5..85f3749d 100644 --- a/config/shared-options.md +++ b/config/shared-options.md @@ -292,6 +292,10 @@ export default defineConfig({ 该选项用于选择用于 CSS 处理的引擎。详细信息请查看 [Lightning CSS](../guide/features.md#lightning-css)。 +::: info 重复的 `@import` +需要注意的是,postcss(postcss-import)处理重复 `@import` 的行为与浏览器是不同的。详情请参考 [postcss/postcss-import#462](https://github.com/postcss/postcss-import/issues/462)。 +::: + ## css.lightningcss - **实验性:** [提供反馈](https://github.com/vitejs/vite/discussions/13835) diff --git a/guide/api-hmr.md b/guide/api-hmr.md index 64321028..a30e2018 100644 --- a/guide/api-hmr.md +++ b/guide/api-hmr.md @@ -218,7 +218,7 @@ import.meta.hot.accept((module) => { 如果在连接前调用,数据会先被缓存、等到连接建立好后再发送。 -查看 [客户端与服务器的数据交互](/guide/api-plugin.html#client-server-communication) 一节获取更多细节。 +查看 [客户端与服务端间通信](/guide/api-plugin.html#client-server-communication) 以及 [自定义事件的 TypeScript 类型定义指南](/guide/api-plugin.html#typescript-for-custom-events) 章节获取更多细节。 ## 推荐阅读 {#further-reading} diff --git a/guide/api-plugin.md b/guide/api-plugin.md index 837a9a42..f0fccc29 100644 --- a/guide/api-plugin.md +++ b/guide/api-plugin.md @@ -479,6 +479,8 @@ Vite 插件也可以提供钩子来服务于特定的 Vite 目标。这些钩子 - 带有 `enforce: 'post'` 的用户插件 - Vite 后置构建插件(最小化,manifest,报告) +请注意,这与钩子的排序是分开的,钩子的顺序仍然会受到它们的 `order` 属性的影响,这一点 [和 Rollup 钩子的表现一样](https://rollupjs.org/plugin-development/#build-hooks)。 + ## 情景应用 {#conditional-application} 默认情况下插件在开发(serve)和构建(build)模式中都会调用。如果插件只需要在预览或构建期间有条件地应用,请使用 `apply` 属性指明它们仅在 `'build'` 或 `'serve'` 模式时调用: @@ -622,16 +624,40 @@ export default defineConfig({ ### 自定义事件的 TypeScript 类型定义指南 {#typeScript-for-custom-events} -可以通过扩展 `CustomEventMap` 这个 interface 来为自定义事件标注类型: +Vite 会在内部从 `CustomEventMap` 这个接口推断出 payload 的类型,可以通过扩展这个接口来为自定义事件进行类型定义: + +:::tip 提示 +在指定 TypeScript 声明文件时,确保包含 `.d.ts` 扩展名。否则,TypeScript 可能不会知道试图扩展的是哪个文件。 +::: ```ts // events.d.ts -import 'vite/types/customEvent' +import 'vite/types/customEvent.d.ts' -declare module 'vite/types/customEvent' { +declare module 'vite/types/customEvent.d.ts' { interface CustomEventMap { 'custom:foo': { msg: string } // 'event-key': payload } } ``` + +这个接口扩展被 `InferCustomEventPayload` 所使用,用来推断事件 `T` 的 payload 类型。要了解更多关于这个接口如何被使用的信息,请参考 [HMR API 文档](./api-hmr#hmr-api)。 + +```ts twoslash +import 'vite/client' +import type { InferCustomEventPayload } from 'vite/types/customEvent.d.ts' +declare module 'vite/types/customEvent.d.ts' { + interface CustomEventMap { + 'custom:foo': { msg: string } + } +} +// ---cut--- +type CustomFooPayload = InferCustomEventPayload<'custom:foo'> +import.meta.hot?.on('custom:foo', (payload) => { + // payload 的类型为 { msg: string } +}) +import.meta.hot?.on('unknown:event', (payload) => { + // payload 的类型为 any +}) +``` diff --git a/guide/api-vite-runtime.md b/guide/api-vite-runtime.md index 82773430..a82b4ff3 100644 --- a/guide/api-vite-runtime.md +++ b/guide/api-vite-runtime.md @@ -1,7 +1,9 @@ # Vite 运行时 API {#vite-runtime-api} -:::warning 低级别 API -这个 API 在 Vite 5.1 中作为一个实验性特性引入。它被添加以 [收集反馈](https://github.com/vitejs/vite/discussions/15774)。在Vite 5.2 中,它可能会有破坏性的变化,所以在使用它时,请确保将 Vite 版本固定在 `~5.1.0`。这是一个面向库和框架作者的低级别 API。如果你的目标是开发应用,请确保首先查看 [Vite SSR 精选板块](https://github.com/vitejs/awesome-vite#ssr) 的高级 SSR 插件和工具。 +:::warning 底层 API +这个 API 在 Vite 5.1 中作为一个实验性特性引入。它被添加以 [收集反馈](https://github.com/vitejs/vite/discussions/15774)。在Vite 5.2 中,它可能会有破坏性的变化,所以在使用它时,请确保将 Vite 版本固定在 `~5.1.0`。这是一个面向库和框架作者的底层 API。如果你的目标是开发应用,请确保首先查看 [Vite SSR 精选板块](https://github.com/vitejs/awesome-vite#ssr) 的高级 SSR 插件和工具。 + +目前,这种 API 正在以 [环境 API](https://github.com/vitejs/vite/discussions/16358) 的形式进行修正,并在 `^6.0.0-alpha.0` 版本中发布。 ::: "Vite 运行时" 是一个工具,它允许首先用 Vite 插件处理任何代码后运行。它与 `server.ssrLoadModule` 不同,因为运行时实现是从服务器解耦的。这允许库和框架作者实现他们自己的服务器和运行时之间的通信层。 diff --git a/guide/backend-integration.md b/guide/backend-integration.md index 3490c464..19ffb4e3 100644 --- a/guide/backend-integration.md +++ b/guide/backend-integration.md @@ -62,24 +62,36 @@ ```json { - "main.js": { - "file": "assets/main.4889e940.js", - "src": "main.js", + "_shared-!~{003}~.js": { + "file": "assets/shared-ChJ_j-JJ.css", + "src": "_shared-!~{003}~.js" + }, + "_shared-B7PI925R.js": { + "file": "assets/shared-B7PI925R.js", + "name": "shared", + "css": ["assets/shared-ChJ_j-JJ.css"] + }, + "baz.js": { + "file": "assets/baz-B2H3sXNv.js", + "name": "baz", + "src": "baz.js", + "isDynamicEntry": true + }, + "views/bar.js": { + "file": "assets/bar-gkvgaI9m.js", + "name": "bar", + "src": "views/bar.js", "isEntry": true, - "dynamicImports": ["views/foo.js"], - "css": ["assets/main.b82dbe22.css"], - "assets": ["assets/asset.0ab0f9cd.png"], - "imports": ["_shared.83069a53.js"] + "imports": ["_shared-B7PI925R.js"], + "dynamicImports": ["baz.js"] }, "views/foo.js": { - "file": "assets/foo.869aea0d.js", + "file": "assets/foo-BRBmoGS9.js", + "name": "foo", "src": "views/foo.js", - "isDynamicEntry": true, - "imports": ["_shared.83069a53.js"] - }, - "_shared.83069a53.js": { - "file": "assets/shared.83069a53.js", - "css": ["assets/shared.a834bfc3.css"] + "isEntry": true, + "imports": ["_shared-B7PI925R.js"], + "css": ["assets/foo-5UjPuW-k.css"] } } ``` @@ -108,35 +120,35 @@ - + ``` 具体来说,一个生成 HTML 的后端在给定 manifest 文件和一个入口文件的情况下, 应该包含以下标签: - 对于入口文件 chunk 的 `css` 列表中的每个文件,都应包含一个 `` 标签。 - - 递归追踪入口文件的 `imports` 列表中的所有 chunk,并为每个导入的 chunk 的每个 css 文件 + - 递归追踪入口文件的 `imports` 列表中的所有 chunk,并为每个导入的 chunk 的每个 CSS 文件 包含一个 `` 标签。 - - 对于入口文件 chunk 的 `file` 键的标签(对于 Javascript 是 - ` + + + - + ``` - 而对于入口文件 `views/foo.js`,应该包含以下标签: + 而对于入口文件 `views/bar.js`,应该包含以下标签: ```html - - + + - + ``` diff --git a/guide/build.md b/guide/build.md index 8cbcbad8..18bd0f08 100644 --- a/guide/build.md +++ b/guide/build.md @@ -47,21 +47,7 @@ export default defineConfig({ ## 产物分块策略 {#chunking-strategy} -你可以通过配置 `build.rollupOptions.output.manualChunks` 来自定义 chunk 分割策略(查看 [Rollup 相应文档](https://rollupjs.org/configuration-options/#output-manualchunks))。在 Vite 2.8 及更早版本中,默认的策略是将 chunk 分割为 `index` 和 `vendor`。这对一些 SPA 来说是好的策略,但是要对所有应用场景提供一种通用解决方案是非常困难的。从 Vite 2.9 起,`manualChunks` 默认情况下不再被更改。你可以通过在配置文件中添加 `splitVendorChunkPlugin` 来继续使用 “分割 Vendor Chunk” 策略: - -```js -// vite.config.js -import { splitVendorChunkPlugin } from 'vite' -export default defineConfig({ - plugins: [splitVendorChunkPlugin()], -}) -``` - -也可以用一个工厂函数 `splitVendorChunk({ cache: SplitVendorChunkCache })` 来提供该策略,在需要与自定义逻辑组合的情况下,`cache.reset()` 需要在 `buildStart` 阶段被调用,以便构建的 watch 模式在这种情况下正常工作。 - -::: warning -你应该使用 `build.rollupOptions.output.manualChunks` 函数形式来使用此插件。如果使用对象形式,插件将不会生效。 -::: +你可以通过配置 `build.rollupOptions.output.manualChunks` 来自定义 chunk 分割策略(查看 [Rollup 相应文档](https://cn.rollupjs.org/configuration-options/#output-manualchunks))。如果你使用的是一个框架,那么请参考他们的文档来了解如何配置分割 chunk。 ## 处理加载报错 {#load-error-handling} @@ -271,24 +257,26 @@ experimental: { 如果 hash 后的资源和公共文件没有被部署在一起,可以根据该函数的第二个参数 `context` 上的字段 `type` 分别定义各个资源组的选项: + ```ts twoslash import type { UserConfig } from 'vite' import path from 'node:path' const config: UserConfig = { - // ---cut-before--- - experimental: { - renderBuiltUrl(filename, { hostId, hostType, type }) { - if (type === 'public') { - return 'https://www.domain.com/' + filename - } else if (path.extname(hostId) === '.js') { - return { runtime: `window.__assetsPath(${JSON.stringify(filename)})` } - } else { - return 'https://cdn.domain.com/assets/' + filename - } - }, +// ---cut-before--- +experimental: { + renderBuiltUrl(filename, { hostId, hostType, type }) { + if (type === 'public') { + return 'https://www.domain.com/' + filename + } else if (path.extname(hostId) === '.js') { + return { runtime: `window.__assetsPath(${JSON.stringify(filename)})` } + } else { + return 'https://cdn.domain.com/assets/' + filename + } }, - // ---cut-after--- +}, +// ---cut-after--- } ``` + 请注意,传递的 `filename` 是一个已解码的 URL,如果函数返回了一个 URL 字符串,那么它也应该是已解码的。当 Vite 渲染 URL 时会自动处理编码。如果返回的是一个带有 `runtime` 的对象,就需要在必要的地方自行处理编码,因为运行时的代码将会按照原样呈现。 diff --git a/guide/env-and-mode.md b/guide/env-and-mode.md index a29c2608..4323c16a 100644 --- a/guide/env-and-mode.md +++ b/guide/env-and-mode.md @@ -2,7 +2,7 @@ ## 环境变量 {#env-variables} -Vite 在一个特殊的 **`import.meta.env`** 对象上暴露环境变量。这里有一些在所有情况下都可以使用的内建变量: +Vite 在一个特殊的 **`import.meta.env`** 对象上暴露环境变量,这些变量在构建时会被静态地替换掉。这里有一些在所有情况下都可以使用的内建变量: - **`import.meta.env.MODE`**: {string} 应用运行的[模式](#modes)。 diff --git a/guide/features.md b/guide/features.md index 073c6de3..cb0d3db5 100644 --- a/guide/features.md +++ b/guide/features.md @@ -699,7 +699,7 @@ import MyWorker from './worker?worker&url' ### [`'nonce-{RANDOM}'`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#nonce-base64-value) -当设置了 [`html.cspNonce`](/config/shared-options#html-cspnonce) 时,Vite 会在输出的脚本标签和样式表的链接标签中添加一个带有指定值的 nonce 属性。请注意,Vite 不会将 nonce 属性添加到其他标签中,例如 `