youvision / think-static
ThinkPHP 8 项目部署插件:主项目通过 Composer 安装或更新依赖时,自动把 project 目录部署到 public/store。
Package info
github.com/indiboy-create/think-static
Type:composer-plugin
pkg:composer/youvision/think-static
Requires
- php: >=8.0
- composer-plugin-api: ^2.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
面向 ThinkPHP 的开源工程索引:组件、框架、服务与发布工具,按能力组织,持续整理。 仓库地址:https://github.com/indiboy-create/ThinkPHP-PanGu/ 在线站点:https://indiboy-create.github.io/ThinkPHP-PanGu/
think-static
ThinkPHP 8 项目部署插件。主项目通过 Composer 安装或更新依赖时,本插件自动把主项目 project 目录部署到 public/store/{path},保持 theme、view、extend、example、index.html、intro.html、readme.md 等目录与文件的配套结构。
主项目无需编写调用代码。
环境要求
- PHP >= 8.0
- Composer >= 2.2
- ThinkPHP 8 主项目
安装
composer require youvision/think-static
Composer 2.2 及以上版本默认拦截插件安装。在主项目 composer.json 中允许本包:
{
"config": {
"allow-plugins": {
"youvision/think-static": true
}
}
}
建议在 composer require 之前配置好 allow-plugins,这样首次安装即可完成自动部署。
主项目结构
项目根/
project/
project.json
theme/
css/app.css
view/
index.html
extend/
demo.php
example/
index.html
index.html
intro.html
readme.md
project是静态资源部署源目录,目录名可通过project_dir修改project.json是部署配置文件theme、view、extend、example以及 HTML、说明文件会一起部署
部署配置 project/project.json
完整示例:
{
"path": "demo",
"map": {
"theme": "theme",
"view": "view",
"extend": "extend",
"example": "example",
"index.html": "index.html",
"intro.html": "intro.html",
"readme.md": "readme.md"
},
"exclude": ["**/*.map"]
}
| 字段 | 必填 | 说明 |
|---|---|---|
path |
是 | 整个 project 部署到 public/store 下的目录名称,不能为空;支持多级目录 |
map |
否 | 部署映射,键为 project 下的相对路径,值为部署到 public/store/{path} 下的相对路径 |
map 的值 |
否 | 字符串为目标路径;true、null 或空字符串表示保持与源相同的路径 |
exclude |
否 | 排除规则,相对 project 根目录,支持 *、**、? 通配符 |
规则说明:
path必须配置且不能为空map留空或省略时,自动部署project下除project.json外的全部顶层条目project.json自身不会部署map中的条目必须存在于project下,否则部署失败- 两个条目不能使用相同或相互嵌套的目标路径
path和map的目标路径必须是相对路径,禁止绝对路径和..- 隐藏文件默认跳过,可通过
skip_dot_files关闭
部署全部顶层条目
配置 path,map 留空或只配置 exclude 时,自动部署 project 下除 project.json 外的全部顶层条目:
{
"path": "demo",
"exclude": ["**/*.map", "readme.md"]
}
部署结果:
project/theme → public/store/demo/theme
project/view → public/store/demo/view
project/extend → public/store/demo/extend
project/example → public/store/demo/example
project/index.html → public/store/demo/index.html
project/intro.html → public/store/demo/intro.html
project/readme.md → public/store/demo/readme.md
显式声明部署条目
{
"path": "demo",
"map": {
"theme": "theme",
"index.html": "index.html"
}
}
部署结果:
project/theme → public/store/demo/theme
project/index.html → public/store/demo/index.html
path 支持多级目录,例如 "path": "site/demo" 会部署到 public/store/site/demo。
调整单个条目目标
map 的值可以修改某个条目的部署路径,路径相对于 public/store/{path}:
{
"path": "demo",
"map": {
"theme": "themes/theme",
"index.html": "index.html"
}
}
部署结果:
project/theme → public/store/demo/themes/theme
project/index.html → public/store/demo/index.html
Composer 自动部署
插件监听 Composer 的 post-autoload-dump 事件,以下操作完成后自动执行部署:
composer install composer update composer dump-autoload
自动部署行为:
- 默认覆盖目标目录中的同名文件
- 主项目没有
project/project.json时静默跳过 - 部署失败只输出警告,不中断 Composer 安装或更新
- 部署完成后输出
think-static: 已部署 N 个静态文件到 public/store/{path}等提示
主题资源修改后,如果不想执行完整的 composer install,运行 composer dump-autoload 即可重新部署。
可选配置
在主项目 composer.json 中通过 extra.think-static 覆盖默认值:
{
"extra": {
"think-static": {
"root": "public/store",
"project_dir": "project",
"manifest": "project.json",
"force": true,
"skip_dot_files": true
}
}
}
| 配置项 | 默认值 | 说明 |
|---|---|---|
root |
public/store |
部署根目录,相对主项目根目录 |
project_dir |
project |
项目资源目录,相对主项目根目录 |
manifest |
project.json |
项目配置文件名,位于 project_dir 内 |
force |
true |
是否覆盖同名文件 |
skip_dot_files |
true |
是否跳过隐藏文件 |
修改配置后执行 composer dump-autoload 生效。
手动部署(可选)
主题资源变化但未执行 Composer 操作时,可在主项目中手动调用:
use Youvision\ThinkStatic\StaticAssets; $assets = new StaticAssets(app()->getRootPath(), [ 'root' => 'public/store', ]); $project = $assets->scan(app()->getRootPath()); $result = $assets->publish(app()->getRootPath(), true);
scan() 返回 Project 对象:
$project->sourcePath; // /项目根/project $project->targetPath; // demo $project->items; // 每个条目的 source、target、path、type $project->exclude; // ['**/*.map']
publish() 的第二个参数控制是否覆盖同名文件。手动调用时默认不覆盖,传入 true 才会覆盖。
publish() 返回:
[
'package' => '/项目根',
'target' => 'public/store/demo',
'items' => [
'theme' => [
'target' => 'public/store/demo/theme',
'copied' => 12,
'skipped' => 0,
'failed' => 0,
],
],
'copied' => 12,
'skipped' => 0,
'failed' => 0,
]
也支持指定其他 Composer 包的 project 目录:
$assets->publish('youvision/think-site'); $assets->publish('/path/to/vendor/youvision/think-site');
异常处理
scan() 和 publish() 在以下情况抛出 RuntimeException:
- 指定的 Composer 包未安装或没有安装目录
project目录或project.json不存在project.json不是有效 JSONpath未配置或为空map中的条目不存在path或map的目标路径无效- 多个条目使用相同或嵌套的目标路径
Composer 插件会自动捕获异常并输出警告,不会中断依赖安装。
验证
php tests/verify.php
测试脚本使用临时目录模拟主项目,覆盖显式 map、默认 map、path 必填、多级 path、目标路径重命名、exclude 排除、隐藏文件跳过、目标冲突和部署结果。