跳至内容

生产环境构建

当您需要将应用程序部署到生产环境时,只需运行 vite build 命令。默认情况下,它使用 <root>/index.html 作为构建入口点,并生成一个适合在静态托管服务上提供的应用程序包。查看 部署静态网站 以获取有关流行服务的指南。

浏览器兼容性

生产环境包假设支持现代 JavaScript。默认情况下,Vite 针对支持 原生 ES 模块原生 ESM 动态导入import.meta 的浏览器。

  • Chrome >=87
  • Firefox >=78
  • Safari >=14
  • Edge >=88

您可以通过 build.target 配置选项 指定自定义目标,其中最低目标是 es2015

请注意,默认情况下,Vite 仅处理语法转换,**不涵盖 polyfill**。您可以查看 Polyfill.io,它是一项根据用户浏览器 UserAgent 字符串自动生成 polyfill 包的服务。

可以通过 @vitejs/plugin-legacy 支持传统浏览器,它会自动生成传统块和相应的 ES 语言特性 polyfill。传统块仅在不支持原生 ESM 的浏览器中按需加载。

公共基础路径

如果您在嵌套的公共路径下部署项目,只需指定 base 配置选项,所有资源路径将相应地重写。此选项也可以作为命令行标志指定,例如 vite build --base=/my/public/path/

JS 导入的资源 URL、CSS url() 引用以及 .html 文件中的资源引用在构建期间都会自动调整以符合此选项。

例外情况是您需要动态地拼接 URL。在这种情况下,您可以使用全局注入的 import.meta.env.BASE_URL 变量,它将是公共基础路径。请注意,此变量在构建期间是静态替换的,因此它必须完全按原样出现(即 import.meta.env['BASE_URL'] 不会起作用)。

有关高级基础路径控制,请查看 高级基础选项

自定义构建

可以通过各种 构建配置选项 自定义构建。具体来说,您可以通过 build.rollupOptions 直接调整底层的 Rollup 选项

js
export default defineConfig({
  build: {
    rollupOptions: {
      // https://rollup.node.org.cn/configuration-options/
    },
  },
})

例如,您可以指定多个 Rollup 输出,并使用仅在构建期间应用的插件。

块拆分策略

您可以使用 build.rollupOptions.output.manualChunks 配置块的拆分方式(请参阅 Rollup 文档)。如果您使用框架,请参考其文档以配置块的拆分方式。

加载错误处理

当 Vite 无法加载动态导入时,它会发出 vite:preloadError 事件。event.payload 包含原始导入错误。如果您调用 event.preventDefault(),则不会抛出错误。

js
window
.
addEventListener
('vite:preloadError', (
event
) => {
window
.
location
.
reload
() // for example, refresh the page
})

当发生新的部署时,托管服务可能会删除先前部署的资源。因此,在新的部署之前访问过您网站的用户可能会遇到导入错误。此错误发生是因为该用户设备上运行的资源已过时,并且它尝试导入相应的旧块,而该块已被删除。此事件对于解决这种情况很有用。

在文件更改时重建

您可以使用 vite build --watch 启用 Rollup 观察者。或者,您可以通过 build.watch 直接调整底层的 WatcherOptions

js
// vite.config.js
export default defineConfig({
  build: {
    watch: {
      // https://rollup.node.org.cn/configuration-options/#watch
    },
  },
})

启用 --watch 标志后,对 vite.config.js 以及要打包的任何文件的更改都会触发重建。

多页面应用程序

假设您有以下源代码结构

├── package.json
├── vite.config.js
├── index.html
├── main.js
└── nested
    ├── index.html
    └── nested.js

在开发过程中,只需导航或链接到 /nested/ - 它按预期工作,就像普通的静态文件服务器一样。

在构建过程中,您需要做的就是将多个 .html 文件指定为入口点

js
// vite.config.js
import { 
resolve
} from 'path'
import {
defineConfig
} from 'vite'
export default
defineConfig
({
build
: {
rollupOptions
: {
input
: {
main
:
resolve
(
__dirname
, 'index.html'),
nested
:
resolve
(
__dirname
, 'nested/index.html'),
}, }, }, })

如果您指定了不同的根目录,请记住,当解析输入路径时,__dirname 仍然是您的 vite.config.js 文件的文件夹。因此,您需要将您的 root 条目添加到 resolve 的参数中。

请注意,对于 HTML 文件,Vite 会忽略在 rollupOptions.input 对象中给定的入口名称,而是尊重解析后的文件 ID,以便在 dist 文件夹中生成 HTML 资源。这确保了与开发服务器工作方式一致的结构。

库模式

当您开发面向浏览器的库时,您很可能大部分时间都在测试/演示页面上,该页面导入您的实际库。使用 Vite,您可以使用您的 index.html 来实现此目的,以获得流畅的开发体验。

当您需要将库打包以供分发时,请使用 build.lib 配置选项。确保还将您不想打包到库中的任何依赖项(例如 vuereact)外部化

js
// vite.config.js
import { 
resolve
} from 'path'
import {
defineConfig
} from 'vite'
export default
defineConfig
({
build
: {
lib
: {
// Could also be a dictionary or array of multiple entry points
entry
:
resolve
(
__dirname
, 'lib/main.js'),
name
: 'MyLib',
// the proper extensions will be added
fileName
: 'my-lib',
},
rollupOptions
: {
// make sure to externalize deps that shouldn't be bundled // into your library
external
: ['vue'],
output
: {
// Provide global variables to use in the UMD build // for externalized deps
globals
: {
vue
: 'Vue',
}, }, }, }, })

入口文件将包含用户可以导入的导出内容

js
// lib/main.js
import Foo from './Foo.vue'
import Bar from './Bar.vue'
export { Foo, Bar }

使用此配置运行 vite build 会使用面向库分发的 Rollup 预设,并生成两种捆绑格式:esumd(可以通过 build.lib 配置)。

$ vite build
building for production...
dist/my-lib.js      0.08 kB / gzip: 0.07 kB
dist/my-lib.umd.cjs 0.30 kB / gzip: 0.16 kB

推荐的库 package.json

json
{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.umd.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.umd.cjs"
    }
  }
}

或者,如果公开多个入口点

json
{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.cjs"
    },
    "./secondary": {
      "import": "./dist/secondary.js",
      "require": "./dist/secondary.cjs"
    }
  }
}

文件扩展名

如果 package.json 不包含 "type": "module",Vite 将为 Node.js 兼容性生成不同的文件扩展名。.js 将变为 .mjs.cjs 将变为 .js

环境变量

在库模式下,所有 import.meta.env.* 用法在构建到生产环境时都会被静态替换。但是,process.env.* 用法不会被替换,以便您的库的使用者可以动态地更改它。如果这是不可取的,您可以使用 define: { 'process.env.NODE_ENV': '"production"' }(例如)来静态替换它们,或者使用 esm-env 以更好地与捆绑器和运行时兼容。

高级用法

库模式包含一个简单且有见地的配置,适用于面向浏览器的库和 JS 框架库。如果您构建的是非浏览器库,或者需要高级构建流程,您可以直接使用 Rollupesbuild

高级基础选项

警告

此功能处于实验阶段。 提供反馈

对于高级用例,部署的资源和公共文件可能位于不同的路径,例如使用不同的缓存策略。用户可以选择在三个不同的路径中部署

  • 生成的入口 HTML 文件(可能在 SSR 期间进行处理)
  • 生成的哈希资源(JS、CSS 和其他文件类型,如图像)
  • 复制的 公共文件

在这种情况下,单个静态 base 不够。Vite 在构建期间通过 experimental.renderBuiltUrl 提供对高级基础选项的实验性支持。

ts
experimental
: {
renderBuiltUrl
(
filename
, {
hostType
}) {
if (
hostType
=== 'js') {
return {
runtime
: `window.__toCdnUrl(${
JSON
.
stringify
(
filename
)})` }
} else { return {
relative
: true }
} }, },

如果哈希资源和公共文件没有一起部署,则可以使用传递给函数的第二个 context 参数中的资源 type 来独立定义每个组的选项。

ts
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
} }, },

请注意,传递的filename是解码后的 URL,如果函数返回 URL 字符串,也应该进行解码。Vite 会在渲染 URL 时自动处理编码。如果返回包含runtime的对象,则需要在需要的地方自行处理编码,因为运行时代码将按原样渲染。