recipes icon indicating copy to clipboard operation
recipes copied to clipboard

Tweak controllers.json path to support Windows

Open W2AlharbiMe opened this issue 3 years ago • 6 comments

Q A
License MIT
Doc issue/PR symfony/symfony-docs#...

Hello, @weaverryan for some reason webpack method enableStimulusBridge cannot find controllers.json in assets folder in windows 10 operating system while passing the absolute path for the filecontrollers.json works

How the issue started?

after installing @symfony/ux-dropzone and running yarn dev webpack encore displayed the following error:

 ERROR  Failed to compile with 1 errors                                                                                      12:59:43 AM
 error  in ./node_modules/@symfony/stimulus-bridge/controllers.json                                                          12:59:43 AM
Module build failed (from ./node_modules/@symfony/stimulus-bridge/dist/webpack/loader.js):
Error: Your controllers.json file was not found. Be sure to add a Webpack alias from "@symfony/stimulus-bridge/controllers.json" to *your* controllers.json file.

keep in mind that i was using the default webpack.config.js and controllers.json exists in assets folder.

Details about my environment:

Node Version: v14.18.1
Webpack Version: 1.7.0

How did i fix it ?

// webpack.config.js
const { join } = require('path');

// get the absolute path for the current working directory using `__dirname` and concatenate it with ./aseets/controllers.json
enableStimulusBridge(join(__dirname, './assets/controllers.json'))

thanks..

W2AlharbiMe avatar Dec 22 '21 21:12 W2AlharbiMe

Thanks for the PR 😍

How to test these changes in your application

  1. Define the SYMFONY_ENDPOINT environment variable:

    # On Unix-like (BSD, Linux and macOS)
    export SYMFONY_ENDPOINT=https://raw.githubusercontent.com/symfony/recipes/flex/pull-1042/index.json
    # On Windows
    SET SYMFONY_ENDPOINT=https://raw.githubusercontent.com/symfony/recipes/flex/pull-1042/index.json
    
  2. Install the package(s) related to this recipe:

    composer req 'symfony/flex:^1.16'
    composer req 'symfony/webpack-encore-bundle:^1.9'
    
  3. Don't forget to unset the SYMFONY_ENDPOINT environment variable when done:

    # On Unix-like (BSD, Linux and macOS)
    unset SYMFONY_ENDPOINT
    # On Windows
    SET SYMFONY_ENDPOINT=
    

Diff between recipe versions

In order to help with the review stage, I'm in charge of computing the diff between the various versions of patched recipes. I'm going keep this comment up to date with any updates of the attached patch.

symfony/webpack-encore-bundle

1.0 vs 1.6
diff --git a/symfony/webpack-encore-bundle/1.6/config/packages/test/webpack_encore.yaml b/symfony/webpack-encore-bundle/1.6/config/packages/test/webpack_encore.yaml
new file mode 100644
index 0000000..02a7651
--- /dev/null
+++ b/symfony/webpack-encore-bundle/1.6/config/packages/test/webpack_encore.yaml
@@ -0,0 +1,2 @@
+#webpack_encore:
+#    strict_mode: false
diff --git a/symfony/webpack-encore-bundle/1.0/config/packages/webpack_encore.yaml b/symfony/webpack-encore-bundle/1.6/config/packages/webpack_encore.yaml
index ce02f6b..a1335c5 100644
--- a/symfony/webpack-encore-bundle/1.0/config/packages/webpack_encore.yaml
+++ b/symfony/webpack-encore-bundle/1.6/config/packages/webpack_encore.yaml
@@ -1,14 +1,25 @@
 webpack_encore:
-    # The path where Encore is building the assets.
-    # This should match Encore.setOutputPath() in webpack.config.js.
+    # The path where Encore is building the assets - i.e. Encore.setOutputPath()
     output_path: '%kernel.project_dir%/public/build'
     # If multiple builds are defined (as shown below), you can disable the default build:
     # output_path: false
 
-    # if using Encore.enableIntegrityHashes() specify the crossorigin attribute value (default: false, or use 'anonymous' or 'use-credentials')
+    # If using Encore.enableIntegrityHashes() and need the crossorigin attribute (default: false, or use 'anonymous' or 'use-credentials')
     # crossorigin: 'anonymous'
 
-    # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes).
-    # To enable caching for the production environment, creating a webpack_encore.yaml in the config/packages/prod directory with this value set to true
-    # Available in version 1.2
-    #cache: false
+    # Preload all rendered script and link tags automatically via the HTTP/2 Link header
+    # preload: true
+
+    # Throw an exception if the entrypoints.json file is missing or an entry is missing from the data
+    # strict_mode: false
+
+    # If you have multiple builds:
+    # builds:
+        # pass "frontend" as the 3rg arg to the Twig functions
+        # {{ encore_entry_script_tags('entry1', null, 'frontend') }}
+
+        # frontend: '%kernel.project_dir%/public/frontend/build'
+
+    # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes)
+    # Put in config/packages/prod/webpack_encore.yaml
+    # cache: true
1.6 vs 1.9
diff --git a/symfony/webpack-encore-bundle/1.6/assets/controllers/hello_controller.js b/symfony/webpack-encore-bundle/1.9/assets/controllers/hello_controller.js
index 8c79f65..e847027 100644
--- a/symfony/webpack-encore-bundle/1.6/assets/controllers/hello_controller.js
+++ b/symfony/webpack-encore-bundle/1.9/assets/controllers/hello_controller.js
@@ -1,4 +1,4 @@
-import { Controller } from 'stimulus';
+import { Controller } from '@hotwired/stimulus';
 
 /*
  * This is an example Stimulus controller!
diff --git a/symfony/webpack-encore-bundle/1.6/config/packages/webpack_encore.yaml b/symfony/webpack-encore-bundle/1.9/config/packages/webpack_encore.yaml
index a1335c5..fa2e39d 100644
--- a/symfony/webpack-encore-bundle/1.6/config/packages/webpack_encore.yaml
+++ b/symfony/webpack-encore-bundle/1.9/config/packages/webpack_encore.yaml
@@ -4,6 +4,16 @@ webpack_encore:
     # If multiple builds are defined (as shown below), you can disable the default build:
     # output_path: false
 
+    # Set attributes that will be rendered on all script and link tags
+    script_attributes:
+        defer: true
+        # Uncomment (also under link_attributes) if using Turbo Drive
+        # https://turbo.hotwired.dev/handbook/drive#reloading-when-assets-change
+        # 'data-turbo-track': reload
+    # link_attributes:
+        # Uncomment if using Turbo Drive
+        # 'data-turbo-track': reload
+
     # If using Encore.enableIntegrityHashes() and need the crossorigin attribute (default: false, or use 'anonymous' or 'use-credentials')
     # crossorigin: 'anonymous'
 
diff --git a/symfony/webpack-encore-bundle/1.6/package.json b/symfony/webpack-encore-bundle/1.9/package.json
index ba0e4f4..813010a 100644
--- a/symfony/webpack-encore-bundle/1.6/package.json
+++ b/symfony/webpack-encore-bundle/1.9/package.json
@@ -1,10 +1,10 @@
 {
     "devDependencies": {
-        "@symfony/stimulus-bridge": "^2.0.0",
-        "@symfony/webpack-encore": "^1.0.0",
+        "@hotwired/stimulus": "^3.0.0",
+        "@symfony/stimulus-bridge": "^3.0.0",
+        "@symfony/webpack-encore": "^1.7.0",
         "core-js": "^3.0.0",
         "regenerator-runtime": "^0.13.2",
-        "stimulus": "^2.0.0",
         "webpack-notifier": "^1.6.0"
     },
     "license": "UNLICENSED",
diff --git a/symfony/webpack-encore-bundle/1.9/post-install.txt b/symfony/webpack-encore-bundle/1.9/post-install.txt
new file mode 100644
index 0000000..735ed3e
--- /dev/null
+++ b/symfony/webpack-encore-bundle/1.9/post-install.txt
@@ -0,0 +1,5 @@
+  * Install Yarn and run yarn install
+
+  * Uncomment the Twig helpers in templates/base.html.twig
+
+  * Start the development server: yarn encore dev-server
diff --git a/symfony/webpack-encore-bundle/1.6/webpack.config.js b/symfony/webpack-encore-bundle/1.9/webpack.config.js
index 056b04a..aee3a15 100644
--- a/symfony/webpack-encore-bundle/1.6/webpack.config.js
+++ b/symfony/webpack-encore-bundle/1.9/webpack.config.js
@@ -1,4 +1,5 @@
 const Encore = require('@symfony/webpack-encore');
+const { join } = require('path');
 
 // 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.
@@ -23,7 +24,7 @@ Encore
     .addEntry('app', './assets/app.js')
 
     // enables the Symfony UX Stimulus bridge (used in assets/bootstrap.js)
-    .enableStimulusBridge('./assets/controllers.json')
+    .enableStimulusBridge(join(__dirname, './assets/controllers.json'))
 
     // When enabled, Webpack "splits" your files into smaller pieces for greater optimization.
     .splitEntryChunks()

github-actions[bot] avatar Dec 22 '21 21:12 github-actions[bot]

Thanks for this! This seems reasonable, and it doesn't break anything on non-Windows machines.

But still, it troubles me... just that I can't figure out why this is happening! In Encore, we even check this path: https://github.com/symfony/webpack-encore/blob/main/lib/WebpackConfig.js#L680 to make sure it exists.

And also, the exact error you got comes from here: https://github.com/symfony/stimulus-bridge/blob/937233afb2dcd52bfcaff57ea27bebad1c2934e5/src/webpack/create-controllers-module.ts#L20-L24

This looks a little weird. But what we do is basically this: there IS aa real @symfony/stimulus-bridge/controllers.json file, it is here: https://github.com/symfony/stimulus-bridge/blob/937233afb2dcd52bfcaff57ea27bebad1c2934e5/controllers.json

This file is never meant to be loaded. In fact, we add that little placeholder so that we can show you that error if it IS loaded. Why should it never be loaded? Because Encore registers a Webpack alias that overrides this path: https://github.com/symfony/webpack-encore/blob/main/lib/WebpackConfig.js#L693-L695

What this means is that, unless I'm missing something, you should only EVER see the error you're seeing if you didn't register ANY webpack alias for @symfony/stimulus-bridge/controllers.json. If you pass an incorrect path to enableStimulusBridge(), then you should get this error: https://github.com/symfony/webpack-encore/blob/main/lib/WebpackConfig.js#L681

There is enough unexplainable stuff here that I'm worried that something else is going on. It could be a bug that we would want to properly fix. To help some debugging, @W2AlharbiMe could you:

A) Right before this line, https://github.com/symfony/webpack-encore/blob/main/lib/WebpackConfig.js#L694, console.log(path.resolve(controllerJsonPath))?

B) At the bottom of your webpack.config.js file, try this:

-module.exports = Encore.getWebpackConfig();
+const finalConfig = Encore.getWebpackConfig();
+console.log(finalConfig.resolve.alias);
+module.exports = finalConfig;

In this second one, I want to verify that the @symfony/stimulus-bridge/controllers.json alias IS present.

Cheers!

weaverryan avatar Dec 23 '21 01:12 weaverryan

Hello, @weaverryan sorry for taking time to reply

A) Right before this line, https://github.com/symfony/webpack-encore/blob/main/lib/WebpackConfig.js#L694, console.log(path.resolve(controllerJsonPath))

Output:

C:\Users\AlharbiAbdullah\Desktop\projects\PHP\books-app-sf\assets\controllers.json

B) At the bottom of your webpack.config.js file, try this:

-module.exports = Encore.getWebpackConfig();
+const finalConfig = Encore.getWebpackConfig();
+console.log(finalConfig.resolve.alias);
+module.exports = finalConfig;

Output:

{
  '@symfony/stimulus-bridge/controllers.json': 'C:\\Users\\AlharbiAbdullah\\Desktop\\projects\\PHP\\books-app-sf\\assets\\controllers.json'
}

could the issue be from @symfony/ux-dropzone since the issue started after i installed it ?

W2AlharbiMe avatar Dec 24 '21 06:12 W2AlharbiMe

Friendly ping @weaverryan, could you have a second look?

nicolas-grekas avatar Feb 17 '22 15:02 nicolas-grekas

could the issue be from @symfony/ux-dropzone since the issue started after i installed it ?

Hmm. Yea, I suppose it's possible. The paths you logged both look good to me. Are you able to consistently repeat this issue? If so, exactly when does the error first appear (is it after installing @symfony/ux-dropzone)? And does stopping Encore and restarting it make the error go away?

Cheers!

weaverryan avatar Mar 01 '22 20:03 weaverryan

Hello, @weaverryan sorry for taking time to reply but i have been looking more into this,

Are you able to consistently repeat this issue?

yes, and it's only when @symfony/ux-dropzon is installed

exactly when does the error first appear (is it after installing @symfony/ux-dropzone)?

it's after installing @symfony/ux-dropzone

And does stopping Encore and restarting it make the error go away?

no


here are some of the stuff that i tried:

  1. i'm using git bash on windows, could it be from git bash ? no i tried CMD but i still get that error if i did not specify the path for the controller.json

  2. could it be because i have a version of encore installed globally and it can't read controller.json path correctly ? no, i removed the global version and still the error exists

  3. what happens when removing @symfony/ux-dropzone ? removing the dependency solve the problem

  4. try other packages in symfony/ux to see if the same error will occur so i decided to try the following packages:

  • @symfony/ux-cropperjs
  • @symfony/ux-lazy-image
  • @symfony/ux-swup

they are working correctly and i'm able to run yarn dev without getting the error

  1. reinstalling @symfony/ux-dropzone breaks again 😭

i took a look at @symfony/ux-dropzone code here: https://github.com/symfony/ux-dropzone

but i did not find something that can potentially lead to the error

thank you so much for waiting my reply, and also thank you so much for taking the time to look into this issue and also to maintain/improve encore again sorry for taking so much time to reply, i usually try to reply quickly.

W2AlharbiMe avatar Mar 08 '22 04:03 W2AlharbiMe

What do we want to do here @weaverryan?

fabpot avatar Jan 24 '23 12:01 fabpot

Sorry for dropping this!

There is still something mysterious about this. Specifically: the problem occurs when installing symfony/ux-dropzone, but it does not occur when installing other UX packages. This tells me that there is not a problem with Encore loading the controllers.json file. And so, the proposed fix should NOT have any effect. However, @W2AlharbiMe says that the proposed fix DOES fix the situation. But I just can't see how :/.

The only thing that's "semi" unique about the Dropzone package is that it has an autoimport for a CSS file: https://github.com/symfony/ux/blob/2.x/src/Dropzone/assets/package.json#L15 - but again, either Encore is able to load the path to the controllers.json file or it's not... I can't see how the internals of that file would affect things.

I'm going to close for now. I do think that there MAY be an issue. But, afaik, no other Windows users have reported this issue.

weaverryan avatar Jan 24 '23 15:01 weaverryan