资源打包 (Vite)
- 简介
- 安装与设置
- 运行 Vite
- 使用 JavaScript
- 使用样式表
- 使用 Blade 和路由
- 资源预取
- 自定义基础 URL
- 环境变量
- 在测试中禁用 Vite
- 服务器端渲染 (SSR)
- 脚本和样式标签属性
- 高级自定义
简介
Vite 是一款现代前端构建工具,它提供了极快的开发环境,并将您的代码打包以供生产使用。在构建 Laravel 应用程序时,您通常会使用 Vite 将应用程序的 CSS 和 JavaScript 文件打包成生产环境就绪的资源。
Laravel 通过提供官方插件和 Blade 指令,实现与 Vite 的无缝集成,从而加载用于开发和生产环境的资源。
安装与设置
以下文档介绍了如何手动安装和配置 Laravel Vite 插件。不过,Laravel 的 入门套件 (Starter Kits) 已经包含了所有这些基础架构,是开始使用 Laravel 和 Vite 最快捷的方式。
安装 Node
在运行 Vite 和 Laravel 插件之前,您必须确保已安装 Node.js (16+) 和 NPM。
1node -v2npm -v
您可以直接从 Node 官网 下载图形化安装程序,轻松安装最新版本的 Node 和 NPM。或者,如果您正在使用 Laravel Sail,则可以通过 Sail 调用 Node 和 NPM。
1./vendor/bin/sail node -v2./vendor/bin/sail npm -v
安装 Vite 和 Laravel 插件
在全新的 Laravel 安装中,您会在应用程序目录结构的根目录下找到一个 package.json 文件。默认的 package.json 文件已经包含了使用 Vite 和 Laravel 插件所需的一切。您可以通过 NPM 安装应用程序的前端依赖项:
1npm install
配置 Vite
Vite 通过项目根目录下的 vite.config.js 文件进行配置。您可以根据需要自定义此文件,也可以安装应用程序所需的任何其他插件,例如 @vitejs/plugin-react、@sveltejs/vite-plugin-svelte 或 @vitejs/plugin-vue。
Laravel Vite 插件要求您指定应用程序的入口点。这些可以是 JavaScript 或 CSS 文件,也包含预处理语言,如 TypeScript、JSX、TSX 和 Sass。
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel([ 7 'resources/css/app.css', 8 'resources/js/app.js', 9 ]),10 ],11});
如果您正在构建 SPA(单页应用,包括使用 Inertia 构建的应用),Vite 在没有 CSS 入口点的情况下效果最好。
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel([ 7 'resources/css/app.css', 8 'resources/js/app.js', 9 ]),10 ],11});
相反,您应该通过 JavaScript 导入您的 CSS。通常,这会在应用程序的 resources/js/app.js 文件中完成。
1import './bootstrap';2import '../css/app.css';
Laravel 插件还支持多个入口点和高级配置选项,例如 SSR 入口点。
使用安全的开发服务器
如果您的本地开发 Web 服务器通过 HTTPS 提供服务,您在连接 Vite 开发服务器时可能会遇到问题。
如果您正在使用 Laravel Herd 并已保护了站点,或者您正在使用 Laravel Valet 并已对您的应用程序运行了 secure 命令,Laravel Vite 插件将自动检测并为您使用生成的 TLS 证书。
如果您使用不匹配应用程序目录名称的主机保护了站点,则可以在应用程序的 vite.config.js 文件中手动指定主机。
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel({ 7 // ... 8 detectTls: 'my-app.test', 9 }),10 ],11});
使用其他 Web 服务器时,您应该生成一个受信任的证书,并手动配置 Vite 以使用该生成的证书。
1// ... 2import fs from 'fs'; 3 4const host = 'my-app.test'; 5 6export default defineConfig({ 7 // ... 8 server: { 9 host, 10 hmr: { host }, 11 https: { 12 key: fs.readFileSync(`/path/to/${host}.key`), 13 cert: fs.readFileSync(`/path/to/${host}.crt`), 14 }, 15 }, 16});
如果您无法为系统生成受信任的证书,可以安装并配置 @vitejs/plugin-basic-ssl 插件。当使用不受信任的证书时,您需要在运行 npm run dev 命令时,通过控制台中的“Local”链接在浏览器中接受 Vite 开发服务器的证书警告。
在 WSL2 的 Sail 中运行开发服务器
当在 Windows Linux 子系统 2 (WSL2) 的 Laravel Sail 中运行 Vite 开发服务器时,您应该将以下配置添加到 vite.config.js 文件中,以确保浏览器能够与开发服务器通信:
1// ... 2 3export default defineConfig({ 4 // ... 5 server: { 6 hmr: { 7 host: 'localhost', 8 }, 9 }, 10});
如果开发服务器运行时文件更改未反映在浏览器中,您可能还需要配置 Vite 的 server.watch.usePolling 选项。
加载脚本和样式
配置好 Vite 入口点后,您现在可以在应用程序根模板的 <head> 中添加 @vite() Blade 指令来引用它们:
1<!DOCTYPE html>2<head>3 {{-- ... --}}4 5 @vite(['resources/css/app.css', 'resources/js/app.js'])6</head>
如果您是通过 JavaScript 导入 CSS,则只需要包含 JavaScript 入口点。
1<!DOCTYPE html>2<head>3 {{-- ... --}}4 5 @vite('resources/js/app.js')6</head>
@vite 指令将自动检测 Vite 开发服务器并注入 Vite 客户端以启用热模块替换 (HMR)。在构建模式下,该指令将加载已编译和版本化的资源,包括任何已导入的 CSS。
如果需要,您也可以在调用 @vite 指令时指定已编译资源的构建路径:
1<!doctype html>2<head>3 {{-- Given build path is relative to public path. --}}4 5 @vite('resources/js/app.js', 'vendor/courier/build')6</head>
内联资源 (Inline Assets)
有时可能需要包含资源的原始内容,而不是链接到资源的版本化 URL。例如,当向 PDF 生成器传递 HTML 内容时,可能需要直接在页面中包含资源内容。您可以使用 Vite facade 提供的 content 方法输出 Vite 资源的内容:
1@use('Illuminate\Support\Facades\Vite') 2 3<!doctype html> 4<head> 5 {{-- ... --}} 6 7 <style> 8 {!! Vite::content('resources/css/app.css') !!} 9 </style>10 <script>11 {!! Vite::content('resources/js/app.js') !!}12 </script>13</head>
运行 Vite
运行 Vite 有两种方式。您可以通过 dev 命令运行开发服务器,这在本地开发时非常有用。开发服务器会自动检测文件更改,并立即反映在任何打开的浏览器窗口中。
或者,运行 build 命令将对应用程序的资源进行版本控制和打包,并为部署到生产环境做好准备。
1# Run the Vite development server...2npm run dev3 4# Build and version the assets for production...5npm run build
如果您在 WSL2 的 Sail 中运行开发服务器,可能需要一些 额外的配置 选项。
使用 JavaScript
别名 (Aliases)
默认情况下,Laravel 插件提供了一个通用的别名,以帮助您快速上手并方便地导入应用程序资源:
1{2 '@' => '/resources/js'3}
您可以将自己的别名添加到 vite.config.js 配置文件中,从而覆盖 '@' 别名:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel(['resources/ts/app.tsx']), 7 ], 8 resolve: { 9 alias: {10 '@': '/resources/ts',11 },12 },13});
Vue
如果您想使用 Vue 框架构建前端,那么您还需要安装 @vitejs/plugin-vue 插件:
1npm install --save-dev @vitejs/plugin-vue
然后,您可以将该插件包含在 vite.config.js 配置文件中。在 Laravel 中使用 Vue 插件时,还有一些额外的选项需要注意。
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3import vue from '@vitejs/plugin-vue'; 4 5export default defineConfig({ 6 plugins: [ 7 laravel(['resources/js/app.js']), 8 vue({ 9 template: {10 transformAssetUrls: {11 // The Vue plugin will re-write asset URLs, when referenced12 // in Single File Components, to point to the Laravel web13 // server. Setting this to `null` allows the Laravel plugin14 // to instead re-write asset URLs to point to the Vite15 // server instead.16 base: null,17 18 // The Vue plugin will parse absolute URLs and treat them19 // as absolute paths to files on disk. Setting this to20 // `false` will leave absolute URLs un-touched so they can21 // reference assets in the public directory as expected.22 includeAbsolute: false,23 },24 },25 }),26 ],27});
Laravel 的 入门套件 已经包含了正确的 Laravel、Vue 和 Vite 配置。这些入门套件是开始使用 Laravel、Vue 和 Vite 最快捷的方式。
React
如果您想使用 React 框架构建前端,那么您还需要安装 @vitejs/plugin-react 插件:
1npm install --save-dev @vitejs/plugin-react
然后,您可以将该插件包含在 vite.config.js 配置文件中。
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3import react from '@vitejs/plugin-react'; 4 5export default defineConfig({ 6 plugins: [ 7 laravel(['resources/js/app.jsx']), 8 react(), 9 ],10});
您需要确保任何包含 JSX 的文件都具有 .jsx 或 .tsx 扩展名,并记住按需更新您的入口点,如上文所示。
您还需要在现有的 @vite 指令旁边包含额外的 @viteReactRefresh Blade 指令。
1@viteReactRefresh2@vite('resources/js/app.jsx')
@viteReactRefresh 指令必须在 @vite 指令之前调用。
Laravel 的 入门套件 已经包含了正确的 Laravel、React 和 Vite 配置。这些入门套件是开始使用 Laravel、React 和 Vite 最快捷的方式。
Svelte
如果您想使用 Svelte 框架构建前端,那么您还需要安装 @sveltejs/vite-plugin-svelte 插件:
1npm install --save-dev @sveltejs/vite-plugin-svelte
然后,您可以将该插件包含在 vite.config.js 配置文件中。
1import { svelte } from '@sveltejs/vite-plugin-svelte'; 2import laravel from 'laravel-vite-plugin'; 3import { defineConfig } from 'vite'; 4 5export default defineConfig({ 6 plugins: [ 7 laravel({ 8 input: ['resources/js/app.ts'], 9 ssr: 'resources/js/ssr.ts',10 refresh: true,11 }),12 svelte(),13 ],14});
Laravel 的 入门套件 已经包含了正确的 Laravel、Svelte 和 Vite 配置。这些入门套件是开始使用 Laravel、Svelte 和 Vite 最快捷的方式。
Inertia
Laravel Vite 插件提供了一个便捷的 resolvePageComponent 函数,以帮助您解析 Inertia 页面组件。以下是该辅助函数在 Vue 3 中使用的示例;不过,您也可以在 React 或 Svelte 等其他框架中使用该函数:
1import { createApp, h } from 'vue'; 2import { createInertiaApp } from '@inertiajs/vue3'; 3import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; 4 5createInertiaApp({ 6 resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')), 7 setup({ el, App, props, plugin }) { 8 createApp({ render: () => h(App, props) }) 9 .use(plugin)10 .mount(el)11 },12});
如果您在 Inertia 中使用了 Vite 的代码分割功能,我们建议配置 资源预取。
Laravel 的 入门套件 已经包含了正确的 Laravel、Inertia 和 Vite 配置。这些入门套件是开始使用 Laravel、Inertia 和 Vite 最快捷的方式。
URL 处理
当在 HTML、CSS 或 JS 中使用 Vite 引用资源时,需要注意一些注意事项。首先,如果您使用绝对路径引用资源,Vite 将不会把该资源包含在构建中;因此,您应该确保资源在您的公共目录(public)中可用。使用 专门的 CSS 入口点 时,应避免使用绝对路径,因为在开发过程中,浏览器会尝试从 Vite 开发服务器加载这些路径,而不是从您的公共目录加载。
引用相对资源路径时,请记住这些路径是相对于引用它们的文件而言的。任何通过相对路径引用的资源都将被 Vite 重写、版本化和打包。
考虑以下项目结构:
1public/2 taylor.png3resources/4 js/5 Pages/6 Welcome.vue7 images/8 abigail.png
以下示例演示了 Vite 如何处理相对和绝对 URL:
1<!-- This asset is not handled by Vite and will not be included in the build -->2<img src="/taylor.png">3 4<!-- This asset will be re-written, versioned, and bundled by Vite -->5<img src="../../images/abigail.png">
使用样式表
Laravel 的 入门套件 已经包含了正确的 Tailwind 和 Vite 配置。或者,如果您想在不使用入门套件的情况下将 Tailwind 与 Laravel 一起使用,请查看 Tailwind 的 Laravel 安装指南。
所有 Laravel 应用程序都已经包含了 Tailwind 和配置正确的 vite.config.js 文件。因此,您只需要启动 Vite 开发服务器或运行 dev Composer 命令,它将同时启动 Laravel 和 Vite 开发服务器:
1composer run dev
应用程序的 CSS 可以放在 resources/css/app.css 文件中。
使用 Blade 和路由
使用 Vite 处理静态资源
在 JavaScript 或 CSS 中引用资源时,Vite 会自动处理并对其进行版本控制。此外,在构建基于 Blade 的应用程序时,Vite 还可以处理并版本化您仅在 Blade 模板中引用的静态资源。
然而,为了实现这一点,您需要在插件的 assets 选项中指定资源,从而让 Vite 知晓它们。例如,如果您想处理并版本化存储在 resources/images 中的所有图片以及 resources/fonts 中的所有字体,您应该将以下内容添加到您的 Vite 配置中:
1laravel({2 input: 'resources/js/app.js',3 assets: ['resources/images/**', 'resources/fonts/**'],4})
运行 npm run build 时,这些资源将由 Vite 处理。然后,您可以在 Blade 模板中使用 Vite::asset 方法引用这些资源,它将返回给定资源的版本化 URL:
1<img src="{{ Vite::asset('resources/images/logo.png') }}">
在 Laravel Vite 插件 3.0 版本之前,必须使用 import.meta.glob 在应用程序的入口点导入静态资源。assets 选项是由于 Vite 8 的变更而引入的。
保存时自动刷新
当您的应用程序使用传统的 Blade 服务器端渲染构建时,Vite 可以通过在您更改应用程序中的视图文件时自动刷新浏览器,从而改进您的开发工作流程。要开始使用,您只需将 refresh 选项设置为 true 即可。
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel({ 7 // ... 8 refresh: true, 9 }),10 ],11});
当 refresh 选项为 true 时,保存以下目录中的文件将在您运行 npm run dev 时触发浏览器执行全页面刷新:
app/Livewire/**app/View/Components/**lang/**resources/lang/**resources/views/**routes/**
如果您正在利用 Ziggy 在应用程序前端生成路由链接,监控 routes/** 目录非常有用。
如果这些默认路径不符合您的需求,您可以指定自己的监控路径列表:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel({ 7 // ... 8 refresh: ['resources/views/**'], 9 }),10 ],11});
在底层,Laravel Vite 插件使用了 vite-plugin-full-reload 包,它提供了一些高级配置选项来微调此功能的行为。如果您需要这种级别的自定义,可以提供 config 定义:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel({ 7 // ... 8 refresh: [{ 9 paths: ['path/to/watch/**'],10 config: { delay: 300 }11 }],12 }),13 ],14});
别名 (Aliases)
在 JavaScript 应用程序中,创建别名以指向经常引用的目录是很常见的。但是,您也可以使用 Illuminate\Support\Facades\Vite 类上的 macro 方法创建在 Blade 中使用的别名。通常,“宏”应该在服务提供者的 boot 方法中定义:
1/**2 * Bootstrap any application services.3 */4public function boot(): void5{6 Vite::macro('image', fn (string $asset) => $this->asset("resources/images/{$asset}"));7}
一旦定义了宏,就可以在模板中调用它。例如,我们可以使用上面定义的 image 宏来引用位于 resources/images/logo.png 的资源:
1<img src="{{ Vite::image('logo.png') }}" alt="Laravel Logo">
资源预取
在使用 Vite 的代码分割功能构建 SPA 时,所需的资源会在每次页面导航时获取。这种行为可能导致 UI 渲染延迟。如果这对您选择的前端框架是个问题,Laravel 提供了在初始页面加载时主动预取应用程序 JavaScript 和 CSS 资源的功能。
您可以通过在服务提供者的 boot 方法中调用 Vite::prefetch 方法,来指示 Laravel 主动预取您的资源:
1<?php 2 3namespace App\Providers; 4 5use Illuminate\Support\Facades\Vite; 6use Illuminate\Support\ServiceProvider; 7 8class AppServiceProvider extends ServiceProvider 9{10 /**11 * Register any application services.12 */13 public function register(): void14 {15 // ...16 }17 18 /**19 * Bootstrap any application services.20 */21 public function boot(): void22 {23 Vite::prefetch(concurrency: 3);24 }25}
在上面的示例中,资源将在每次页面加载时以最多 3 个并发下载的速度进行预取。您可以根据应用程序的需求修改并发数,或者如果应用程序应该一次性下载所有资源,则不指定并发限制:
1/**2 * Bootstrap any application services.3 */4public function boot(): void5{6 Vite::prefetch();7}
默认情况下,预取将在页面 load 事件触发时开始。如果您想自定义预取开始的时间,可以指定一个 Vite 将要监听的事件:
1/**2 * Bootstrap any application services.3 */4public function boot(): void5{6 Vite::prefetch(event: 'vite:prefetch');7}
使用上面的代码,当您手动在 window 对象上分派 vite:prefetch 事件时,预取就会开始。例如,您可以让预取在页面加载三秒后开始:
1<script>2 addEventListener('load', () => setTimeout(() => {3 dispatchEvent(new Event('vite:prefetch'))4 }, 3000))5</script>
自定义基础 URL
如果您的 Vite 编译资源部署到与应用程序不同的域(例如通过 CDN),则必须在应用程序的 .env 文件中指定 ASSET_URL 环境变量:
1ASSET_URL=https://cdn.example.com
配置资源 URL 后,所有指向您资源的重写 URL 都将以配置的值作为前缀:
1https://cdn.example.com/build/assets/app.9dce8d17.js
请记住,绝对 URL 不会被 Vite 重写,因此它们不会被添加前缀。
环境变量
您可以通过在应用程序的 .env 文件中为环境变量添加 VITE_ 前缀,将它们注入到 JavaScript 中:
1VITE_SENTRY_DSN_PUBLIC=http://example.com
您可以通过 import.meta.env 对象访问注入的环境变量:
1import.meta.env.VITE_SENTRY_DSN_PUBLIC
在测试中禁用 Vite
Laravel 的 Vite 集成会尝试在运行测试时解析您的资源,这要求您要么运行 Vite 开发服务器,要么构建您的资源。
如果您希望在测试期间模拟 Vite,可以调用 withoutVite 方法,该方法适用于任何扩展了 Laravel TestCase 类的测试:
1test('without vite example', function () {2 $this->withoutVite();3 4 // ...5});
1use Tests\TestCase; 2 3class ExampleTest extends TestCase 4{ 5 public function test_without_vite_example(): void 6 { 7 $this->withoutVite(); 8 9 // ...10 }11}
如果您想对所有测试禁用 Vite,可以从基础 TestCase 类的 setUp 方法中调用 withoutVite 方法:
1<?php 2 3namespace Tests; 4 5use Illuminate\Foundation\Testing\TestCase as BaseTestCase; 6 7abstract class TestCase extends BaseTestCase 8{ 9 protected function setUp(): void10 {11 parent::setUp();12 13 $this->withoutVite();14 }15}
服务器端渲染 (SSR)
Laravel Vite 插件使得使用 Vite 设置服务器端渲染变得轻而易举。要开始使用,请在 resources/js/ssr.js 创建一个 SSR 入口点,并通过将配置选项传递给 Laravel 插件来指定该入口点:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel({ 7 input: 'resources/js/app.js', 8 ssr: 'resources/js/ssr.js', 9 }),10 ],11});
为确保您不会忘记重建 SSR 入口点,我们建议增强应用程序 package.json 中的“build”脚本以创建您的 SSR 构建:
1"scripts": {2 "dev": "vite",3 "build": "vite build" 4 "build": "vite build && vite build --ssr" 5}
然后,要构建并启动 SSR 服务器,您可以运行以下命令:
1npm run build2node bootstrap/ssr/ssr.js
如果您正在使用 Inertia 的 SSR,则可以使用 inertia:start-ssr Artisan 命令来启动 SSR 服务器:
1php artisan inertia:start-ssr
Laravel 的 入门套件 已经包含了正确的 Laravel、Inertia SSR 和 Vite 配置。这些入门套件是开始使用 Laravel、Inertia SSR 和 Vite 最快捷的方式。
脚本和样式标签属性
内容安全策略 (CSP) Nonce
如果您希望在脚本和样式标签上包含 nonce 属性,作为内容安全策略的一部分,您可以在自定义中间件中使用 useCspNonce 方法生成或指定一个 nonce:
1<?php 2 3namespace App\Http\Middleware; 4 5use Closure; 6use Illuminate\Http\Request; 7use Illuminate\Support\Facades\Vite; 8use Symfony\Component\HttpFoundation\Response; 9 10class AddContentSecurityPolicyHeaders11{12 /**13 * Handle an incoming request.14 *15 * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next16 */17 public function handle(Request $request, Closure $next): Response18 {19 Vite::useCspNonce();20 21 return $next($request)->withHeaders([22 'Content-Security-Policy' => "script-src 'nonce-".Vite::cspNonce()."'",23 ]);24 }25}
调用 useCspNonce 方法后,Laravel 将自动在所有生成的脚本和样式标签上包含 nonce 属性。
如果您需要在其他地方指定 nonce,包括 Laravel 入门套件中包含的 Ziggy @route 指令,您可以使用 cspNonce 方法检索它:
1@routes(nonce: Vite::cspNonce())
如果您已经有一个想要指示 Laravel 使用的 nonce,则可以将该 nonce 传递给 useCspNonce 方法:
1Vite::useCspNonce($nonce);
子资源完整性 (SRI)
如果您的 Vite 清单包含资源的 integrity 哈希值,Laravel 将自动在它生成的任何脚本和样式标签上添加 integrity 属性,以强制执行子资源完整性。默认情况下,Vite 不会在其清单中包含 integrity 哈希值,但您可以通过安装 vite-plugin-manifest-sri NPM 插件来启用它。
1npm install --save-dev vite-plugin-manifest-sri
然后,您可以在 vite.config.js 文件中启用此插件:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3import manifestSRI from 'vite-plugin-manifest-sri'; 4 5export default defineConfig({ 6 plugins: [ 7 laravel({ 8 // ... 9 }),10 manifestSRI(),11 ],12});
如果需要,您还可以自定义可以找到完整性哈希的清单键 (manifest key):
1use Illuminate\Support\Facades\Vite;2 3Vite::useIntegrityKey('custom-integrity-key');
如果您想完全禁用此自动检测,可以将 false 传递给 useIntegrityKey 方法:
1Vite::useIntegrityKey(false);
任意属性
如果您需要在脚本和样式标签上包含额外的属性,例如 data-turbo-track 属性,可以通过 useScriptTagAttributes 和 useStyleTagAttributes 方法指定它们。通常,这些方法应该从服务提供者中调用:
1use Illuminate\Support\Facades\Vite; 2 3Vite::useScriptTagAttributes([ 4 'data-turbo-track' => 'reload', // Specify a value for the attribute... 5 'async' => true, // Specify an attribute without a value... 6 'integrity' => false, // Exclude an attribute that would otherwise be included... 7]); 8 9Vite::useStyleTagAttributes([10 'data-turbo-track' => 'reload',11]);
如果您需要有条件地添加属性,可以传递一个回调函数,该回调函数将接收资源源路径、其 URL、其清单块 (manifest chunk) 和整个清单:
1use Illuminate\Support\Facades\Vite;2 3Vite::useScriptTagAttributes(fn (string $src, string $url, array|null $chunk, array|null $manifest) => [4 'data-turbo-track' => $src === 'resources/js/app.js' ? 'reload' : false,5]);6 7Vite::useStyleTagAttributes(fn (string $src, string $url, array|null $chunk, array|null $manifest) => [8 'data-turbo-track' => $chunk && $chunk['isEntry'] ? 'reload' : false,9]);
当 Vite 开发服务器运行时,$chunk 和 $manifest 参数将为 null。
高级自定义
开箱即用,Laravel 的 Vite 插件使用了合理的约定,应该适用于大多数应用程序;然而,有时您可能需要自定义 Vite 的行为。为了启用额外的自定义选项,我们提供了以下方法和选项,它们可以替代 @vite Blade 指令使用:
1<!doctype html> 2<head> 3 {{-- ... --}} 4 5 {{ 6 Vite::useHotFile(storage_path('vite.hot')) // Customize the "hot" file... 7 ->useBuildDirectory('bundle') // Customize the build directory... 8 ->useManifestFilename('assets.json') // Customize the manifest filename... 9 ->withEntryPoints(['resources/js/app.js']) // Specify the entry points...10 ->createAssetPathsUsing(function (string $path, ?bool $secure) { // Customize the backend path generation for built assets...11 return "https://cdn.example.com/{$path}";12 })13 }}14</head>
在 vite.config.js 文件中,您应该指定相同的配置:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel({ 7 hotFile: 'storage/vite.hot', // Customize the "hot" file... 8 buildDirectory: 'bundle', // Customize the build directory... 9 input: ['resources/js/app.js'], // Specify the entry points...10 }),11 ],12 build: {13 manifest: 'assets.json', // Customize the manifest filename...14 },15});
开发服务器跨域资源共享 (CORS)
如果您在浏览器中从 Vite 开发服务器获取资源时遇到跨域资源共享 (CORS) 问题,则可能需要授予您的自定义源访问开发服务器的权限。Vite 结合 Laravel 插件无需额外配置即可允许以下源:
::1127.0.0.1localhost*.test*.localhost- 项目
.env中的APP_URL
为项目允许自定义源的最简单方法是确保应用程序的 APP_URL 环境变量与您在浏览器中访问的源匹配。例如,如果您访问 https://my-app.laravel,则应更新您的 .env 以匹配:
1APP_URL=https://my-app.laravel
如果您需要对源进行更细粒度的控制(例如支持多个源),则应利用 Vite 全面且灵活的内置 CORS 服务器配置。例如,您可以在项目的 vite.config.js 文件中的 server.cors.origin 配置选项中指定多个源:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel({ 7 input: 'resources/js/app.js', 8 refresh: true, 9 }),10 ],11 server: { 12 cors: { 13 origin: [ 14 'https://backend.laravel', 15 'http://admin.laravel:8566', 16 ], 17 }, 18 }, 19});
您还可以包含正则表达式模式,如果您想允许给定顶级域(如 *.laravel)的所有源,这将很有帮助:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3 4export default defineConfig({ 5 plugins: [ 6 laravel({ 7 input: 'resources/js/app.js', 8 refresh: true, 9 }),10 ],11 server: { 12 cors: { 13 origin: [ 14 // Supports: SCHEME://DOMAIN.laravel[:PORT] 15 /^https?:\/\/.*\.laravel(:\d+)?$/, 16 ], 17 }, 18 }, 19});
修正开发服务器 URL
Vite 生态系统中的某些插件假定以正斜杠开头的 URL 将始终指向 Vite 开发服务器。然而,由于 Laravel 集成的性质,情况并非如此。
例如,当 Vite 正在为您提供资源时,vite-imagetools 插件会输出如下 URL:
1<img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">
vite-imagetools 插件期望输出的 URL 将被 Vite 拦截,然后该插件可以处理所有以 /@imagetools 开头的 URL。如果您使用的插件预料到这种行为,则需要手动修正 URL。您可以通过在 vite.config.js 文件中使用 transformOnServe 选项来完成此操作。
在这个特定示例中,我们将开发服务器 URL 添加到生成代码中所有 /@imagetools 出现的位置之前:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3import { imagetools } from 'vite-imagetools'; 4 5export default defineConfig({ 6 plugins: [ 7 laravel({ 8 // ... 9 transformOnServe: (code, devServerUrl) => code.replaceAll('/@imagetools', devServerUrl+'/@imagetools'),10 }),11 imagetools(),12 ],13});
现在,当 Vite 提供资源时,它将输出指向 Vite 开发服务器的 URL:
1- <img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">2+ <img src="http://[::1]:5173/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">