v13.34.0。
注册与发布是不同的处理
loadViewsFrom() 会为命名空间注册查找路径。publishes() 注册复制源和复制目标,实际的复制由 vendor:publish 完成。在下面的示例中,即使不发布也可以使用 courier::deliveries.show。
src/CourierServiceProvider.php
resources/views/deliveries/show.blade.php。视图名中的点号在查找时会被转换为目录分隔符。
resources/views/deliveries/show.blade.php
loadViewsFrom() 第二个参数指定的 courier 构成了视图引用和覆盖目录的约定。
按文件查找覆盖位置
ServiceProvider::loadViewsFrom() 会在 view 被解析时,依次检查配置中的 view.paths。如果各路径下存在 vendor/courier 目录,就将该目录添加到命名空间中,最后再添加包的路径。
FileViewFinder 会依次查找该命名空间的路径,并返回第一个找到的文件。在使用标准 resources/views 的配置下,顺序如下。
这并不是整个目录的切换。即使用户只覆盖了 deliveries/show.blade.php,其他未覆盖的视图仍会从包中加载。
在存在多个
view.paths 的配置中,覆盖位置也可能有多个。resource_path('views/vendor/courier') 只是本示例中的发布目标,并不是将查找范围固定在该位置的处理。请使用包专属的命名空间,避免多个提供者向同一名称添加路径的设计。只自定义需要的视图
用户可以通过以下命令复制模板。指定提供者和标签,以免牵连其他资源。重新发布不会合并差异
VendorPublishCommand 通常在存在同名发布目标文件时跳过复制。--force 会覆盖现有文件。此外,--existing 也是”覆盖已发布文件”的选项,并不是保留用户编辑的模式。
无论哪种方式,都不是对旧版、新版和用户编辑进行比较后的合并。也不会自动从发布目标中删除已从包中移除的视图。请不要将更新步骤简化为”只需重新发布同一标签”。
将视图也作为公开 API 进行维护
不仅是视图名,接收的数据和引用的组件也会影响用户的自定义内容。例如,如果在新版中将trackingCode 改为其他变量名,保留旧模板的用户将无法从新代码中获得所需的值。
发布前,请确认以下约定。
- 不要随意更改命名空间和
deliveries.show等视图名。 - 记录传递的变量、类型以及必填与可选的区别。
- 将
@include和@extends的引用目标、Blade 组件的 props 也纳入变更范围。 - 在发布说明中写明修改过的视图,以及需要应用到已发布旧版模板的变更。
Blade 缓存不会更新覆盖文件
view:cache 会将 Blade 模板预编译为 PHP。ViewCacheCommand 首先执行 view:clear,然后收集普通视图路径和注册到命名空间的路径来查找编译对象。
与查找结果缓存区分开
FileViewFinder::find() 会将找到的路径保存到该 Finder 实例的 $views 数组中。此外,覆盖目录的存在性检查是在 loadViewsFrom() 的回调中进行的。即使在启动后添加了新目录,也不会自动加入已注册的查找路径。
view:clear 并不是一次性清除其他运行中进程所持有的 Finder 状态的命令。对于 Octane 等长时间运行的进程,请按照常规部署步骤重新加载。Finder 的 flush() 会清除查找结果,但不会注册新的覆盖目录。
发布前需要确认的事项
除了包的测试之外,还要在使用方应用程序中确认以下组合。只渲染最新模板的测试无法验证对已发布旧版的用户的兼容性。- 在未发布的状态下,渲染的是包中的视图。
- 只覆盖一个文件时,仅该文件优先,其他文件回退到包中。
- 在保留旧版已发布模板的状态下,也能使用新版传递的数据进行渲染。
- 普通的重新发布会保留自定义内容,未发布文件的添加也符合预期。
- 修改覆盖文件后
view:cache成功,并且重新启动后显示的是修改后的内容。
相关页面
视图
了解视图的创建、数据传递和预编译的基础知识。
Blade 模板
了解布局、include 和组件的用法。
版本兼容性管理
将模板约定的变更与发布策略关联起来。
Octane
了解长时间运行的应用程序的生命周期和重新加载。