WordPress 中使用 React 项目

use react in wordpress post

在之前的系列文章中,我们曾经介绍过 Frontity 这个 React 框架,其可以通过 Rest Api 访问 WordPress 中的数据,这种方式把 WordPress 作为后台的数据存储库,前端完全由 Frontity 来处理。那么可不可以直接在现有的 WordPress 网站中使用 React 呢,答案是可以的,本篇文章就介绍实现方法。

其实,React 本身就支持在现有的网站项目中部分使用 React,并且可以逐步过渡到完全使用React 的单网页版本。下面就介绍如何在 WordPress 文章中的一个区块中使用 React 程序渲染内容。

一、创建 React 项目

在 WordPress 的插件目录中新建一个目录,比如叫 “react-wordpress”,进入该目录,创建插件主程序文件 react-wordpress.php,并在该目录下创建 react 程序框架(这里使用 vite,也可以使用 React 自己的 create-react-app 脚本)。

$mkdir react-wordpress
$cd react-wordpress
$npm create vite@latest my-react-app

? Select a framework: › – Use arrow-keys. Return to submit.
Vanilla
Vue
❯ React
Preact
Lit
Svelte
Others

选择 React 框架,然后回车,出现下面的提示:

?✔ Select a framework: › React
? Select a variant: › – Use arrow-keys. Return to submit.
❯ JavaScript
TypeScript
JavaScript + SWC
TypeScript + SWC

根据自己的情况选择 JavaScript 或者 TypeScript 编程代码,这里选择 JavaScript。

✔ Select a framework: › React
✔ Select a variant: › JavaScript
Scaffolding project in /home/user/www/wordpress/wp-content/plugins/react-wordpress/my-react-app…
Done. Now run:
cd my-react-app
npm install
npm run dev

按照上面的提示安装 React 程序所需的相关模块。

二、WordPress 插件主程序代码

react-wordpress.php

<?php
/**
 * Plugin Name: Kflyo Recact Components
 * Plugin URI: https://www.kflyo.com
 * Description: This plugin add react components in wordpress post.
 * Version: 0.1
 * Author: kflyo
 * Author URI: https://www.kflyo.com
 * License: GPL
 */

defined( 'ABSPATH' ) or die();
define( 'REACT_APP_PATH', plugin_dir_path( __FILE__ ) . '/my-react-app' );
define( 'REACT_APP_URL', plugin_dir_url( __FILE__ ) . 'my-react-app' );
//处理react代码加载
require_once( REACT_APP_PATH . '/react-enqueue.php' );

这里有两种方式装载编译打包后的 React 程序代码,一种是自己实现装载代码(程序简单),另一种是使用 vite 提供的,下面分别介绍。新建文件 react-enqueue.php。

1、自己实现装载

react-enqueue.php

<?php

defined( 'ABSPATH' ) or die();

add_action( 'wp_enqueue_scripts', 'react_app_enqueue');
function react_app_enqueue() {
    if (file_exists(REACT_APP_PATH . "/dist/assets/" )) {
        $files = scandir(REACT_APP_PATH . "/dist/assets/");
        if (count($files) > 0) {
            $file_array = array();
            foreach ($files as $file) {
                if ($file != '.' && $file != '..' &&  is_file(REACT_APP_PATH . "/dist/assets/" . $file)) {
                    $file_string = strtolower(preg_replace("[._-]", "", $file));
                    $file_array[] = basename($file);
                }
            }
        }

        foreach ($file_array as $key => $file) {
            $ext = preg_replace('/^.*\./', '', $file);
            if("js" === $ext) wp_enqueue_script( 'reactjs-' . $key, REACT_APP_URL . "/dist/assets/" . $file, array(), null, true );
            else if("css" === $ext) wp_enqueue_style( 'reactcss-' . $key, REACT_APP_URL . "/dist/assets/" . $file );
        }
    }
}
2、使用 vite 装载

第一步在插件的主目录安装 idleberg/wordpress-vite-assets 程序包。

$composer require idleberg/wordpress-vite-assets

第二步在 vite 的配置文件中增加 build 配置项 【manifest: true】,参见下面第四部分的内容,这样在 build 后会生成 manifest.json。

第三步使用 vite 装载代码装载 build 后的 React 程序。

react-enqueue.php

require 'vendor/autoload.php';
use Idleberg\WordpressViteAssets\WordpressViteAssets;

$baseUrl = REACT_APP_URL . "/dist/";
$manifest = REACT_APP_PATH . "/dist/manifest.json";
$entryPoint = "index.html";

$viteAssets = new WordPressViteAssets($manifest, $baseUrl);
$viteAssets->inject($entryPoint, ["action" => "wp_enqueue_scripts"]);

三、修改 React 主程序代码

main.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
//把标签id改成“my-root-id”(之前是“root”)
const react_root = document.getElementById('my-root-id');
if (react_root) {
    ReactDOM.createRoot(react_root).render(
      <React.StrictMode>
        <ChakraProvider>
            <App />
        </ChakraProvider>
      </React.StrictMode>,
    );
}
//这里还可以增加其它界面元素的bundle,见下面第六部分说明

除了 createRoot,还可以使用 createPortal 把 React 组件注入到 DOM 节点中,一般情况下,createPortal 用在弹出对话框、提示框等场景。

四、修改 vite 配置文件

vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  //增加react程序部署位置
  base: "/wp-content/plugins/react-wordpress/my-react-app/dist",
    build: {
        //src目录中的文件修改后自动build
        watch: {
            include: 'src/**'
        },
        //build后生成manifest.json
        manifest: true,
    },
  plugins: [react()],
})

如果是使用 create-react-app 创建的程序,则需要在 package.json 中增加配置项:

“homepage”: “/wp-content/plugins/react-wordpress/my-react-app/build”

五、编译打包 React 程序

在 React 程序主目录下(my-react-app),运行下面的命令:

$npm run build

六、创建文章并引入 React 程序

在创建的文章中增加 “自定义HTML” 区块,可义定义多个,也可以是其它的位置,比如 Widget、Sidebar 等,在 main.jsx 中增加相应的代码即可:

<div id="my-root-id"></div>
<div id="another-root-id"></div>

最后,激活插件并浏览文章,就可以看见 React 程序输出的内容了。

按照上面介绍的方法还可以把 React 程序集成到 WidgetMenuShortCode 等这些 WordPress 的程序元素中。

发表评论

邮箱地址不会被公开。 必填项已用*标注