Symfony ux-react:使用react_component()时,React组件不会呈现

1sbrub3j  于 2023-10-24  发布在  React
关注(0)|答案(1)|浏览(149)

我已经初始化了一个新的Symfony项目,版本为6.3.3,并且想尝试使用React的symfony-ux。所以我遵循了这个指南:https://symfony.com/bundles/ux-react/current/index.html但是我无法在页面上渲染react组件。
我已经安装了所有的软件包,并有一个结构看起来像这样:enter image description here
然后我的controllers.json看起来像这样:

{
    "controllers": {
        "@symfony/ux-react": {
            "react": {
                "enabled": true,
                "fetch": "eager"
            }
        }
    },
    "entrypoints": []
}

我的bootstrap.js看起来像这样:

import { startStimulusApp } from '@symfony/stimulus-bridge';
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
export const app = startStimulusApp(require.context(
    '@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
    true,
    /\.[jt]sx?$/
));
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

app.js看起来像这样:

import { registerReactControllerComponents } from '@symfony/ux-react';
import './bootstrap.js';
/*
 * Welcome to your app's main JavaScript file!
 *
 * We recommend including the built version of this JavaScript file
 * (and its CSS file) in your base layout (base.html.twig).
 */

// any CSS you import will output into a single css file (app.css in this case)
import './styles/app.css';

registerReactControllerComponents(require.context('./react/controllers', true, /\.(j|t)sx?$/));

你好,jsx看起来像这样:

import React from 'react';

export default function (props) {

   return <div>TESTING</div>;
}

在我的home.html.twig中,我有以下内容:

{% extends 'base.html.twig' %}

{% block body %}
    <div>
        Component should render below
        <div {{ react_component('Hello') }}>
          
        </div>
    </div>
{% endblock %}

我在日志中没有得到任何错误,所以安装的模块似乎一切正常。但是Hello.jsx react组件没有显示。只有我在模板中编写的其他东西。
然而,当检查时,我可以看到刺激已经将此内容放入div开始标记中:

data-controller=“symfony--ux-react--react”data-symfony--ux-react--react-component-value=“Hello”

但是里面的测试文本不会呈现在页面上。如果有人能帮我看看这个,我会很高兴:)
我的package.json看起来像这样:

{
    "devDependencies": {
        "@babel/core": "^7.17.0",
        "@babel/preset-env": "^7.16.0",
        "@babel/preset-react": "^7.22.5",
        "@hotwired/stimulus": "^3.0.0",
        "@symfony/stimulus-bridge": "^3.2.0",
        "@symfony/ux-react": "file:vendor/symfony/ux-react/assets",
        "@symfony/webpack-encore": "^4.0.0",
        "core-js": "^3.23.0",
        "react": "^18.2.0",
        "react-dom": "^18.0",
        "regenerator-runtime": "^0.13.9",
        "webpack": "^5.74.0",
        "webpack-cli": "^4.10.0",
        "webpack-notifier": "^1.15.0"
    },
    "license": "UNLICENSED",
    "private": true,
    "scripts": {
        "dev-server": "encore dev-server",
        "dev": "encore dev",
        "watch": "encore dev --watch",
        "build": "encore production --progress"
    }
}

EDIT以下是webpack.config的外观:

const Encore = require('@symfony/webpack-encore');

// Manually configure the runtime environment if not already configured yet by the "encore" command.
// It's useful when you use tools that rely on webpack.config.js file.
if (!Encore.isRuntimeEnvironmentConfigured()) {
    Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}

Encore
    // directory where compiled assets will be stored
    .setOutputPath('public/build/')
    // public path used by the web server to access the output path
    .setPublicPath('/build')
    // only needed for CDN's or subdirectory deploy
    //.setManifestKeyPrefix('build/')

    /*
     * ENTRY CONFIG
     *
     * Each entry will result in one JavaScript file (e.g. app.js)
     * and one CSS file (e.g. app.css) if your JavaScript imports CSS.
     */
    .addEntry('app', './assets/app.js')

    // When enabled, Webpack "splits" your files into smaller pieces for greater optimization.
    .splitEntryChunks()

    // enables the Symfony UX Stimulus bridge (used in assets/bootstrap.js)
    .enableStimulusBridge('./assets/controllers.json')

    // will require an extra script tag for runtime.js
    // but, you probably want this, unless you're building a single-page app
    .enableSingleRuntimeChunk()

    /*
     * FEATURE CONFIG
     *
     * Enable & configure other features below. For a full
     * list of features, see:
     * https://symfony.com/doc/current/frontend.html#adding-more-features
     */
    .cleanupOutputBeforeBuild()
    .enableBuildNotifications()
    .enableSourceMaps(!Encore.isProduction())
    // enables hashed filenames (e.g. app.abc123.css)
    .enableVersioning(Encore.isProduction())

    // configure Babel
    // .configureBabel((config) => {
    //     config.plugins.push('@babel/a-babel-plugin');
    // })

    // enables and configure @babel/preset-env polyfills
    .configureBabelPresetEnv((config) => {
        config.useBuiltIns = 'usage';
        config.corejs = '3.23';
    })

    // enables Sass/SCSS support
    //.enableSassLoader()

    // uncomment if you use TypeScript
    //.enableTypeScriptLoader()

    // uncomment if you use React
    .enableReactPreset()

    // uncomment to get integrity="..." attributes on your script & link tags
    // requires WebpackEncoreBundle 1.4 or higher
    //.enableIntegrityHashes(Encore.isProduction())

    // uncomment if you're having problems with a jQuery plugin
    //.autoProvidejQuery()
;

module.exports = Encore.getWebpackConfig();

和base.html.twig:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
        {% block stylesheets %}
        {% endblock %}

        {% block javascripts %}
        {% endblock %}
    </head>
    <body>
        {% block body %}{% endblock %}
    </body>
</html>
c9qzyr3d

c9qzyr3d1#

你是否使用assets mapper编译了你的.jsx?我在你的结构中看不到编译后的.js文件。
在链接https://symfony.com/bundles/ux-react/current/index.html#using-with-assetmapper中,它说:

Because the JSX format isn't pure JavaScript, using this library with AssetMapper requires some extra steps.

Compile your .jsx files to pure JavaScript files. This can be done by installing Babel and the @babel/preset-react preset.

此外,我可以看到你在依赖项中使用了webpack-encore。我们可以看到你的webpack.js.js和你的base.html.twig吗?在加载脚本的后面应该有这一行:

{{ encore_entry_script_tags('app') }}

先谢了。
(我应该把这个放在评论里,我现在没有50 rep:/)

**编辑:**根据webpack encore文档,您的base.html.twig必须包含

{% block javascripts %}
    {{ encore_entry_script_tags('app') }}
{% endblock %}

加载JavaScript文件。然后你需要像这样将新的.js文件注册到webpack.js.js中:
https://symfony.com/doc/current/frontend/encore/simple-example.html#multiple-entries
然后导入你需要的.js文件到你需要的tig中(这里你的react文件通过使用ineritance导入到你需要的tig中)。这样,你的app.js文件就应该被执行了。
要编译.js文件,您必须使用以下命令:

npm run watch

要加载CSS,请在base.html.twig中执行以下代码:

{% block stylesheets %}
    {{ encore_entry_link_tags('app') }}
{% endblock %}

相关问题