刚拆完第三个插件才发现:我的目录结构一直在"假装专业"
上周帮朋友 review 一个练手插件,打开 zip 差点没笑出声——全部代码塞在一个 800 行的主文件里,assets 和语言包跟 PHP 混成一锅粥。但笑完就沉默了,因为两年前的我也是这样,还觉得自己"结构挺清晰"。
现在我的目录长这样,不一定最优,但确实救过我的命:
my-plugin/ ├── my-plugin.php // 唯一入口,只做"接线员" ├── bootstrap.php // 实际初始化,解耦出来方便单元测试 ├── src/ │ ├── Admin/ // 后台相关:菜单、设置页、Metabox │ ├── Frontend/ // 前台:短码、小工具、public 钩子 │ ├── Core/ // 跨层工具:自动加载、容器、常量 │ └── Database/ // 迁移、查询封装、版本控制 ├── assets/ │ ├── css/src/ // SCSS 源文件,不是直接 enqueue 的 │ ├── js/src/ // Webpack 入口,分 admin/frontend │ └── images/ ├── languages/ // .pot 由 wp-cli 生成,别手写 ├── tests/ // 不是 test/,WordPress 核心用了复数 └── vendor/ // Composer,但 production 要 --no-dev
重点说入口文件。很多人把 `register_activation_hook` 直接写在主文件头部,激活时爽了,但后面想测激活逻辑就得整包加载。我现在把钩子注册也甩给 `bootstrap.php`,主文件只剩 20 行:
<?php
/**
* Plugin Name: My Plugin
* ...
*/
if ( ! defined( 'ABSPATH' ) ) exit;
define( 'MY_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'MY_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
require_once MY_PLUGIN_DIR . 'vendor/autoload.php';
require_once MY_PLUGIN_DIR . 'bootstrap.php';
本地环境我用的是 wp-env(就那个 @wordpress/env),不是 VVV 也不是 Local。理由很现实:同事用 Mac 我用 Linux,以前共享数据库 dump 总出字符集问题。wp-env 的 `.wp-env.json` 里指定插件路径,一键起两个容器(WordPress + MySQL),数据库随毁随建:
{
"plugins": [ "." ],
"port": 8888,
"testsPort": 8889,
"config": {
"WP_DEBUG": true,
"SCRIPT_DEBUG": true,
"WP_DEBUG_LOG": true
}
}
但有个坑:默认的 `wp-env start` 不会自动装你的 Composer 依赖,因为容器里没进你插件目录跑 `composer install`。我加了个 `package.json` 脚本兜底:
{
"scripts": {
"wp-env": "wp-env",
"setup": "composer install && wp-env start && wp-env run cli wp plugin activate my-plugin"
}
}
调试方面,`WP_DEBUG_LOG` 写进 `/wp-content/debug.log`,但容器里看文件麻烦。我直接挂了个 volume 出来,或者更懒的办法:装 Query Monitor,再在 `wp-config.php`(通过 wp-env 的 `config` 注入)里开 `QM_ENABLE_CAPS_PANEL`,权限问题一眼看穿。
最近刚踩的新坑:用 `wp-env` 时如果插件里有 Webpack 构建的前端资源,`SCRIPT_DEBUG` 设为 true 会让 WordPress 优先找 `.js` 而非 `.min.js`,但我的 `assets/js/` 里只有构建后的文件,源文件在 `assets/js/src/`。结果 enqueue 时路径对不上,白屏半天。现在构建脚本会同时吐 `app.js` 和 `app.min.js`,或者干脆在开发环境让 Webpack 监听 + `wp-env` 的 `port` 映射同步过去。
你们本地调试用啥?有没有被 `wp-env` 的容器时区坑过(cron 事件对不上系统时间)?或者目录结构有别的组织方式,比如按"功能模块"而非"技术层级"分?想听听实际项目里怎么权衡的。

