hammerstone/sidecar-inertia

一个用于在 AWS Lambda 上渲染 Inertia 应用的 Laravel 扩展包。

v0.0.5 2023-01-09 14:25 UTC

This package is auto-updated.

Last update: 2024-09-09 18:08:59 UTC


README

🚨 目前这个功能还在测试阶段!

您可以在 hammerstonedev/sidecar-inertia-demo 找到完整的 Jetstream + Inertia + Sidecar 示例仓库。

概览

本扩展包提供了一个 Sidecar 函数,用于在 AWS Lambda 上运行 Inertia 服务器端渲染

Sidecar 扩展包、部署和执行来自您的 Laravel 项目的 AWS Lambda 函数。

它适用于任何 Laravel 7 或 8 应用程序,无论托管在何处,包括您的本地计算机、Vapor、Heroku、共享虚拟服务器或其他任何类型的托管环境。

启用 SSR

遵循 官方 Inertia 文档 中的启用 SSR 指南是一个好的开始,但有一些事情您可以跳过

  • 您不需要 npm install @inertiajs/server
  • 您不需要 npm install webpack-node-externals
  • 当您到达“构建您的应用程序”部分时再回到这里

确保 inertia/laravel-inertia 至少是版本 0.5.1

安装

要引入此扩展包,请运行以下命令

composer require hammerstone/sidecar-inertia

这将同时安装 Sidecar。

使用 Sidecar 网关

更新您的 AppServiceProvider 以使用 SidecarGateway 作为默认的 Inertia SSR 网关

namespace App\Providers;

use Hammerstone\Sidecar\Inertia\SidecarGateway;
use Illuminate\Support\ServiceProvider;
use Inertia\Ssr\Gateway;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        // Use Sidecar to run Inertia SSR.
        $this->app->instance(Gateway::class, new SidecarGateway);
    }
}

更新配置

更新您的 config/inertia.php 以包含 Sidecar 设置

<?php

return [
    'ssr' => [
        'enabled' => true,

        'sidecar' => [
            // The Sidecar function that handles the SSR.
            'handler' => \Hammerstone\Sidecar\Inertia\SSR::class,
            
            // Log some stats on how long each Lambda request takes.
            'timings' => false,
            
            // Throw exceptions, should they occur.
            'debug' => env('APP_DEBUG', false),
            
            // Compile Ziggy routes with the Lambda function.
            'ziggy' => false
        ],
    ],

    // ...
];

配置 Sidecar

如果您还没有配置 Sidecar,您将需要这样做。

通过运行以下命令发布 sidecar.php 配置文件

php artisan sidecar:install

要交互式配置您的 Sidecar AWS 凭据,您可以运行

php artisan sidecar:configure

官方 Sidecar 文档提供了更详细的说明。

现在更新您的 config/sidecar.php 以包含此扩展包提供的功能。

<?php

return [
    'functions' => [
        \Hammerstone\Sidecar\Inertia\SSR::class
    ],
    
    // ...
];

更新您的 JavaScript

这仅涵盖 Vue3,请遵循 Inertia 文档中的 Vue2 或 React,并请打开任何问题。

您需要更新您的 webpack.ssr.mix.js 文件。这应该适用于大多数情况,但如果遇到错误,请打开任何问题。 (这是基于 Inertia 文档,略有修改。)

const path = require('path')
const mix = require('laravel-mix')

mix
    .js('resources/js/ssr.js', 'public/js')
    .options({
        manifest: false
    })
    .vue({
        version: 3,
        useVueStyleLoader: true,
        options: {
            optimizeSSR: true
        }
    })
    .alias({
        '@': path.resolve('resources/js')
    })
    .webpackConfig({
        target: 'node',
        externals: {
            node: true,
            // Sidecar will ship a file called compiledZiggy as a part of
            // the package. We don't want webpack to try to inline it
            // because it doesn't exist at the time webpack runs.
            // './compiledZiggy': 'require("./compiledZiggy")'
        },
        resolve: {
            alias: {
                // Uncomment if you're using Ziggy.
                // ziggy: path.resolve('vendor/tightenco/ziggy/src/js'),
            },
        },
    })

并将您的 resources/js/ssr.js 更新为如下所示。具体细节可能因应用程序而异。如果您使用 Ziggy,您可能需要取消注释 Ziggy 代码。 (这是基于 Inertia 文档,略有修改。)

import {createSSRApp, h} from 'vue'
import {renderToString} from '@vue/server-renderer'
import {createInertiaApp} from '@inertiajs/inertia-vue3'
// import route from 'ziggy';

exports.handler = async function (event) {
    // This is the file that Sidecar has compiled for us if
    // this application uses Ziggy. We import it using
    // this syntax since it may not exist at all.
    // const compiledZiggy = await import('./compiledZiggy');

    return await createInertiaApp({
        page: event,
        render: renderToString,
        resolve: (name) => require(`./Pages/${name}`),
        setup({app, props, plugin}) {
            // const Ziggy = {
            //     // Start with the stuff that may be baked into this Lambda.
            //     ...(compiledZiggy || {}),
            // 
            //     // Then if they passed anything to us via the event,
            //     // overwrite everything that was baked in.
            //     ...event?.props?.ziggy,
            // }

            // Construct a new location, since window.location is not available.
            // Ziggy.location = new URL(Ziggy.url)

            return createSSRApp({
                render: () => h(app, props),
            }).use(plugin).mixin({
                methods: {
                    // Use our custom Ziggy object as the config.
                    // route: (name, params, absolute, config = Ziggy) => route(name, params, absolute, config),
                },
            })
        },
    });
}

部署您的 SSR 函数

在您的 sidecar.php 中添加了 SSR 函数后,您应该运行 php artisan sidecar:deploy --activate 以部署您的函数。

这将编译您的 JavaScript,作为 beforeDeployment 钩子,因此您不必担心先执行这一步。

调试 SSR

建议您在本地部署 Sidecar 函数,以便您可以更快地测试 SSR。您可以从本地机器运行 php artisan sidecar:deploy --activate,您的 SSR 函数将被部署到 Lambda。

您还可以在 config/inertia.php 文件中将 ssr.sidecar.debug 设置为 true,这样当 SSR 失败时,Sidecar 会抛出异常而不是回退到客户端渲染。这有助于您快速诊断问题。

Ziggy(可选)

如果您使用 Ziggy,需要将一些 Ziggy 信息传递给您的 Lambda。您可以通过在 HandleInertiaRequests 中间件中添加以下内容来实现。

class HandleInertiaRequests extends Middleware
{
    public function share(Request $request)
    {
        $ziggy = new Ziggy($group = null, $request->url());
        $ziggy = $ziggy->toArray();

        // During development, send over the entire Ziggy object, so that
        // when routes change we don't have to redeploy.  In production,
        // only send the current URL, as we will bake the Ziggy config
        // into the Lambda SSR package.
        $ziggy = app()->environment('production') ? Arr::only($ziggy, 'url') : $ziggy;

        return array_merge(parent::share($request), [
            'ziggy' => $ziggy
        ]);
    }
}