首页  >  文章  >  web前端  >  Inertia.js 采用指南:概述、示例和替代方案

Inertia.js 采用指南:概述、示例和替代方案

Patricia Arquette
Patricia Arquette原创
2024-10-24 05:34:02510浏览

作者:Rahul Chhodde✏️

现代前端框架与其专用的全栈框架完美搭配——例如 React 与 Next.js、Vue 与 Nuxt.js 以及 Svelte 与 SvelteKit。但是,当将 React 等现代前端解决方案与 Laravel 等传统后端或服务器端框架配对时,同样的易用性和开箱即用的支持似乎是不可能的。

JavaScript 前端解决方案和传统后端框架之间的适应性差距由 Inertia.js 填补。在本采用指南中,我们将学习如何使用 Inertia 构建具有传统后端框架和现代 JavaScript 前端的单页应用程序 (SPA),同时维护服务器端路由。

什么是 Inertia.js?

Inertia.js 是一个工具,允许开发人员使用流行的前端和后端框架构建现代 SPA,而无需中间的 API。 Inertia 由 Jonathan Reinink 创建于 2019 年,其主要思想是在利用现有服务器端框架的同时简化构建现代 SPA 的过程。

简单来说,Inertia 就像粘合剂一样,将服务器端和客户端框架粘合在一起,确保后端和前端之间的高效通信。借助 Inertia,您无需为前端和后端或服务器端维护两个不同的代码库,而是像单体一样在单个代码库中开发整个应用程序。

Inertia.js 随着时间的推移发生了怎样的变化?

最初,Inertia 仅支持 Vue 和 Laravel。随着其后续版本的发展,它不断发展并扩展了对更多框架的支持。

现代的 Inertia 整体提供了重要的功能,例如服务器端渲染 (SSR)、自动资产版本控制、页面组件延迟加载、TypeScript 支持等等。稍后我们将在讨论框架集成时探讨其框架支持。

Inertia.js 的工作原理

Inertia 的作用就像前端和后端之间的适配器。它与普通SPA有以下几个方面的不同:

  • 维护服务器端路由,同时提供类似 SPA 的体验
  • 用小型提取请求替换全页重新加载
  • 接收服务器返回的 JSON 数据
  • 需要更少的 JavaScript 来进行水合

当使用 Inertia 支持的应用程序从浏览器发出请求时,它首先到达后端。结果,创建了 Inertia 响应,首先通过 Inertia 客户端将完整的 HTML 文档与 Inertia JavaScript 库返回到浏览器。

对于后续导航,Inertia 客户端发出获取请求并接收从服务器返回的 JSON 数据。然后,客户端使用收到的数据更新前端,并将更改反映在应用程序上,而无需重新加载整个页面。

这是一个以可视化方式解释整个过程的流程图:
Inertia.js adoption guide: Overview, examples, and alternatives

进一步阅读:

  • Inertia.js 简介

为什么选择 Inertia.js?

如果您必须为 SPA 使用传统的后端框架,但可以自由地处理前端,那么您应该考虑使用 Inertia 或类似的工具。

Inertia 是为 Laravel 量身定制的,为 Laravel 项目提供了更高的稳定性。如果您是一名 Laravel 开发人员,并且想要做的不仅仅是 Blade 模板默认提供的功能,那么 Inertia 可能是您想要尝试的东西。

您可以探索更多惯性可以成为您朋友的用例。接下来的两节介绍使用 Inertia 的一些优点和缺点,这将帮助您做出明智的决定,选择它进行应用程序开发。

Inertia.js 的缺点

SPA 一般有一些已知的缺点,我们不会在这里讨论。相反,我们将讨论 Inertia 作为开发实用程序的缺点。

灵活性较差

使用 Inertia,您可以在单个代码库中维护应用程序的前端和后端。这种紧密耦合使得 Inertia 不适合需要单独维护前端和后端以实现更好的可维护性、关注点分离、可扩展性、独立开发、技术堆栈灵活性等原因的项目。

开发者经验

使用像 Inertia 这样的工具可以为您的堆栈添加更多实用工具来探索和学习。了解惯性特定的模式和约定有一个适度的学习曲线,这可能有点烦人和耗时。

由于前端和后端采用 Inertia 等工具还不是主流,因此没有标准的方法来使用它们。因此,放弃 Inertia 需要进行大量的重构,尤其是在前端。

此外,测试复杂性,尤其是 API 和单元测试,必然会增加,因为前端和后端之间的边界在一个整体中重合。

小社区

Inertia 在 GitHub 上拥有超过 6,000 颗星和超过 85 名贡献者。它的 Laravel 适配器拥有超过 2,000 颗星。所有这些统计数据加起来远低于同类工具,这些工具不提供与 Inertia 一样多的功能和框架支持。

因此,在某些情况下,您可能想用它构建一些特定的东西,但却找不到足够的参考资料和指南来遵循。

请参阅下表,了解 Inertia.js 和 Livewire 等一些竞争者之间的直接比较。

进一步阅读:

  • Livewire 与 Inertia.js:比较 Laravel 前端

技术考虑

使用 Inertia 首先使应用程序离线可能会很复杂,因为使用此工具建立合理的缓存策略并不简单。您还应该记住,Inertia 默认情况下会在每个请求上发送完整页面组件,从而增加有效负载大小,这可以通过部分重新加载来解决。

Inertia.js 的优点

Inertia 与传统的客户端渲染 SPA 相比具有一些普遍优势。让我们一一讨论它的一些主要优点。

无缝集成

Inertia 与流行的前端和后端框架完美集成,并在其演示版本中为 Vue 提供第一手支持。支持的框架和库(包括前端和后端)包括 Laravel、Rails、Phoenix、Django、React、Vue 和 Svelte。

Laravel 允许您使用 Vite 构建您的资产,与基于 Webpack 的 Laravel Mix 相比,为您提供更快、更高效的开发体验。如果您的目标是实现基于 JavaScript 的前端,那么基于 Vite 的资产捆绑非常适合您。

进一步阅读:

  • Inertia.js、Vue.js 和 AdonisJs 入门
  • 使用 Laravel 和 Vue 创建单页应用程序

简化开发

尽管如上所述开发人员体验稍差,但 Inertia 提供了简化的集成,无需单独的 API 即可使前端和后端协同工作。 Inertia 允许您使用入门套件并提供手动安装指南来设置客户端和服务器端环境以进行开发。

表现

Inertia 应用程序不是将带有大量 JavaScript 包的完全服务器渲染的 HTML 发送到客户端,而是接收带有初始 JSON 数据的最小 HTML shell,这在客户端上渲染速度相对较快。

这使得基于 Inertia 的应用程序的初始性能略好于常规客户端渲染的 SPA,而不会增加复杂性。它还提高了整体质量更高的用户体验,并改进了首次内容绘制(First Contentful Paint),这是一个重要的核心网络重要指标。

进一步阅读:

  • SPA 的核心 Web Vitals 最佳实践

SEO友好

基于惯性的应用程序使用服务器端路由,这会产生更整洁、更容易抓取的 URL。这使得处理每个页面的元数据变得非常简单。此外,正如上一点所讨论的,由于发送到客户端的初始数据量很少,这些应用程序可能具有更好的 FCP 分数。

这两个功能结合起来可以带来更好的 SEO,并使 Inertia.js 应用程序比传统 SPA 更具优势。

提示:如果客户端渲染 (CSR) 对 FCP 指标产生负面影响,您可以选择使用 Inertia.js 的 SSR 插件的完全服务器渲染应用来提高分数。

捆绑尺寸

由于 Inertia.js 充当前端和后端之间的适配器,因此它非常紧凑(应该如此),压缩和压缩后仅重约 15kB。

文档

Inertia 文档可让您立即开始使用,尤其是在使用 Laravel 作为后端框架时。它还具有旧版本的升级指南,涵盖从一般到高级的概念,全部集中在一个地方。

Inertia.js 入门

让我们学习如何使用两种最流行的前端和后端解决方案设置 Inertia:基于 Laravel 的后端和由 React 驱动的前端。您可以在此 GitHub 存储库中找到本教程中涵盖的所有代码。

请注意,为了简单起见,此设置不涉及使用 TypeScript。

服务器端安装

假设你的机器上安装了 Laravel,让我们使用 Laravel 安装程序命令创建一个新的 Laravel 项目:

laravel new

您应该在开发者终端中看到如下内容:
Inertia.js adoption guide: Overview, examples, and alternatives
在终端中执行该命令并为您的项目提供名称后,安装程序将要求您选择启动工具包和测试框架、初始化 Git 存储库,并完成其他设置流程。

像 Breeze 或 Jetstream 这样的入门套件提供了一些现成的基于 Inertia.js 的脚手架和演示应用程序,但我们不想要这样。我们将从头开始设置。

进一步阅读:

  • Laravel Breeze 的 Inertia-React 堆栈与 Next.js 和 Gatsby
  • Laravel 与 AdonisJs:你应该使用哪个?

安装步骤结束时,系统将提示您选择一个数据库。我选择了 pgsql,因为我使用 PostgreSQL 来解释本文。根据您的数据库偏好选择您的数据库。

接下来,我们应该通过在终端中运行以下 Composer 命令来安装 Laravel 的 Inertia.js 集成:

composer require inertiajs/inertia-laravel

上面的命令将安装 Inertia 的 Laravel 适配器及其依赖项。它还将为 Laravel 和 Inertia 的合作奠定基础。

之后,让我们添加 Inertia 中间件来处理 Laravel 中的 Inertia 请求。使用以下 artisan 命令来执行此操作:

laravel new

客户端安装

我们将使用 React 来处理页面和组件,而不是 Laravel 的默认 Blade 模板。让我们进入项目文件夹并使用以下命令安装 React 和 React DOM。使用您选择的 Node 包管理器来执行此操作:

composer require inertiajs/inertia-laravel

我们还要安装 Vite 的 React 插件作为开发依赖项,因为我们将在整个项目中使用 Vite 作为我们的资产管理器:

php artisan inertia:middleware

最后,使用以下命令添加对 React 的 Inertia 支持:

pnpm add react react-dom

我还在这个设置中使用了 Tailwind CSS,这是完全可选的。如果您还想安装 Tailwind CSS,则与使用 React 或 Vue 应用程序安装 Tailwind CSS 时遵循的步骤相同。

配置

首先,在resources/js目录中找到app.js文件,将其重命名为app.jsx,并将其内容替换为以下内容:

pnpm add --save-dev @vitejs/plugin-react

上述更改将帮助 Inertia 识别我们的页面并将其链接到正确的路线。

接下来,我们将 resources/view 目录中的welcome.blade.php 文件重命名为 app.blade.php,并将其内容替换为以下内容:

pnpm add @inertiajs/react

请注意,在网页的基本 HTML 结构中,此文件包含一些注入某些脚本以运行重新加载、添加脚本等所需的 Inertia 和 Vite 指令。

接下来,在 bootstrap/app.php 文件中添加所需的中间件来处理 Inertia 特定的请求:

import { createInertiaApp } from "@inertiajs/react";
import { createRoot } from "react-dom/client";
import "../css/app.css";

createInertiaApp({
  resolve: (name) => {
    const pages = import.meta.glob("./Pages/**/*.jsx", { eager: true });
    return pages[`./Pages/${name}.jsx`];
  },
  setup({ el, App, props }) {
    createRoot(el).render(<App {...props} />);
  },
});

我们还可以配置 React 插件来与 Vite 配合使用,享受它提供的好处:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  @viteReactRefresh
  @vite('resources/js/app.jsx')
  @inertiaHead
</head>
<body>
  @inertia
  <div id="app"></div>
</body>
</html>

最后,让我们使用以下命令运行 Laravel 和 React:

<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use App\Http\Middleware\HandleInertiaRequests;

return Application::configure(basePath: dirname(__DIR__))
  ->withRouting(
    web: __DIR__.'/../routes/web.php',
    commands: __DIR__.'/../routes/console.php',
    health: '/up',
  )
  ->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        HandleInertiaRequests::class,
    ]);
  })
  ->withExceptions(function (Exceptions $exceptions) {
    //
  })->create();

我们可以编写一个 Shell 脚本来在单个终端窗口中一起运行这些命令,但为了让事情简单明了,现在让我们在两个单独的终端中运行它们。

这些命令执行成功后,可以看到两个本地URL。运行 Laravel 来查看您的 Laravel 应用程序的外观。至此,您已经成功使用 Inertia 设置了一个基本应用程序!

Inertia.js 的主要功能

您可以使用 Inertia 应用程序做很多事情。让我们来看看您应该了解的一些突出功能。

页面和布局

为了更好地组织不同的布局和页面,请在 resources/js 目录中创建两个子目录。您还可以在此处的单独目录中管理组件,并根据需要在页面中使用它们。

这是我们主要布局的一个简单示例:

import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [
    laravel({
      input: "resources/js/app.jsx",
      refresh: true,
    }),
    react(),
  ],
  resolve: {
    alias: {
      "@": "/resources/js",
    },
  },
});

这基本上是一个用作基本布局的组件,因此被放置在专用的布局文件夹中。 MainLayout 现在可以用作我们页面中的组件,如以下代码所示:

laravel new

以下是 MainLayout.jsx 和 About.jsx 如何使用 Tailwind CSS 提供的样式一起形成一个工作页面:
Inertia.js adoption guide: Overview, examples, and alternatives

链接和路由

使用传统的 Laravel 路由,可以轻松创建新路由并挂钩到我们在上一节中了解的页面中。尽管它不是基于文件的,但路由管理起来相当简单。如果您使用过 Express 和 Fastify 等基于 JavaScript 的后端框架,那么您已经熟悉 Laravel 中路由的工作方式。

导航到routes/web.php文件,添加新路由,并使用Inertia的render方法渲染相关页面,如下代码所示:

composer require inertiajs/inertia-laravel

Inertia 中的动态链接类似于 React 和 Next,可以使用 Inertia 的 Link 组件来完成,如下所示:

php artisan inertia:middleware

下面的屏幕截图演示了我们刚刚在上面的代码块中创建的导航的类似 SPA 的动态行为:
Inertia.js adoption guide: Overview, examples, and alternatives

HTTP 请求(GET/POST/非 GET 请求)

Inertia 提供了一个 useForm 钩子来处理 GET 和 POST 请求,以处理状态和表单提交。它还提供了 usePage 挂钩,它允许您访问从服务器传递到客户端的共享数据,例如成功或失败消息。

这是一个简单的示例,它发出 GET 和 POST 请求来加载和发送用户数据。请注意,GET 请求由 Inertia 隐式处理,而我们使用 useForm 挂钩中的 post 方法发出 POST 请求以将数据发送到服务器:

pnpm add react react-dom

使用这种方法,我们可以组合一个页面来从数据库中获取数据列表,将其显示在 HTML 表格中,并使用如下所示的表单将更多此类数据添加到数据库中:
Inertia.js adoption guide: Overview, examples, and alternatives

进度指标

Inertia.js 提供基于 NProgress 的进度指示。您可以在建立 App.jsx 文件时启用此功能,并为进度指示器提供配置设置:

pnpm add --save-dev @vitejs/plugin-react

如果您不熟悉 NProgress 加载动画的样子,请看一下:
Inertia.js adoption guide: Overview, examples, and alternatives

数据库集成

如果您经常使用 Laravel,那么将数据库集成并使用到您的 Inertia 设置中并不需要花费太多时间。只需在 .env 文件中添加所需的数据库凭据,确保您使用正确的数据库驱动程序,查看 config/database.php 文件,然后就可以开始了。

有了现有的数据库,您可以使用 Laravel 的迁移系统来定义所需的数据库模式。我没有数据库,所以我创建了一个数据库,并使用 Laravel Seeder 机制在其中填充了一些虚假的用户数据,以在前端显示。以下是我之后遵循的一些步骤:

  • 在应用程序目录中为我的用户数据创建了一个模型,并创建了一个 HTTP 控制器来处理有关此数据的数据库请求
  • 在 resources/js/Pages 目录中创建了一个 Users 页面,并为其提供了一个带有用户数组的 prop。该用户数组通过本质上使用 Inertia 发出的 GET 请求获取所需的数据。我们还可以发出 POST 请求将数据添加到数据库
  • 在routes/web.php 文件中定义用户路由并将我们的HTTP 控制器链接到它

对于 Laravel 生态系统的新手或不经常使用 Laravel 数据库的人来说,迁移和填充数据库时可能需要更多的时间。在这种情况下,清除配置缓存可能会极大地帮助消除由缓存的配置选项引起的错误。

Inertia.js 用例

惯性的潜在应用是多种多样的。使用 Inertia 将 Laravel 与现代 JavaScript 前端配对,可以简化具有强大后端功能的单体应用程序的全栈开发。

虽然它并不适合每个团队或情况,但在以下一些用例中您可能会发现惯性是一个不错的选择:

  • 不想依赖 Blade 进行模板化并希望使用强大的解决方案来处理客户端功能的应用程序
  • 使用 Laravel 作为后端但希望利用主要为基于 JavaScript 的前端框架制作和维护的现代库的旧应用程序
  • 计划迁移到基于 Laravel 的后端以享受传统服务器技术而不是无服务器技术提供的优势的现代应用程序
  • SPA 想要在搜索引擎上获得更好的可见性以及 SSR 的性能优势
  • 对于那些热爱并想要同时使用 PHP 和 JavaScript 的人

Inertia.js vs. Livewire vs. Hybridly

Inertia 并不是桥接服务器端和客户端框架和库的唯一解决方案。 Livewire 和 Hybridly 是另外两种流行的工具,各有优点和缺点。在比较您的选择时,您可能需要考虑:

  • 社区 — 与 Livewire 相比,Inertia.js 的社区相对较小,但比 Hybridly 更好。
  • 功能 — Livewire 和 Hybridly 不提供实现前端框架的支持,而 Inertia.js 以其对主要基于 JavaScript 的前端解决方案的支持而闻名。
  • 性能 — 这主要取决于实现,但基于 Inertia.js 的 SPA 可以提供更好的感知性能,而使用 Livewire 和 Hybridly 的服务器渲染应用程序可以更好,因为大多数页面都是服务器渲染的.
  • 文档 — 与 Hybridly 相比,Livewire 和 Inertia.js 拥有很好的文档,Hybridly 相当新,并且还有进一步改进的空间。

此表提供了这三者如何比较的有用快照,以进一步告知您的决定:

Feature Inertia.js Livewire Hybridly
Server-side framework Laravel, Rails Laravel only Laravel only
Client-side framework Vue.js, React, Svelte None (PHP-based) Vue.js
SPA-like experience Yes Yes Yes
Server-side rendering (SSR) Optional Yes Yes
Real-time updates No (needs additional setup) Yes Yes
Full-page reloads No No No
Learning curve Moderate Low Moderate
Component-based architecture Yes Yes Yes
State management Client-side Server-side Both
SEO-friendly Good Excellent Excellent
Backend-driven UI Partial Full Full
Progressive enhancement Limited Yes Yes
File uploads Supported Native support Supported
Pagination Supported Native support Supported
Form handling Client-side Server-side Both
Authentication Supported Native support Supported
Authorization Supported Native support Supported
Testing Both client & server Server Both client and server
Ecosystem/Community Small Large Small (newer)
Performance Very good Good Very good
Bundle size Larger (due to JS framework) Smaller Moderate
Offline support Possible Limited Possible
Mobile app development Possible Not ideal Possible

结论

在本采用指南中,我们了解了 Inertia.js 是什么以及如何使用它来利用 Laravel 等传统后端框架和 React 等现代前端库创建混合应用程序。

我们了解了使用 Inertia 的优缺点、它的一些实际应用以及使用 Laravel 设置它的示例。如果您在遵循本指南时遇到困难,请考虑为我们介绍的项目克隆此 GitHub 存储库,或者发表评论,我很乐意为您提供帮助。


您是否添加新的 JS 库来构建新功能或提高性能?如果他们反其道而行怎么办?

毫无疑问,前端变得越来越复杂。当您向应用程序添加新的 JavaScript 库和其他依赖项时,您需要更多的可见性以确保您的用户不会遇到未知问题。

LogRocket 是一个前端应用程序监控解决方案,可让您重放 JavaScript 错误,就像它们发生在您自己的浏览器中一样,以便您可以更有效地对错误做出反应。

Inertia.js adoption guide: Overview, examples, and alternatives

LogRocket 可以与任何应用程序完美配合,无论框架如何,并且具有用于记录来自 Redux、Vuex 和 @ngrx/store 的其他上下文的插件。您无需猜测问题发生的原因,而是可以汇总并报告问题发生时应用程序所处的状态。 LogRocket 还监控您的应用程序的性能,报告客户端 CPU 负载、客户端内存使用情况等指标。

自信地构建 - 开始免费监控。

以上是Inertia.js 采用指南:概述、示例和替代方案的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn