Vite

Vite

AdonisJS 使用 Vite 来打包应用的前端资源。我们提供了一个官方集成,它完成了将 Vite 与 AdonisJS 这样的后端框架集成所需的所有繁重工作。它包括:

  • 将 Vite 开发服务器嵌入 AdonisJS 中。
  • 一个专用的 Vite 插件,用于简化配置选项。
  • 用于为 Vite 处理的资源生成 URL 的 Edge 辅助函数和标签。
  • 访问 Vite Runtime API 以执行服务端渲染(SSR)。

Vite 被嵌入在 AdonisJS 开发服务器中,每个应由 Vite 处理的请求都会通过 AdonisJS 中间件代理给它。这让我们可以直接访问 Vite 的运行时 API 来执行服务端渲染(SSR),并管理单一的开发服务器。这也意味着资源由 AdonisJS 直接提供,而不是由单独的进程提供。

还在使用 @adonisjs/vite 2.x?查看迁移指南 升级到最新版本。

安装

首先,确保至少安装了以下版本的 AdonisJS:

  • @adonisjs/core:6.9.1 或更高
  • @adonisjs/assembler:7.7.0 或更高

然后安装并配置 @adonisjs/vite 包。下面的命令会安装该包和 vite,并通过创建必要的配置文件来配置项目。

npm
node ace add @adonisjs/vite
  1. adonisrc.ts 文件中注册以下 service provider。

    {
    providers: [
    // ...其他 providers
    () => import('@adonisjs/vite/vite_provider')
    ]
    }
  2. 创建 vite.config.tsconfig/vite.ts 配置文件。

  3. 创建前端入口点文件,即 resources/js/app.js

完成后,将以下内容添加到你的 adonisrc.ts 文件中。

import { defineConfig } from '@adonisjs/core/build/standalone'
export default defineConfig({
assetsBundler: false,
hooks: {
onBuildStarting: [() => import('@adonisjs/vite/build_hook')],
},
})

assetsBundler 属性设为 false,以关闭由 AdonisJS Assembler 管理的资源打包器。

hooks 属性注册了 @adonisjs/vite/build_hook 来执行 Vite 构建过程。详见 Assembler hooks

配置

设置过程会创建两个配置文件。vite.config.ts 文件用于配置 Vite 打包器,config/vite.ts 由 AdonisJS 在后端使用。

Vite 配置文件

vite.config.ts 文件是 Vite 使用的常规配置文件。你可以根据项目需求,在该文件中安装并注册额外的 Vite 插件。

默认情况下,vite.config.ts 文件使用 AdonisJS 插件,它接受以下选项。

vite.config.ts
import { defineConfig } from 'vite'
import adonisjs from '@adonisjs/vite/client'
export default defineConfig({
plugins: [
adonisjs({
entrypoints: ['resources/js/app.js'],
reload: ['resources/views/**/*.edge'],
}),
]
})
entrypoints

entrypoints 指你前端代码库的入口点文件。通常它会是一个带有额外导入的 JavaScript 或 TypeScript 文件。每个入口点都会生成一个独立的输出包。

此外,如果需要,你可以定义多个入口点。例如,一个面向用户的 app 入口点,另一个管理后台入口点。

buildDirectory

buildDirectory 选项定义了输出目录的相对路径。该选项的值作为 build.outDir 选项提供给 Vite。

如果你决定更改默认值,请确保同时更新 config/vite.ts 文件中的 buildDirectory 路径。

默认:public/assets

reload

它包含一个 glob 模式数组,用于监听文件变化并刷新浏览器。默认情况下,我们监听 Edge 模板。不过,你也可以配置额外的模式。

assetsUrl

它包含在为生产环境生成资源链接时添加前缀的 URL。如果你将 Vite 输出上传到 CDN,那么该属性的值应该是 CDN 服务器 URL。

确保你更新后端配置以使用相同的 assetsUrl 值。


AdonisJS 配置文件

AdonisJS 在后端使用 config/vite.ts 文件来了解 Vite 构建过程的输出路径。

config/vite.ts
import { defineConfig } from '@adonisjs/vite'
const viteBackendConfig = defineConfig({
buildDirectory: 'public/assets',
assetsUrl: '/assets',
})
export default viteBackendConfig
buildDirectory

它包含 Vite 构建输出目录的路径。如果你在 vite.config.ts 文件中更改了默认值,也必须更新此后端配置。

assetsUrl

为生产环境生成资源链接时添加前缀的 URL。如果你将 Vite 输出上传到 CDN,那么该属性的值应该是 CDN 服务器 URL。

scriptAttributes

你可以使用 scriptAttributes 属性为使用 @vite 标签生成的 script 标签设置属性。属性是一组键值对。

config/vite.ts
defineConfig({
scriptAttributes: {
defer: true,
async: true,
}
})
styleAttributes

你可以使用 styleAttributes 属性为使用 @vite 标签生成的 link 标签设置属性。属性是一组键值对。

config/vite.ts
defineConfig({
styleAttributes: {
'data-turbo-track': 'reload'
}
})

你还可以通过将函数赋值给 styleAttributes 选项来有条件地应用这些属性。

defineConfig({
styleAttributes: ({ src, url }) => {
if (src === 'resources/css/admin.css') {
return {
'data-turbo-track': 'reload'
}
}
}
})

前端资源的目录结构

从技术上讲,AdonisJS 并不强制前端资源使用任何目录结构。你可以按照自己喜欢的方式组织它们。

不过,我们建议将前端资源存放在 resources 文件夹中,每种资源类别放在其自己的子目录中。

resources
└── css
└── js
└── fonts
└── images

Vite 的输出会位于 public/assets 文件夹中。我们选择 /assets 子目录,这样你还可以继续使用 public 文件夹存放其他你不想用 Vite 处理的静态文件。

启动开发服务器

你可以像往常一样启动应用,AdonisJS 会自动将所需的请求代理给 Vite。

node ace serve --hmr

在 Edge 模板中包含入口点

你可以使用 @vite Edge 标签渲染 vite.config.ts 文件中定义的入口点对应的 script 和 style 标签。该标签接受一个入口点数组,并返回 scriptlink 标签。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@vite(['resources/js/app.js'])
</head>
<body>
</body>
</html>

我们建议将 CSS 文件导入到你的 JavaScript 文件中,而不是单独将它们注册为一个入口点。例如:

resources
└── css
└── app.css
└── js
└── app.js
resources/js/app.js
import '../css/app.css'

在 Edge 模板中引用资源

Vite 会创建由入口点导入的文件的依赖关系图,并根据打包输出自动更新它们的路径。不过,Vite 并不知道 Edge 模板,也无法检测到它们引用的资源。

因此,我们提供了一个 Edge 辅助函数,你可以用它来为 Vite 处理的文件创建 URL。在下面的示例中:

  • asset 辅助函数会在开发期间返回一个指向 Vite 开发服务器的 URL。
  • 在生产期间返回指向输出文件名的 URL。
<link rel="stylesheet" href="{{ asset('resources/css/app.css') }}">
开发环境的输出
<link rel="stylesheet" href="http://localhost:5173/resources/css/app.css">
生产环境的输出
<link rel="stylesheet" href="/assets/app-3bc29777.css">

使用 Vite 处理额外资源

Vite 会忽略未被前端代码导入的静态资源。这些可能是仅在 Edge 模板中引用的静态图片、字体或 SVG 图标。

因此,你需要使用 Vite 的 Glob imports API 通知 Vite 这些资源的存在。

在下面的示例中,我们要求 Vite 处理 resources/images 目录中的所有文件。这段代码应写在一个入口点文件中。

resources/js/app.js
import.meta.glob(['../images/**'])

现在,你可以像下面这样在 Edge 模板中引用这些图片。

<img src="{{ asset('resources/images/hero.jpg') }}" />

配置 TypeScript

如果你计划在前端代码库中使用 TypeScript,请在 resources 目录内创建一个额外的 tsconfig.json 文件。Vite 和你的代码编辑器会自动将此配置文件用于 resources 目录内的 TypeScript 源代码。

resources/tsconfig.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"lib": ["DOM"],
"jsx": "preserve", // 如果你在使用 React
"paths": {
"@/*": ["./js/*"]
}
}
}

配合 React 启用 HMR

要在开发期间启用 react-refresh,你必须使用 @viteReactRefresh Edge 标签。它应写在使用 @vite 标签包含入口点之前。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@viteReactRefresh()
@vite(['resources/js/app.js'])
</head>
<body>
</body>
</html>

完成后,你可以像在常规 Vite 项目中一样配置 React 插件。

import { defineConfig } from 'vite'
import adonisjs from '@adonisjs/vite/client'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
adonisjs({
entrypoints: ["resources/js/app.js"],
}),
react(),
],
})

将资源部署到 CDN

使用 Vite 创建生产构建后,你可以将打包输出上传到 CDN 服务器以提供文件。

不过,在此之前,你必须在 Vite 和 AdonisJS 中注册你的 CDN 服务器 URL,这样 manifest.json 文件或懒加载的 chunk 中的输出 URL 才会指向你的 CDN 服务器。

你必须在 vite.config.tsconfig/vite.ts 文件中定义 assetsUrl

vite.config.ts
import { defineConfig } from 'vite'
import adonisjs from '@adonisjs/vite/client'
export default defineConfig({
plugins: [
adonisjs({
entrypoints: ['resources/js/app.js'],
reloads: ['resources/views/**/*.edge'],
assetsUrl: 'https://cdn.example.com/',
}),
]
})
config/vite.ts
import { defineConfig } from '@adonisjs/vite'
const viteBackendConfig = defineConfig({
buildDirectory: 'public/assets',
assetsUrl: 'https://cdn.example.com/',
})
export default viteBackendConfig

进阶概念

中间件模式

在 AdonisJS 的旧版本中,Vite 是作为一个单独的进程启动的,并拥有自己的开发服务器。

在 3.x 版本中,Vite 被嵌入到 AdonisJS 开发服务器中,每个应由 Vite 处理的请求都会通过 AdonisJS 中间件代理给它。

中间件模式的优势在于,我们可以直接访问 Vite 的运行时 API 来执行服务端渲染(SSR),并且只需管理单一的开发服务器。

你可以在 Vite 文档 中阅读更多关于中间件模式的内容。

Manifest 文件

Vite 会生成 manifest 文件,与你的资源生产构建一起。

manifest 文件包含 Vite 处理的资源的 URL,AdonisJS 使用该文件为 Edge 模板中引用的资源创建 URL,无论这些资源是使用 asset 辅助函数还是 @vite 标签引用的。