资产捆绑(Vite)
介绍
Vite 是一个现代的前端构建工具,提供了一个极其快速的开发环境,并将你的代码打包成适用于生产的资源。在使用 Laravel 构建应用程序时,通常会使用 Vite 将应用程序的 CSS 和 JavaScript 文件打包成生产就绪的资源。
Laravel 通过提供官方插件和 Blade 指令与 Vite 无缝集成,用于加载开发和生产环境中的资源。
你还在使用 Laravel Mix 吗? Vite 已经在新的 Laravel 安装中替代了 Laravel Mix。有关 Mix 的文档,请访问 Laravel Mix 网站。如果你想切换到 Vite,请参阅我们的 【迁移指南】。 |
在 Vite 和 Laravel Mix 之间的选择
在过渡到 Vite 之前,新的 Laravel 应用程序使用的是 Mix,它是由 webpack 驱动的,用于打包资源。Vite 侧重于提供一个更快、更高效的体验,尤其是在构建丰富的 JavaScript 应用程序时。如果你正在开发一个单页面应用程序(SPA),包括使用 Inertia 等工具开发的应用,Vite 将是一个完美的选择。
Vite 也非常适用于传统的服务器端渲染应用程序,尤其是那些包含少量 JavaScript 的应用,包括使用 Livewire 的应用。然而,它缺少一些 Laravel Mix 支持的功能,比如将没有直接在 JavaScript 应用程序中引用的任意资产复制到构建中的能力。
安装与设置
以下文档讨论了如何手动安装和配置 Laravel Vite 插件。然而,Laravel 的【起始套件】已经包含了所有这些脚手架,并且是开始使用 Laravel 和 Vite 的最快方式。 |
安装 Node
在运行 Vite 和 Laravel 插件之前,必须确保已经安装 Node.js(16+)和 NPM:
node -v
npm -v
您可以通过【官方 Node 网站】的图形安装程序轻松安装最新版本的 Node 和 NPM。或者,如果您使用的是 Laravel Sail,您可以通过 Sail 调用 Node 和 NPM:
./vendor/bin/sail node -v
./vendor/bin/sail npm -v
安装 Vite 和 Laravel 插件
在全新安装的 Laravel 中,您将在应用程序目录结构的根目录中找到一个 package.json
文件。默认的 package.json
文件已经包含了使用 Vite 和 Laravel 插件所需的一切。您可以通过 NPM 安装应用程序的前端依赖项:
npm install
配置 Vite
Vite 的配置通过项目根目录中的 vite.config.js
文件进行。您可以根据需要自定义此文件,并安装应用程序所需的其它插件,如 @vitejs/plugin-vue
或 @vitejs/plugin-react
。
Laravel Vite 插件要求您指定应用程序的入口点。这些入口点可以是 JavaScript 或 CSS 文件,也可以是经过预处理的语言,如 TypeScript、JSX、TSX 和 Sass。
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
],
});
如果您正在构建一个单页面应用(SPA),包括使用 Inertia 构建的应用,Vite 在没有 CSS 入口点的情况下效果最佳:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
],
});
相反,您应该通过 JavaScript 导入 CSS。通常,这将在应用程序的 resources/js/app.js
文件中完成:
import './bootstrap';
import '../css/app.css';
Laravel 插件还支持多个入口点和高级配置选项,如 【SSR 入口点】。
使用安全的开发服务器
如果您的本地开发 Web 服务器通过 HTTPS 提供应用程序,您可能会遇到连接 Vite 开发服务器的问题。
如果您正在使用 Laravel Herd 并且已为站点启用了安全连接,或正在使用 Laravel Valet 并且已对应用程序运行了 【secure
命令】,则 Laravel Vite 插件将自动检测并使用生成的 TLS 证书。
如果您使用的主机与应用程序目录名称不匹配,您可以手动在应用程序的 vite.config.js
文件中指定主机:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
// ...
detectTls: 'my-app.test',
}),
],
});
当使用其它 Web 服务器时,您应该生成一个受信任的证书,并手动配置 Vite 使用生成的证书:
// ...
import fs from 'fs';
const host = 'my-app.test';
export default defineConfig({
// ...
server: {
host,
hmr: { host },
https: {
key: fs.readFileSync(`/path/to/${host}.key`),
cert: fs.readFileSync(`/path/to/${host}.crt`),
},
},
});
如果您无法为系统生成受信任的证书,您可以安装并配置 @vitejs/plugin-basic-ssl
【插件】。在使用不受信任的证书时,您需要在浏览器中接受 Vite 开发服务器的证书警告,方法是运行 npm run dev
命令时,按照控制台中的 "Local" 链接进行操作。
在 Sail 上通过 WSL2 运行开发服务器
当在 Windows Subsystem for Linux 2(WSL2)中的 【Laravel Sail】 上运行 Vite 开发服务器时,您应该在 vite.config.js
文件中添加以下配置,以确保浏览器可以与开发服务器通信:
// ...
export default defineConfig({
// ...
server: {
hmr: {
host: 'localhost',
},
},
});
如果文件更改在开发服务器运行时没有在浏览器中反映出来,您可能还需要配置 Vite 的 server.watch.usePolling
【选项】。
加载脚本和样式
配置了 Vite 入口点后,您可以通过在应用程序的根模板的 <head>
中添加 @vite()
Blade 指令来引用它们:
<!DOCTYPE html>
<head>
{{-- ... --}}
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
如果您通过 JavaScript 导入 CSS,则只需包含 JavaScript 入口点:
<!DOCTYPE html>
<head>
{{-- ... --}}
@vite('resources/js/app.js')
</head>
@vite
指令会自动检测 Vite 开发服务器并注入 Vite 客户端以启用热模块替换(HMR)。在构建模式下,该指令将加载已编译并带版本号的资产,包括任何导入的 CSS。
如果需要,您还可以在调用 @vite
指令时指定已编译资产的构建路径:
<!doctype html>
<head>
{{-- 给定的构建路径相对于 public 路径 --}}
@vite('resources/js/app.js', 'vendor/courier/build')
</head>
内联资产
有时,您可能需要包含资产的原始内容,而不是链接到版本化后的资产 URL。例如,当将 HTML 内容传递给 PDF 生成器时,您可能需要将资产内容直接包含到页面中。您可以使用 Vite facade 提供的 content
方法输出 Vite 资产的内容:
@use('Illuminate\Support\Facades\Vite')
<!doctype html>
<head>
{{-- ... --}}
<style>
{!! Vite::content('resources/css/app.css') !!}
</style>
<script>
{!! Vite::content('resources/js/app.js') !!}
</script>
</head>
与 JavaScript 一起工作
别名
默认情况下,Laravel 插件提供了一个常用的别名,帮助您快速入门,并方便地导入您的应用程序资产:
{
'@' => '/resources/js'
}
您可以通过在 vite.config.js
配置文件中添加自己的别名来覆盖 '@' 别名:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel(['resources/ts/app.tsx']),
],
resolve: {
alias: {
'@': '/resources/ts',
},
},
});
Vue
如果您想使用 Vue 框架来构建前端,那么还需要安装 @vitejs/plugin-vue
插件:
npm install --save-dev @vitejs/plugin-vue
然后,您可以在 vite.config.js
配置文件中包含该插件。使用 Vue 插件时,Laravel 需要一些额外的配置选项:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel(['resources/js/app.js']),
vue({
template: {
transformAssetUrls: {
// Vue 插件将重新编写单文件组件中的资产 URL,
// 将它们指向 Laravel 网络服务器。将此设置为 `null`
// 允许 Laravel 插件将资产 URL 重新写入为指向 Vite 服务器。
base: null,
// Vue 插件会解析绝对 URL,并将它们视为磁盘上的文件路径。
// 将此设置为 `false` 将保持绝对 URL 不变,
// 使它们可以按预期引用 public 目录中的资产。
includeAbsolute: false,
},
},
}),
],
});
Laravel 的【启动工具包】已经包含了正确的 Laravel、Vue 和 Vite 配置。查看 Laravel Breeze,这是开始使用 Laravel、Vue 和 Vite 的最快方法。 |
React
如果您想使用 React 框架来构建前端,那么还需要安装 @vitejs/plugin-react
插件:
npm install --save-dev @vitejs/plugin-react
然后,您可以在 vite.config.js
配置文件中包含该插件:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
laravel(['resources/js/app.jsx']),
react(),
],
});
确保任何包含 JSX 的文件都有 .jsx
或 .tsx
扩展名,并根据需要更新您的入口文件,【如上所示】。
您还需要在现有的 @vite
指令旁边,包含额外的 @viteReactRefresh
Blade 指令:
@viteReactRefresh
@vite('resources/js/app.jsx')
@viteReactRefresh
指令必须在 @vite
指令之前调用。
Laravel 的 【启动工具包】 已经包含了正确的 Laravel、React 和 Vite 配置。查看 Laravel Breeze,这是开始使用 Laravel、React 和 Vite 的最快方法。 |
Inertia
Laravel Vite 插件提供了一个方便的 resolvePageComponent
函数,帮助您解析 Inertia 页面组件。下面是一个与 Vue 3 一起使用的示例;但是,您也可以在其它框架(如 React)中使用该函数:
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
createInertiaApp({
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el)
},
});
如果您使用了 Vite 的代码分割功能与 Inertia,我们建议配置资产预加载( asset prefetching )。
Laravel 的 【启动工具包】 已经包含了正确的 Laravel、Inertia 和 Vite 配置。查看 Laravel Breeze,这是开始使用 Laravel、Inertia 和 Vite 的最快方法。 |
URL 处理
在使用 Vite 时引用应用程序中的资产(HTML、CSS 或 JS 文件中的资产)时,有几个注意事项需要考虑。首先,如果您使用绝对路径引用资产,Vite 将不会将该资产包含在构建中;因此,您需要确保该资产可在公共目录中访问。在使用【专用的 CSS 入口点时】,应该避免使用绝对路径,因为在开发过程中,浏览器将尝试从 Vite 开发服务器加载这些路径(CSS 托管的位置),而不是从公共目录加载。
当引用相对路径的资产时,您应该记住,路径是相对于引用它们的文件的。通过相对路径引用的任何资产都会被 Vite 重新编写、版本化和打包。
考虑以下项目结构:
public/
taylor.png
resources/
js/
Pages/
Welcome.vue
images/
abigail.png
以下示例演示了 Vite 如何处理相对路径和绝对路径:
<!-- 这个资产不会被 Vite 处理,也不会包含在构建中 -->
<img src="/taylor.png">
<!-- 这个资产会被 Vite 重新编写、版本化并打包 -->
<img src="../../images/abigail.png">
与样式表一起工作
您可以在 【Vite 文档】中了解更多关于 Vite 对 CSS 的支持。如果您使用的是 PostCSS 插件,如 【Tailwind】,您可以在项目根目录中创建一个 postcss.config.js
文件,Vite 将自动应用该配置:
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Laravel 的【启动套件】已经包含了正确的 Tailwind、PostCSS 和 Vite 配置。或者,如果您希望在不使用启动套件的情况下将 Tailwind 和 Laravel 一起使用,可以查看 【Tailwind 的 Laravel 安装指南】。 |
与 Blade 和路由一起工作
使用 Vite 处理静态资产
在 JavaScript 或 CSS 中引用资产时,Vite 会自动处理并为它们生成版本。此外,在构建基于 Blade 的应用程序时,Vite 也可以处理并版本化仅在 Blade 模板中引用的静态资产。
但是,为了实现这一点,您需要通过将静态资产导入到应用程序的入口文件中,让 Vite 识别您的资产。例如,如果您想处理并版本化存储在 resources/images
中的所有图片和存储在 resources/fonts
中的所有字体,您应在应用程序的 resources/js/app.js
入口文件中添加以下代码:
import.meta.glob([
'../images/**',
'../fonts/**',
]);
这些资产现在将在运行 npm run build
时由 Vite 处理。然后,您可以在 Blade 模板中使用 Vite::asset
方法引用这些资产,该方法将返回给定资产的版本化 URL:
<img src="{{ Vite::asset('resources/images/logo.png') }}">
保存时刷新
当您的应用程序使用传统的服务器端渲染与 Blade 时,Vite 可以通过在您更改应用程序中的视图文件时自动刷新浏览器来改善您的开发工作流。要开始使用,只需将 refresh
选项设置为 true
。
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
// ...
refresh: true,
}),
],
});
当 refresh
选项为 true
时,保存以下目录中的文件将触发浏览器进行完整的页面刷新,当您运行 npm run dev
时:
-
app/Livewire/**
-
app/View/Components/**
-
lang/**
-
resources/lang/**
-
resources/views/**
-
routes/**
如果您在应用程序的前端使用 Ziggy 生成路由链接,监视 routes/**
目录非常有用。
如果这些默认路径不符合您的需求,您可以指定自己要监视的路径列表:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
// ...
refresh: ['resources/views/**'],
}),
],
});
在后台,Laravel Vite 插件使用了 vite-plugin-full-reload
包,该包提供了一些高级配置选项,可以微调此功能的行为。如果您需要这种级别的自定义,您可以提供配置定义:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
// ...
refresh: [{
paths: ['path/to/watch/**'],
config: { delay: 300 }
}],
}),
],
});
别名
在 JavaScript 应用程序中,通常会【创建别名】来引用经常使用的目录。你也可以通过在 Illuminate\Support\Facades\Vite
类上使用 macro
方法来创建别名,用于 Blade 中。通常,"宏" 应该在【服务提供者】的 boot
方法中定义:
/**
* 启动任何应用服务。
*/
public function boot(): void
{
Vite::macro('image', fn (string $asset) => $this->asset("resources/images/{$asset}"));
}
定义了宏后,可以在模板中调用它。例如,我们可以使用上面定义的 image
宏来引用位于 resources/images/logo.png
的资产:
<img src="{{ Vite::image('logo.png') }}" alt="Laravel Logo">
资产预取
在使用 Vite 的代码分割功能构建单页应用(SPA)时,所需的资产会在每次页面导航时进行请求。这种行为可能导致 UI 渲染的延迟。如果你的前端框架存在这种问题,Laravel 提供了一个方法,可以在初始页面加载时提前预取应用的 JavaScript 和 CSS 资产。
你可以通过在【服务提供者】的 boot
方法中调用 Vite::prefetch
方法来指示 Laravel 提前预取你的资产:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Vite;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* 注册任何应用服务。
*/
public function register(): void
{
// ...
}
/**
* 启动任何应用服务。
*/
public function boot(): void
{
Vite::prefetch(concurrency: 3);
}
}
在上面的示例中,资产将在每次页面加载时以最多 3
个并发下载进行预取。你可以根据应用的需求修改并发数,或者如果希望应用一次性下载所有资产,则可以不指定并发限制:
/**
* 启动任何应用服务。
*/
public function boot(): void
{
Vite::prefetch();
}
默认情况下,预取将在【页面加载事件】触发时开始。如果你希望自定义预取开始的时间,可以指定 Vite 监听的事件:
/**
* 启动任何应用服务。
*/
public function boot(): void
{
Vite::prefetch(event: 'vite:prefetch');
}
根据上述代码,预取将在你手动在 window
对象上触发 vite:prefetch
事件时开始。例如,你可以让预取在页面加载后 3 秒开始:
<script>
addEventListener('load', () => setTimeout(() => {
dispatchEvent(new Event('vite:prefetch'))
}, 3000))
</script>
自定义基础 URL
如果你的 Vite 编译后的资产部署到一个与应用程序不同的域,例如通过 CDN,你必须在应用程序的 .env
文件中指定 ASSET_URL
环境变量:
ASSET_URL=https://cdn.example.com
配置了资产 URL 后,所有重新编写的资产 URL 将会以配置的值为前缀:
https://cdn.example.com/build/assets/app.9dce8d17.js
请记住,【绝对路径的 URL 不会被 Vite 重新编写】,因此它们不会添加前缀。
环境变量
你可以通过在应用程序的 .env
文件中将环境变量前缀设置为 VITE_
来将环境变量注入到你的 JavaScript 中:
VITE_SENTRY_DSN_PUBLIC=http://example.com
你可以通过 import.meta.env
对象访问注入的环境变量:
import.meta.env.VITE_SENTRY_DSN_PUBLIC
在测试中禁用 Vite
Laravel 的 Vite 集成在运行测试时会尝试解析你的资源,这要求你必须运行 Vite 开发服务器或构建你的资源。
如果你希望在测试期间模拟 Vite,可以在任何继承 Laravel TestCase
类的测试中调用 withoutVite
方法:
test('without vite example', function () {
$this->withoutVite();
// ...
});
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_without_vite_example(): void
{
$this->withoutVite();
// ...
}
}
如果你希望禁用所有测试中的 Vite,可以在你的基类 TestCase
类的 setUp
方法中调用 withoutVite
方法:
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->withoutVite();
}
}
服务器端渲染 (SSR)
Laravel Vite 插件使得与 Vite 配合进行服务器端渲染(SSR)的设置变得非常简单。要开始使用,首先在 resources/js/ssr.js
创建一个 SSR 入口点,并通过传递配置选项给 Laravel 插件来指定这个入口点:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
ssr: 'resources/js/ssr.js',
}),
],
});
为了确保不会忘记重新构建 SSR 入口点,建议在你应用的 package.json
中增强 "build" 脚本,以便创建 SSR 构建:
"scripts": {
"dev": "vite",
"build": "vite build",
"build": "vite build && vite build --ssr"
}
然后,要构建并启动 SSR 服务器,你可以运行以下命令:
npm run build
node bootstrap/ssr/ssr.js
如果你正在使用 【Inertia 和 SSR】,你可以使用 inertia:start-ssr
Artisan 命令来启动 SSR 服务器:
php artisan inertia:start-ssr
Laravel 的【入门套件】已经包括了适当的 Laravel、Inertia SSR 和 Vite 配置。查看 【Laravel Breeze】,快速开始使用 Laravel、Inertia SSR 和 Vite。 |
脚本和样式标签属性
内容安全策略 (CSP) 随机数
如果你希望在你的 <script>
和 <style>
标签中添加一个 nonce
【属性】,作为你【内容安全策略(CSP)】的一部分,你可以通过在自定义【中间件】中使用 useCspNonce
方法来生成或指定一个 nonce:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Vite;
use Symfony\Component\HttpFoundation\Response;
class AddContentSecurityPolicyHeaders
{
/**
* 处理传入的请求。
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
Vite::useCspNonce();
return $next($request)->withHeaders([
'Content-Security-Policy' => "script-src 'nonce-".Vite::cspNonce()."'",
]);
}
}
在调用 useCspNonce
方法后,Laravel 会自动在所有生成的 <script>
和 <style>
标签中包含 nonce
属性。
如果你需要在其它地方指定 nonce,包括 Laravel 入门套件中包含的 Ziggy @route
指令,你可以通过 cspNonce
方法获取它:
@routes(nonce: Vite::cspNonce())
如果你已经有一个 nonce,并希望让 Laravel 使用它,可以将该 nonce 传递给 useCspNonce
方法:
Vite::useCspNonce($nonce);
子资源完整性 (SRI)
如果你的 Vite 清单中包含了资产的 integrity
哈希,Laravel 将自动在它生成的任何 <script>
和 <style>
标签上添加 integrity
属性,以强制执行子【资源完整性】(Subresource Integrity, SRI)。默认情况下,Vite 并不会在其清单中包含 integrity
哈希,但你可以通过安装 vite-plugin-manifest-sri
NPM 插件来启用此功能:
npm install --save-dev vite-plugin-manifest-sri
然后,你可以在 vite.config.js
文件中启用此插件:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import manifestSRI from 'vite-plugin-manifest-sri';
export default defineConfig({
plugins: [
laravel({
// ...
}),
manifestSRI(),
],
});
如果需要,你还可以自定义清单中查找完整性哈希的键:
use Illuminate\Support\Facades\Vite;
Vite::useIntegrityKey('custom-integrity-key');
如果你希望完全禁用自动检测完整性哈希,你可以将 false
传递给 useIntegrityKey
方法:
Vite::useIntegrityKey(false);
任意属性
如果你需要在 <script>
和 <style>
标签中添加额外的属性,例如 data-turbo-track
属性,你可以通过 useScriptTagAttributes
和 useStyleTagAttributes
方法来指定这些属性。通常,这些方法应该在服务提供者中调用:
use Illuminate\Support\Facades\Vite;
Vite::useScriptTagAttributes([
'data-turbo-track' => 'reload', // 为属性指定值...
'async' => true, // 为属性指定没有值...
'integrity' => false, // 排除本应包含的属性...
]);
Vite::useStyleTagAttributes([
'data-turbo-track' => 'reload',
]);
如果你需要有条件地添加属性,你可以传递一个回调函数,该函数将接收资产的源路径、URL、清单块以及整个清单:
use Illuminate\Support\Facades\Vite;
Vite::useScriptTagAttributes(fn (string $src, string $url, array|null $chunk, array|null $manifest) => [
'data-turbo-track' => $src === 'resources/js/app.js' ? 'reload' : false,
]);
Vite::useStyleTagAttributes(fn (string $src, string $url, array|null $chunk, array|null $manifest) => [
'data-turbo-track' => $chunk && $chunk['isEntry'] ? 'reload' : false,
]);
当 Vite 开发服务器正在运行时, |
高级自定义
开箱即用,Laravel 的 Vite 插件采用了合理的约定,这些约定适用于大多数应用程序;然而,有时你可能需要自定义 Vite 的行为。为了启用额外的自定义选项,你可以使用以下方法和选项,它们可以替代 Blade 指令 @vite
:
<!doctype html>
<head>
{{-- ... --}}
{{
Vite::useHotFile(storage_path('vite.hot')) // 自定义 "hot" 文件...
->useBuildDirectory('bundle') // 自定义构建目录...
->useManifestFilename('assets.json') // 自定义清单文件名...
->withEntryPoints(['resources/js/app.js']) // 指定入口文件...
->createAssetPathsUsing(function (string $path, ?bool $secure) { // 自定义构建资源的后端路径生成...
return "https://cdn.example.com/{$path}";
})
}}
</head>
在 vite.config.js
文件中,你应该指定相同的配置:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
hotFile: 'storage/vite.hot', // 自定义 "hot" 文件...
buildDirectory: 'bundle', // 自定义构建目录...
input: ['resources/js/app.js'], // 指定入口文件...
}),
],
build: {
manifest: 'assets.json', // 自定义清单文件名...
},
});
纠正开发服务器 URL
Vite 生态系统中的一些插件假设以斜杠开头的 URL 总是指向 Vite 开发服务器。然而,由于 Laravel 集成的特性,情况并非如此。
例如,vite-imagetools
插件在 Vite 提供资源时会输出如下 URL:
<img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">
vite-imagetools
插件期望输出的 URL 会被 Vite 拦截,然后插件处理所有以 /@imagetools
开头的 URL。如果你正在使用期望这种行为的插件,你需要手动修正这些 URL。你可以在 vite.config.js
文件中使用 transformOnServe
选项来实现。
在这个特定的例子中,我们将在生成的代码中将所有 /@imagetools
前面加上开发服务器的 URL:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import { imagetools } from 'vite-imagetools';
export default defineConfig({
plugins: [
laravel({
// ...
transformOnServe: (code, devServerUrl) => code.replaceAll('/@imagetools', devServerUrl+'/@imagetools'),
}),
imagetools(),
],
});
现在,当 Vite 提供资源时,它会输出指向 Vite 开发服务器的 URL:
- <img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">
+ <img src="http://[::1]:5173/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">