fix: use vite-plugin-symfony Stimulus loader and wrap react_component in div
The @symfony/stimulus-bundle loader generates an empty controllers.js, so Stimulus controllers from controllers.json (including ux-react) were never registered. Switching to vite-plugin-symfony/stimulus/helpers uses the virtual:symfony/controllers module that properly reads controllers.json. Also wrap react_component() output in a <div> since it only renders data-attributes, not a full HTML element. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
4
assets/bootstrap.js
vendored
4
assets/bootstrap.js
vendored
@@ -1,4 +1,4 @@
|
||||
import { startStimulusApp } from '@symfony/stimulus-bundle';
|
||||
import { startStimulusApp } from 'vite-plugin-symfony/stimulus/helpers';
|
||||
|
||||
const app = startStimulusApp();
|
||||
|
||||
@@ -15,5 +15,5 @@ window.resolveReactComponent = (name) => {
|
||||
.map(k => k.replace('./react/controllers/', '').replace('.jsx', ''));
|
||||
throw new Error(`React controller "${name}" does not exist. Possible values: ${available.join(', ')}`);
|
||||
}
|
||||
return module.default;
|
||||
return module;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
{
|
||||
"controllers": {
|
||||
"@symfony/ux-react": {
|
||||
"react": {
|
||||
"enabled": true,
|
||||
"fetch": "eager"
|
||||
}
|
||||
},
|
||||
"@symfony/ux-turbo": {
|
||||
"turbo-core": {
|
||||
"enabled": true,
|
||||
@@ -9,12 +15,6 @@
|
||||
"enabled": false,
|
||||
"fetch": "eager"
|
||||
}
|
||||
},
|
||||
"@symfony/ux-react": {
|
||||
"react": {
|
||||
"enabled": true,
|
||||
"fetch": "eager"
|
||||
}
|
||||
}
|
||||
},
|
||||
"entrypoints": []
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
when@dev:
|
||||
pentatrion_vite:
|
||||
proxy_origin: http://node:5173
|
||||
|
||||
pentatrion_vite:
|
||||
default_build: app
|
||||
builds:
|
||||
|
||||
@@ -30,6 +30,14 @@ ENV APP_ENV=dev \
|
||||
POSTGRES_USER=app \
|
||||
POSTGRES_PASSWORD=pwd
|
||||
|
||||
###
|
||||
# Composer install stage (provides vendor assets for node build)
|
||||
###
|
||||
FROM base AS composer-deps
|
||||
|
||||
COPY composer.json composer.lock symfony.lock ./
|
||||
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
|
||||
|
||||
###
|
||||
# Node build stage (for prod assets)
|
||||
###
|
||||
@@ -37,6 +45,9 @@ FROM node:22-alpine AS node-build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy vendor UX assets so npm can resolve file: dependencies
|
||||
COPY --from=composer-deps /app/vendor/symfony/ux-react/assets vendor/symfony/ux-react/assets
|
||||
|
||||
COPY package.json package-lock.json* ./
|
||||
RUN npm install
|
||||
|
||||
|
||||
56
package-lock.json
generated
56
package-lock.json
generated
@@ -15,6 +15,8 @@
|
||||
"react-dom": "^19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@symfony/stimulus-bridge": "^3.2.0 || ^4.0.0",
|
||||
"@symfony/ux-turbo": "file:vendor/symfony/ux-turbo/assets",
|
||||
"@vitejs/plugin-react-swc": "^4.3.0",
|
||||
"vite": "^6.0",
|
||||
"vite-plugin-symfony": "^8.0"
|
||||
@@ -961,7 +963,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@hotwired/stimulus-webpack-helpers/-/stimulus-webpack-helpers-1.0.1.tgz",
|
||||
"integrity": "sha512-wa/zupVG0eWxRYJjC1IiPBdt3Lruv0RqGN+/DTMmUWUyMAEB27KXmVY6a8YpUVTM7QwVuaLNGW4EqDgrS2upXQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@hotwired/stimulus": ">= 3.0"
|
||||
}
|
||||
@@ -1701,7 +1702,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@symfony/stimulus-bridge/-/stimulus-bridge-4.0.1.tgz",
|
||||
"integrity": "sha512-+/kSQ4qFXMbZS+HjkhzOxwdN+60pMev7kzzDpQV/Tdm/iIWoxx5GDsVcdLaBb2783BVQHyrBP72JerF2SXTbTg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@hotwired/stimulus-webpack-helpers": "^1.0.1",
|
||||
"@types/webpack-env": "^1.16.4",
|
||||
@@ -1723,6 +1723,10 @@
|
||||
"resolved": "vendor/symfony/ux-react/assets",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@symfony/ux-turbo": {
|
||||
"resolved": "vendor/symfony/ux-turbo/assets",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@testing-library/dom": {
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
|
||||
@@ -1861,12 +1865,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/hotwired__turbo": {
|
||||
"version": "8.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/hotwired__turbo/-/hotwired__turbo-8.0.9.tgz",
|
||||
"integrity": "sha512-q2XWdObf8J+3V8fESKkd452Iy1A9ZFemQVGzKmxmZ02Clo1D/HEiX8bMQRmJ432RQ4sp24R0f7XQjHWNQC26XA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.2.14",
|
||||
@@ -2069,7 +2079,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
|
||||
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
@@ -2086,7 +2095,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
|
||||
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"ajv": "^8.0.0"
|
||||
},
|
||||
@@ -2104,7 +2112,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
|
||||
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3"
|
||||
},
|
||||
@@ -2477,8 +2484,7 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.3.3",
|
||||
@@ -2511,8 +2517,7 @@
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"peer": true
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.20.1",
|
||||
@@ -2774,8 +2779,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
@@ -2795,7 +2799,6 @@
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz",
|
||||
"integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 12.13.0"
|
||||
}
|
||||
@@ -3127,7 +3130,6 @@
|
||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -3260,7 +3262,6 @@
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
|
||||
"integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"ajv": "^8.9.0",
|
||||
@@ -4683,6 +4684,29 @@
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vendor/symfony/ux-turbo/assets": {
|
||||
"name": "@symfony/ux-turbo",
|
||||
"version": "2.31.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@hotwired/stimulus": "^3.0.0",
|
||||
"@hotwired/turbo": "^7.1.0 || ^8.0",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@types/hotwired__turbo": "^8.0.4",
|
||||
"jsdom": "^26.1.0",
|
||||
"tslib": "^2.8.1",
|
||||
"tsx": "^4.20.3",
|
||||
"typescript": "^5.8.3",
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@hotwired/stimulus": "^3.0.0",
|
||||
"@hotwired/turbo": "^7.1.0 || ^8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"react-dom": "^19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@symfony/stimulus-bridge": "^3.2.0 || ^4.0.0",
|
||||
"@symfony/ux-turbo": "file:vendor/symfony/ux-turbo/assets",
|
||||
"@vitejs/plugin-react-swc": "^4.3.0",
|
||||
"vite": "^6.0",
|
||||
"vite-plugin-symfony": "^8.0"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ react_component('GameGrid', {
|
||||
<div {{ react_component('GameGrid', {
|
||||
grid: grid,
|
||||
width: width,
|
||||
middle: middle,
|
||||
}) }}
|
||||
}) }}></div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -23,6 +23,7 @@ export default defineConfig({
|
||||
strictPort: true,
|
||||
origin: 'http://localhost:5173',
|
||||
cors: true,
|
||||
allowedHosts: ['node'],
|
||||
hmr: {
|
||||
host: 'localhost',
|
||||
port: 5173,
|
||||
|
||||
Reference in New Issue
Block a user