react 等前端依赖必须装在 package.json 中,通过 npm install 安装;composer.json 仅管理 php 后端依赖,与前端 js 无关。

React 依赖该装在 package.json 还是 composer.json?
只装在 composer.json 里没用——Gutenberg 前端代码运行在浏览器,React、@wordpress/element 这些必须走 npm 构建流程。Composer 管的是 PHP 后端(比如区块注册、REST API 扩展),和前端 JS 依赖完全不交集。
正确做法:前端依赖全进 package.json,用 npm install 装;PHP 相关逻辑(如 register_block_type)用 Composer 管理插件依赖或自动加载即可。
-
package.json必须存在且含"react"、"react-dom"、"@wordpress/scripts" - 不要在
composer.json的require里写"react/react"类伪包——不存在,装不上,还会触发 Composer 报错Could not find a matching version - 若用 WP CLI 生成区块脚手架(
wp scaffold block),它会自动初始化package.json,别手动删掉
为什么 wp.element 在开发时不能直接用 CDN 版本?
因为 Gutenberg 编辑器已内建全局 window.wp.element,但这是生产环境打包后的版本,没有 dev 模式警告、不支持 HMR、缺少源码映射。你本地写的 JSX 如果依赖未转译的 createElement 或 useState,直接引用 CDN 会导致开发时无法热更新、报错定位困难、甚至组件不渲染。
正确做法:用 @wordpress/element 作为 peer dependency,让 webpack 别打包它,而是从 WordPress 加载的全局 wp.element 中取。
立即学习“前端免费学习笔记(深入)”;
- 确保
package.json中"@wordpress/element"在peerDependencies和devDependencies都有(不是dependencies) - webpack 配置里加
externals: { '@wordpress/element': 'wp.element' },否则会重复打包 React 导致冲突 - 如果漏掉 externals,控制台会出现
Invalid hook call—— 典型的 React 多实例问题
register_block_type 的 editor_script 怎么指向正确的构建产物?
这个参数不是写路径,而是写 wp_register_script 注册时用的 handle 名。WordPress 不会自动读取 build/index.js,你得先用 wp_register_script 显式注册,再把 handle 传给 register_block_type。
常见错误是直接写 'file:./build/index.js' 或相对路径——PHP 层不认识这种写法,结果区块 JS 根本不加载。
- 在插件主文件或
block.php里调用wp_register_script( 'my-block-editor', plugin_dir_url( __FILE__ ) . 'build/index.js', Array( 'wp-element', 'wp-blocks', 'wp-i18n' ), filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' ), true ); -
register_block_type的editor_script值必须严格等于上面注册的 handle:'my-block-editor' - 注意依赖数组要对齐:比如用了
useSelect就得加'wp-data',漏了就会报wp.data is not defined
PHP 和 JS 之间如何安全传参(比如 REST API nonce 或当前用户 ID)?
别在 PHP 里拼接 JS 字符串输出变量,容易 xss;也别硬编码到 build/index.js 里——构建后就固化了,动态值失效。
标准解法是用 wp_add_inline_script 注入全局对象,JS 层统一从 window.myBlockData 读取。
- PHP 侧:在注册 script 后立刻调用
wp_add_inline_script( 'my-block-editor', 'window.myBlockData = ' . wp_json_encode( array( 'nonce' => wp_create_nonce( 'wp_rest' ), 'user_id' => get_current_user_id() ) ) . ';', 'before' ); - JS 侧:直接访问
window.myBlockData.nonce,无需额外 fetch 或 props 传递 - 如果忘了加
'before',JS 可能执行时window.myBlockData还未定义,导致Cannot read Property 'nonce' of undefined
最易被忽略的是:Webpack 构建产物的文件名哈希(如 index.abc123.js)和 PHP 里 filemtime() 的配合。一旦开了哈希但没同步更新 wp_register_script 的 URL,浏览器就会 404,而控制台只显示 “Failed to load Resource”,根本看不出是路径错了。