PHP-Vite.js桥接工具,框架无关

1.0 2023-01-03 09:27 UTC

This package is auto-updated.

Last update: 2024-08-29 10:06:00 UTC


README

PHP from Packagist Test Suite Coverage Status

PHP-Vite桥接构建工具,适用于任何框架。

💿 composer require dakujem/peat

此工具帮助将Vite捆绑的JS应用集成到PHP服务器端的网页中。

它提供了一种生成所需资产<script><link>标签的方式。

Vite

Vite(又称Vite.js)由两部分组成

  • 开发服务器
  • bundler

要集成一个JS应用,后端必须输出如下片段

  • 来自bundler(生产)的文件
    <!-- PRODUCTION -->
    <script type="module" src="/placeholder/assets/main.cf1f50e2.js"></script>
    <script type="module" src="/placeholder/assets/vendor.5f8262d6.js"></script>
    <link rel="stylesheet" href="/placeholder/assets/main.c9fc69a7.css" />
  • 指向由开发服务器提供的文件的链接
    <!-- DEVELOPMENT -->
    <script type="module" src="https://:5173/@vite/client"></script>
    <script type="module" src="https://:5173/src/main.js"></script>

为了获得最佳的开发体验,我们只想关注两种情况下的JS应用的入口点main.js
理想情况下,我们希望实现以下内容

  <!-- PHP template -->
  <?php echo vite('main.js'); ?>
  
  <!-- or other templating systems, like Twig -->
  {{ vite('main.js') }}

要实现这一点,Peat将读取Vite为每个捆绑生成的manifest JSON文件。
在开发中,我们只需简单地提供入口点(以及支持库@vite/client),浏览器将加载其余的文件作为ES模块。

Vite配置

Vite(vite.config.js)必须配置为输出manifest文件并覆盖默认的入口点

  • build.manifest必须设置为true
  • build.rollupOptions.input应指向main.js(或其他JS入口点)

更多详细信息请参阅Vite后端集成指南

💡

您还可以将build.outDir设置为指向后端公开目录的子目录,这样在每次构建后您就不必手动移动构建文件。

配置故障排除

测试配置是否正常工作的最简单方法是,将以下片段放入您的PHP服务器端的HTML模板中,并观察输出。

启动开发服务器(Vite npm run serve 和PHP),
然后将此片段放入HTML模板中

<?php echo Dakujem\Peat\ViteHelper::populateDevelopmentAssets('src/main.js', 'https://:5173'); ?>

它应该生成指向开发资产的<script>标签,JS应用应从服务器加载。
如果不起作用,请检查入口名称和Vite服务器URL和端口。入口名称应与build.rollupOptions.input选项相匹配。

接下来,要测试一个捆绑包,
通过运行npm run build来构建捆绑包,
将dist文件移动到您的PHP服务器公开根目录中(或配置build.outDir选项),
然后将前面的片段替换为以下片段(将my-js-widget替换为正确的目录)

<?php echo Dakujem\Peat\ViteHelper::extractAssets('src/main.js', './my-js-widget/manifest.json', '/my-js-widget'); ?>

它应该为您的JS和CSS生成<script><link>标签。
请注意,manifest文件的路径,因为它会根据您从何处运行片段而改变。根据需要进行调整。
了解'./my-js-widget/manifest.json'是服务器路径,而'/my-js-widget'是URL前缀的一部分,指向资产(即您将dist文件移动到的位置,相对于公开根目录中的PHP脚本)。
此外,请注意'/my-js-widget'是绝对的,您可能需要添加您项目的基路径或使用相对偏移量(见下文)。

一旦这个工作,我建议您继续配置桥接服务(见下文)。

💡

如果上述方法都不奏效,请阅读Vite后端集成指南,尝试找出哪些HTML能正确服务于您的JS应用,然后将其与Peat输出的结果进行比较,并相应地调整变量。

桥接使用

最直接的方法是在您的服务容器中将ViteBridge注册为服务。

根据您的运行环境,此服务将创建一个合适的"入口定位器"(ViteLocatorContract),为Vite入口填充资源。

要获取资源URL(或HTML标签),请使用ViteLocatorContract::entry方法(见下例)。

示例

假设JS源文件位于<project>/js/src,公共目录为<project>/publicmy-js-widget可以替换为任何路径。

按照以下方式配置Vite

// vite.config.js
import {defineConfig} from "vite";

export default defineConfig({
  build: {
    manifest: true,
    outDir: '../public/my-js-widget', // output directly to the public dir
    rollupOptions: {
      // overwrite default .html entrypoint
      input: 'src/main.js',
    }
  }
});

按照以下方式配置ViteBridge服务

$bridgeService = new ViteBridge(
    manifestFile: ROOT_DIR . '/public/my-js-widget/manifest.json',
    cacheFile: TEMP_DIR . '/vite.php',   // can be any writable file
    assetPathPrefix: '/my-js-widget',   // all asset paths from the manifest will be prefixed by this value
    devServerUrl: 'https://:5173',
);

然后直接使用它

$locator = $bridgeService->makePassiveEntryLocator(useDevServer: $isDevelopment);
$html = (string) $locator->entry('src/main.js');

然后在模板中稍后

<head>
  <?php echo $html; ?>
</head>

上述方法会将所有必要的HTML标签喂给main.js入口点,传递给$html变量,无论是开发服务器还是任何捆绑(取决于$isDevelopment变量)。

您可能想要注册一个使用定位器并在模板内部调用的方法,如下所示

$vite = function (string $entryName) use ($locator) {
    return $locator->entry($entryName)
}

然后在模板中稍后调用

<head>
  <?php echo $vite('src/main.js'); ?>
</head>

例如,在Twig或Latte中,您可以注册一个过滤器如下使用

<head>
  {{ vite('src/main.js') }}
</head>

生产设置

在生产环境中,性能至关重要。

为了避免在每次请求时都读取和解析JSON清单文件,Peat允许您一次性解析JSON清单内容,并将其导出为PHP文件。然后Peat将包含该优化文件而不是读取JSON清单。

💡

请确保在生产环境中启用此缓存机制。在高负载场景下,包含一个微小的PHP文件比在每次请求时解析JSON文件要快得多。

要填充生产环境的缓存文件,请调用ViteBundleLocator::populateCache

$bridgeService->populateCache();

然而,此文件必须在使用时重新填充(在每次Vite构建时)。

这是通过在部署/CI过程中构建步骤中调用ViteBuildLocator::populateCache()来实现的。

如果您没有使用部署管道或CI进行部署,我建议您比较缓存文件和清单文件的文件时间戳,或在您的缓存清除过程中包含缓存文件。

处理相对路径

到目前为止,我们使用的是资源的绝对路径。这是推荐的

💡

assetPathPrefix应包含项目的基本路径以及清单文件的路径,并且应该是绝对路径。

但是,如果您需要使用相对路径,您也可以。

ViteLocatorContract::entry方法接受一个名为"相对偏移量"的第二个参数,它旨在用于需要为每次调用添加前缀的assetPathPrefix的情况。

该参数应在不在公共文档根目录中的脚本中使用。
该参数通常包含像..../..等字符串,指向公共根目录。

使用绝对路径时不要使用此参数,因为它会破坏生成的URI。

高级使用

除了使用ViteBridge::makePassiveEntryLocator摩擦减少器之外,还可以组合自定义的入口定位器设置。定位器必须实现ViteLocatorContract接口。

提供了两个定位器来帮助您组合自己的定位器设置

  • CollectiveLocator与简单的可调用函数或其他定位器一起使用,以创建定位器堆栈(后备)
  • ConditionalLocator允许在堆栈中添加运行时条件以启用/禁用定位器

请参阅ViteBridge源代码以获取灵感。

兼容性

请注意,此工具(Peat)与Vite的工作方式紧密耦合。

目前,Peat支持Vite版本v2v3v4及更高版本。

除非 Vite.js 生成其 manifest.json 文件的方式发生重大更改,否则 Peat 将与 Vite.js 的未来版本保持兼容。

集成