Repository: symfony/ux
Pull request #2232 (2024-10-02 17:57:04)

Replace JS toolchain by asset-mapper when testing ux-turbo
| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| Issues        | -
| License       | MIT

:speak_no_evil: 

nicolas-grekas: Curiously, this fails on PHP 8.3 but passes on 8.4 locally (deps=high).
It's going to be fun to debug... If anyone is up to having a look, help welcome :)
Kocal: I will take a look tomorrow!
Kocal: Those issues were caused because the assets were not reachable with the webserver/browser ran by Panther:
<img width="1001" alt="image" src="https://github.com/user-attachments/assets/aad6b9f0-def4-4b3a-b175-507980247a6c">

It was fixed by compiling assets with `asset-map:compile`.

Now all that's left is this issue and we'll be good to go :)
<img width="1482" alt="image" src="https://github.com/user-attachments/assets/0961f498-fd90-42cc-a772-6d33e9da2b9c">

nicolas-grekas: >It was fixed by compiling assets with asset-map:compile.

Super strange. I opened https://github.com/php/php-src/issues/16194 because this looks like a PHP bug to me.

Patch:
diff --git a/src/Turbo/.gitignore b/src/Turbo/.gitignore
index 264070be..9bd0c178 100644
--- a/src/Turbo/.gitignore
+++ b/src/Turbo/.gitignore
@@ -3,10 +3,11 @@
 /.phpunit.result.cache
 /composer.phar
 /composer.lock
+/drivers/
 /phpunit.xml
-/vendor/
-/tests/app/var
+/tests/app/assets/vendor/
+/tests/app/public/assets/
 /tests/app/public/build/
+/tests/app/var/
+/vendor/
 node_modules/
-package-lock.json
-yarn.lock
diff --git a/src/Turbo/composer.json b/src/Turbo/composer.json
index e3cb4651..b98a77b1 100644
--- a/src/Turbo/composer.json
+++ b/src/Turbo/composer.json
@@ -41,21 +41,21 @@
         "doctrine/doctrine-bundle": "^2.4.3",
         "doctrine/orm": "^2.8 | 3.0",
         "phpstan/phpstan": "^1.10",
+        "symfony/asset-mapper": "^6.4|^7.0",
         "symfony/debug-bundle": "^5.4|^6.0|^7.0",
         "symfony/form": "^5.4|^6.0|^7.0",
-        "symfony/framework-bundle": "^5.4|^6.0|^7.0",
+        "symfony/framework-bundle": "^6.4|^7.0",
         "symfony/mercure-bundle": "^0.3.7",
         "symfony/messenger": "^5.4|^6.0|^7.0",
-        "symfony/panther": "^1.0|^2.0",
+        "symfony/panther": "^2.1",
         "symfony/phpunit-bridge": "^5.4|^6.0|^7.0",
         "symfony/process": "^5.4|6.3.*|^7.0",
         "symfony/property-access": "^5.4|^6.0|^7.0",
         "symfony/security-core": "^5.4|^6.0|^7.0",
         "symfony/stopwatch": "^5.4|^6.0|^7.0",
         "symfony/ux-twig-component": "^2.21",
-        "symfony/twig-bundle": "^5.4|^6.0|^7.0",
+        "symfony/twig-bundle": "^6.4|^7.0",
         "symfony/web-profiler-bundle": "^5.4|^6.0|^7.0",
-        "symfony/webpack-encore-bundle": "^2.1.1",
         "symfony/expression-language": "^5.4|^6.0|^7.0",
         "dbrekelmans/bdi": "dev-main"
     },


Test patch:
diff --git a/.github/workflows/test-turbo.yml b/.github/workflows/test-turbo.yml
index 47008d26..d3028192 100644
--- a/.github/workflows/test-turbo.yml
+++ b/.github/workflows/test-turbo.yml
@@ -41,10 +41,12 @@ jobs:
         strategy:
            fail-fast: false
            matrix:
-               php-version: ['8.1', '8.4']
+               php-version: ['8.1', '8.3', '8.4']
                include:
                   - php-version: '8.1'
                     dependency-version: 'lowest'
+                  - php-version: '8.3'
+                    dependency-version: 'highest'
                   - php-version: '8.4'
                     dependency-version: 'highest'
 
@@ -65,8 +67,6 @@ jobs:
             - name: Checkout
               uses: actions/checkout@v4
 
-            - run: corepack enable
-
             - name: Setup PHP
               uses: shivammathur/setup-php@v2
               with:
@@ -75,31 +75,17 @@ jobs:
             - name: Install symfony/flex
               run: composer global config allow-plugins.symfony/flex true && composer global require symfony/flex
 
-            - name: Install Turbo packages
+            - name: Install dependencies with composer
               uses: ramsey/composer-install@v3
               with:
                 working-directory: src/Turbo
                 dependency-versions: ${{ matrix.dependency-version }}
 
-            - name: Get yarn cache directory path
-              id: yarn-cache-dir-path
-              run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
-
-            - uses: actions/cache@v4
-              id: yarn-cache
-              with:
-                  path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
-                  key: ${{ runner.os }}-yarn-${{ hashFiles('**/package.json') }}
-                  restore-keys: |
-                      ${{ runner.os }}-yarn-
-
             - name: Install JavaScript dependencies
               working-directory: src/Turbo/tests/app
-              run: touch yarn.lock && yarn install --mode update-lockfile && yarn install
-
-            - name: Build JavaScript
-              working-directory: src/Turbo/tests/app
-              run: yarn build
+              run: |
+                php public/index.php importmap:install
+                php public/index.php asset-map:compile
 
             - name: Create DB
               working-directory: src/Turbo/tests/app
diff --git a/src/Turbo/tests/BroadcastTest.php b/src/Turbo/tests/BroadcastTest.php
index 3fee2ec3..f95b00cd 100644
--- a/src/Turbo/tests/BroadcastTest.php
+++ b/src/Turbo/tests/BroadcastTest.php
@@ -26,8 +26,8 @@ class BroadcastTest extends PantherTestCase
 
     protected function setUp(): void
     {
-        if (!file_exists(__DIR__.'/app/public/build')) {
-            throw new \Exception(\sprintf('Move into "%s" and execute Encore before running this test.', realpath(__DIR__.'/app')));
+        if (!file_exists(__DIR__.'/app/assets/vendor/installed.php')) {
+            throw new \Exception(\sprintf('Move into "%s" and execute `php public/index.php importmap:install` before running this test.', realpath(__DIR__.'/app')));
         }
 
         parent::setUp();
diff --git a/src/Turbo/tests/app/Kernel.php b/src/Turbo/tests/app/Kernel.php
index 5e259413..675a0f8b 100644
--- a/src/Turbo/tests/app/Kernel.php
+++ b/src/Turbo/tests/app/Kernel.php
@@ -39,7 +39,6 @@ use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
 use Symfony\UX\StimulusBundle\StimulusBundle;
 use Symfony\UX\Turbo\TurboBundle;
 use Symfony\UX\TwigComponent\TwigComponentBundle;
-use Symfony\WebpackEncoreBundle\WebpackEncoreBundle;
 use Twig\Environment;
 
 /**
@@ -57,7 +56,6 @@ class Kernel extends BaseKernel
         yield new MercureBundle();
         yield new TwigComponentBundle();
         yield new TurboBundle();
-        yield new WebpackEncoreBundle();
         yield new StimulusBundle();
         yield new WebProfilerBundle();
         yield new DebugBundle();
@@ -67,10 +65,13 @@ class Kernel extends BaseKernel
     {
         $container->extension('framework', [
             'secret' => 'ChangeMe',
-            'test' => 'test' === ($_SERVER['APP_ENV'] ?? 'dev'),
+            'test' => 'test' === $this->environment,
             'router' => [
                 'utf8' => true,
             ],
+            'asset_mapper' => [
+                'paths' => ['assets/'],
+            ],
             'profiler' => [
                 'only_exceptions' => false,
             ],
@@ -108,7 +109,6 @@ class Kernel extends BaseKernel
         $container
             ->extension('doctrine', $doctrineConfig);
 
-        $container->extension('webpack_encore', ['output_path' => 'build']);
         $container->extension('web_profiler', [
             'toolbar' => true,
             'intercept_redirects' => false,
diff --git a/src/Turbo/tests/app/assets/controllers.json b/src/Turbo/tests/app/assets/controllers.json
new file mode 100644
index 00000000..bde96a53
--- /dev/null
+++ b/src/Turbo/tests/app/assets/controllers.json
@@ -0,0 +1,4 @@
+{
+    "controllers": {},
+    "entrypoints": []
+}
diff --git a/src/Turbo/tests/app/assets/controllers/.gitignore b/src/Turbo/tests/app/assets/controllers/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/src/Turbo/tests/app/importmap.php b/src/Turbo/tests/app/importmap.php
new file mode 100644
index 00000000..d0f04e19
--- /dev/null
+++ b/src/Turbo/tests/app/importmap.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return [
+    'app' => [
+        'path' => './assets/app.js',
+        'entrypoint' => true,
+    ],
+    '@hotwired/stimulus' => [
+        'version' => '3.2.2',
+    ],
+    '@symfony/stimulus-bundle' => [
+        'path' => '../../vendor/symfony/stimulus-bundle/assets/dist/loader.js',
+    ],
+    '@symfony/ux-turbo/dist/turbo_stream_controller' => [
+        'path' => '../../assets/dist/turbo_stream_controller.js',
+    ],
+    '@hotwired/turbo' => [
+        'version' => '7.3.0',
+    ],
+];
diff --git a/src/Turbo/tests/app/package.json b/src/Turbo/tests/app/package.json
deleted file mode 100644
index 43fc6df5..00000000
--- a/src/Turbo/tests/app/package.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-    "packageManager": "yarn@4.5.0",
-    "devDependencies": {
-        "@babel/core": "^7.20.12",
-        "@babel/preset-env": "^7.20.2",
-        "@hotwired/stimulus": "^3.0.0",
-        "@hotwired/turbo": "^7.0.1",
-        "@symfony/ux-turbo": "file:../../assets",
-        "@symfony/webpack-encore": "^4.2.0",
-        "core-js": "^3.0.0",
-        "regenerator-runtime": "^0.13.2",
-        "webpack": "^5.75.0",
-        "webpack-cli": "^5.0.1",
-        "webpack-notifier": "^1.6.0"
-    },
-    "resolutions": {
-        "coa": "2.0.2"
-    },
-    "license": "MIT",
-    "private": true,
-    "scripts": {
-        "dev-server": "encore dev-server",
-        "dev": "encore dev",
-        "watch": "encore dev --watch",
-        "build": "encore production --progress"
-    }
-}
diff --git a/src/Turbo/tests/app/public/index.php b/src/Turbo/tests/app/public/index.php
index 3b0f4f6a..0ca58ec3 100644
--- a/src/Turbo/tests/app/public/index.php
+++ b/src/Turbo/tests/app/public/index.php
@@ -11,10 +11,13 @@
 
 use App\Kernel;
 use Symfony\Bundle\FrameworkBundle\Console\Application;
+use Symfony\Component\ErrorHandler\Debug;
 use Symfony\Component\HttpFoundation\Request;
 
 require __DIR__.'/../../../vendor/autoload.php';
 
+Debug::enable();
+
 $app = new Kernel($_SERVER['APP_ENV'] ?? 'dev', $_SERVER['APP_DEBUG'] ?? true);
 
 if (\PHP_SAPI === 'cli') {
diff --git a/src/Turbo/tests/app/templates/base.html.twig b/src/Turbo/tests/app/templates/base.html.twig
index 0a3c7a37..0d532df5 100644
--- a/src/Turbo/tests/app/templates/base.html.twig
+++ b/src/Turbo/tests/app/templates/base.html.twig
@@ -4,7 +4,9 @@
         <meta charset="UTF-8">
         <title>Symfony UX Turbo</title>
         {% block stylesheets %}{% endblock %}
-        {{ encore_entry_script_tags('app') }}
+        {% block javascripts %}
+            {% block importmap %}{{ importmap('app') }}{% endblock %}
+        {% endblock %}
     </head>
     <body>
         <nav id="navigation">
diff --git a/src/Turbo/tests/app/webpack.config.js b/src/Turbo/tests/app/webpack.config.js
deleted file mode 100644
index aeb1151b..00000000
--- a/src/Turbo/tests/app/webpack.config.js
+++ /dev/null
@@ -1,23 +0,0 @@
-var Encore = require('@symfony/webpack-encore');
-
-if (!Encore.isRuntimeEnvironmentConfigured()) {
-    Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
-}
-
-Encore
-    .setOutputPath('public/build/')
-    .setPublicPath('/build')
-    .addEntry('app', './assets/app.js')
-    .splitEntryChunks()
-    .enableSingleRuntimeChunk()
-    .cleanupOutputBeforeBuild()
-    .enableBuildNotifications()
-    .enableSourceMaps(!Encore.isProduction())
-    .enableVersioning(Encore.isProduction())
-    .configureBabelPresetEnv((config) => {
-        config.useBuiltIns = 'usage';
-        config.corejs = 3;
-    })
-;
-
-module.exports = Encore.getWebpackConfig();