如何在 Laravel 中正确加载特定于页面的脚本?

问题描述 投票:0回答:2

在 Laravel 10 中,js 资源默认使用 Vite 编译,从 /resources/js 到 /public/build/assets/。它生成版本化文件,这意味着它们就像 file-987dfdf.js (随机字符串)。 在刀片模板中,@vite() 指令为开发和生产模式生成正确的路径。而且还注入一个连接到其服务器以进行热模块替换的脚本。 通常@vite是从主布局的HEAD部分调用的。

现在,我的问题是:如何从其他刀片模板加载特定于页面的脚本(使用@stack和@push)?如果我在那里使用@vite,那么它将再次注入服务器客户端脚本。如果我不使用@vite,我就无法正确引用脚本的构建版本。

我确信有一些更聪明的方法,但无法弄清楚。在这种情况下,文档没有帮助。

php laravel build vite
2个回答
0
投票

如果我正确阅读你的帖子:看来你正在使用@vite并且没有指定任何文件?

试试这个。在您的布局中,在合适的地方使用它:

@stack('vite')

然后在您想要加载自定义样式或脚本的其他刀片文件中,推送到该文件。

示例:

@push('vite')
    @vite(['resources/js/file.ext'])
@endpush

有了这个,您不需要知道资源的最终文件名,只需要知道资源文件夹中资源的相对路径。


0
投票

这是基于意见的,我将展示我的做法:

假设你有这些路线

Route::get('/', ...)->name('front');
Route::get('/about', ...)->name('about');
  1. vite.config.ts
    中定义每页条目(您可以设置全局模式以自动发现页面 - 请参阅此处的讨论中接受的答案)
// vite.config.js

input: [
    'resources/js/common.js', // common file for every page and backup

    'resources/js/front.js', // front page only
    'resources/js/about.js', // about page only
],
  1. 创建查看composer
  2. 解析每条路线的入口点(我通常命名每条可能的路线 - 您定义当前路线的方法可能会有所不同)
// app/View/Composers/EntrypointComposer

use Illuminate\View\View;
use Illuminate\Support\Facades\Route;

class EntrypointComposer
{
    public function compose(View $view): void
    {
        // "entrypoint" key here is the name of the variable
        // which will be used in a blade file
        $view->with('entrypoint', $this->resolveEntrypointPerPage());
    }

    /**
     * Resolve vite entrypoint
     * based on current route name
     */
    private function resolveEntrypointPerPage(): string|array
    {
        return match (Route::current()->getName()) {
            // On a page named `front` load `common.js` and `front.js`
            'front' => ['resources/js/common.js', 'resources/js/front.js'],

            // You may import `common.js` file within `about.js`
            // Meaning there is no need to add extra point for `common.js`
            'about' => 'resources/js/about.js',

            // etc ...

            // Backup. For non specified pages `common.js` file will be loaded
            default => 'resources/js/common.js',
        };
    }
}
  1. 在 ServiceProvider 中注册
// app/Providers/AppServiceProvider

use Illuminate\Support\Facades\View;

public function boot()
{
    View::composers([
        EntrypointComposer::class => 'partials.head', // path to the blade component file (**NOT** page) where `@vite` directive is used

        // ...
    ]);
}
  1. 将密钥
    $entrypoint
    包含在刀片文件中
// partials/head.blade.php

@vite($entrypoint)
© www.soinside.com 2019 - 2024. All rights reserved.