Skip to content

Vite

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

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

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

TIP

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

安装

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

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

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

sh
// title: npm
node ace add @adonisjs/vite

:::disclosure

  1. adonisrc.ts 文件中注册以下服务提供者。

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

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

:::

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

ts
import { defineConfig } from '@adonisjs/core/build/standalone'

export default defineConfig({
  // highlight-start
  assetsBundler: false,
  hooks: {
    onBuildStarting: [() => import('@adonisjs/vite/build_hook')],
  },
  // highlight-end
})

assetsBundler 属性设置为 false 以关闭 AdonisJS Assembler 执行的资产打包器管理。

hooks 属性注册 @adonisjs/vite/build_hook 以执行 Vite 构建过程。有关更多信息,请参阅 Assembler 钩子

配置

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

Vite 配置文件

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

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

ts
// title: 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 文件。每个入口点将产生一个单独的输出包。

此外,如果需要,你可以定义多个入口点。例如,一个用于面向用户的应用程序的入口点,另一个用于管理面板。

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 构建过程的输出路径。

ts
// title: 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 标签上设置属性。属性是键值对的集合。

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

你可以使用 styleAttributes 属性在使用 @vite 标签生成的 link 标签上设置属性。属性是键值对的集合。

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

你还可以通过将函数分配给 styleAttributes 选项来有条件地应用属性。

ts
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。

sh
node ace serve --hmr

在 Edge 模板中包含入口点

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

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

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

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

在 Edge 模板中引用资产

Vite 创建入口点导入的文件的依赖图,并根据打包输出自动更新它们的路径。但是,Vite 不知道 Edge 模板,无法检测它们引用的资产。

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

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

使用 Vite 处理其他资产

Vite 忽略前端代码未导入的静态资产。它可能是仅在 Edge 模板中引用的静态图像、字体或 SVG 图标。

因此,你必须使用其 Glob 导入 API 通知 Vite 这些资产的存在。

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

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

现在,你可以在 Edge 模板中按如下方式引用图像。

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

配置 TypeScript

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

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

为 React 启用 HMR

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

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

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

ts
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"],
    }),
    // highlight-start
    react(),
    // highlight-end
  ],
})

将资产部署到 CDN

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

但是,在此之前,你必须向 Vite 和 AdonisJS 注册 CDN 服务器的 URL,以便 manifest.json 文件内的输出 URL 或延迟加载的块应指向你的 CDN 服务器。

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

ts
// title: 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'],
      // highlight-start
      assetsUrl: 'https://cdn.example.com/',
      // highlight-end
    }),
  ]
})
ts
// title: config/vite.ts
import { defineConfig } from '@adonisjs/vite'

const viteBackendConfig = defineConfig({
  buildDirectory: 'public/assets',
  // highlight-start
  assetsUrl: 'https://cdn.example.com/',
  // highlight-end
})

export default viteBackendConfig

高级概念

中间件模式

在旧版本的 AdonisJS 中,Vite 作为单独的进程生成并拥有自己的开发服务器。

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

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

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

Manifest 文件

Vite 在资产的生产构建旁边生成 manifest 文件

manifest 文件包含 Vite 处理的资产的 URL,AdonisJS 使用此文件为 Edge 模板中使用 asset 辅助函数或 @vite 标签引用的资产创建 URL。