Search by

youvision / think-static

indiboy-create

ThinkPHP 8 项目部署插件:主项目通过 Composer 安装或更新依赖时,自动把 project 目录部署到 public/store。

Package info

github.com/indiboy-create/think-static

Type:composer-plugin

pkg:composer/youvision/think-static

Statistics

Installs: 3

Dependents: 2

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-11-10 08:28 UTC

This package is auto-updated.

Last update: 2026-11-11 03:19:12 UTC


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 不是有效 JSON
  • path 未配置或为空
  • map 中的条目不存在
  • path 或 map 的目标路径无效
  • 多个条目使用相同或嵌套的目标路径

Composer 插件会自动捕获异常并输出警告,不会中断依赖安装。

验证

php tests/verify.php

测试脚本使用临时目录模拟主项目,覆盖显式 map、默认 map、path 必填、多级 path、目标路径重命名、exclude 排除、隐藏文件跳过、目标冲突和部署结果。