Project

General

Profile

Actions

Bug #101373

closed

ext:form does not load from dynamicJavaScriptModules because ext:core ImportMap does not include the JS files

Added by Stefan P 10 months ago. Updated 10 months ago.

Status:
Resolved
Priority:
Should have
Assignee:
-
Category:
Backend JavaScript
Target version:
-
Start date:
2023-07-18
Due date:
% Done:

100%

Estimated time:
TYPO3 Version:
12
PHP Version:
Tags:
Complexity:
Is Regression:
Sprint Focus:

Description

I have an extension that adds a new form element defintion to EXT:form, running on TYPO3 12. I wanted to use the latest v12 JavaScript register method, as mentioned in the docs:

In the form editor YAML, if I replace the deprecated dynamicRequireJsModules with dynamicJavaScriptModules, add the JavaScriptModules.php file and adjust the format of the js file accordingly, I get this error in the Browser console:
Unable to resolve specifier '@myvendor/my-extension/Backend/FormEditor/ViewModel.js'

So, the YAML is correctly parsed and the correct file should be loaded. Dumping the import map inside the JavaScriptModules.php loader, I can also see that this is registering my JS file with the same structure as every other JS file from core extensions.

But it still can not be resolved and loaded in the Browser. I tried upper and lowercase names (bot in actual file names as well in the config files), different ways of writing the EXT key (like "my_extension" and "my-extension"). I looked how core extensions register JS modules and adapted my code. Nothing works.

Using the deprecated v11 way works without any problems.

Is this a bug in the form extension or is something missing in the documentation?

UPDATE: I found out that my extension is not in the variable $extensionsToLoad in the class ImportMap . How to get it in there? In the original $importMap (loaded from JavaScriptModules.php) it is correctly included, but in the final resolved one that is passed to the FE it is not included, because my extension key is not in $extensionsToLoad.

This seems to be because in ImportMap::resolveImport around line 106 the helper.js of EXT:form is not yet available. At least this is the situation why for my extension the ImportMap::loadDependencies('my-package') is not executed.

Actions #1

Updated by Stefan P 10 months ago

  • Description updated (diff)
Actions #2

Updated by Stefan P 10 months ago

  • Description updated (diff)
Actions #3

Updated by Stefan P 10 months ago

  • Description updated (diff)
Actions #4

Updated by Stefan P 10 months ago

  • Description updated (diff)
Actions #5

Updated by Stefan P 10 months ago

Do I have to specifiy anything anyhwere else besides the JavaScriptModules.php ?

Actions #6

Updated by Stefan P 10 months ago

  • Subject changed from Form extension does not load from dynamicJavaScriptModules to Form extension does not load from dynamicJavaScriptModules because tagged Imports are ignored

I think I found the cause / solution. With #96710 tagged imports where introduced. But it seems this change was not forwarded into ext:form.

In cms-form/Classes/Controller/FormEditorController.php on line 181 add a new tag inclusion (I made this tag name up here, maybe there's a better one, and maybe there's also a better line for this change):
$pageRenderer->getJavaScriptRenderer()->includeTaggedImports('form.extension');

And in the JavaScriptModules.php add 'tags' => ['form.extension']

Then everything works.

Actions #7

Updated by Stefan P 10 months ago

  • Subject changed from Form extension does not load from dynamicJavaScriptModules because tagged Imports are ignored to ext:form does not load from dynamicJavaScriptModules because ext:core ImportMap does not include the JS files
  • Category changed from Form Framework to Backend JavaScript

I'm not sure if my suggested way is the best one.

ext:form already does the following, which correctly adds dynamicJavaScriptModules inside $jsModules to the rendering, which in the end triggers the "Unable to resolve..." error, because the actual JS file gets not included in the rendering:

$this->pageRenderer->getJavaScriptRenderer()->addJavaScriptModuleInstruction(
    JavaScriptModuleInstruction::create('@typo3/form/backend/helper.js', 'Helper')
        ->invoke('dispatchFormManager', $jsModules, $this->getFormManagerAppInitialData())
);

I'd expect that adding an explicit JavaScript instruction also means that the required files are then loaded implicitly, automatically, without the need to tell again via tags.

So it's also possible to argue that this is a bug in ext:core and not in ext:form, because it does not load files it was told to load. Not sure what the original intenion by the authors was on how this JavaScript stuff should be used in the end.
Is there ever a case when I want to have a JavaScriptModuleInstruction without having the relevant JS files passed to the rendering by the ImportMap ?

Actions #8

Updated by Stefan P 10 months ago

The change to ES6-style JS for ext:form (#96568) was BEFORE the tags were introduced (#96710). So I think that the tag code messed something up

Actions #9

Updated by Stefan P 10 months ago

More info: other core extensions do at least one of these when loading JS modules:
  • $pageRenderer->getJavaScriptRenderer()->includeTaggedImports('tag-whatever'); (if a tag is present in JavaScriptModules.php)
  • <f:be.pageRenderer includeJavaScriptModules="{0: '@typo3/package/whatever.js'}"/> (if no tags are present in JavaScriptModules.php )

ext:form does none of them.

Actions #10

Updated by Stefan P 10 months ago

It also seems strange that ext:form registers its own JS files with the tag 'backend.contextmenu' - sounds like a hack to me to workaround similar problems as discribed in this issue (adding this tag to my extension does not work , I tried it).

Actions #11

Updated by Gerrit Code Review 10 months ago

  • Status changed from New to Under Review

Patch set 1 for branch 12.4 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/80174

Actions #12

Updated by Gerrit Code Review 10 months ago

Patch set 1 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/80175

Actions #13

Updated by Benjamin Franzke 10 months ago

Thanks for your report, can confirm.
Fixed with the following patch https://review.typo3.org/c/Packages/TYPO3.CMS/+/80174 – please test.

Regarding some statements:

I think I found the cause / solution. With #96710 tagged imports where introduced. But it seems this change was not forwarded into ext:form.
The change to ES6-style JS for ext:form (#96568) was BEFORE the tags were introduced (#96710). So I think that the tag code messed something up

Yes, right, adding a (or two) tags for these "dynamic" imports would be an option, and I thought about adding one, but:
The dynamic module in EXT:form aren't dynamic at all, as they are all loaded on startup, so I decided/proposed to just preload them.
(Instead of preloading them we could have also just included them in the importmap, but that would require new API and preload is fine IMO)

Tags where actually thought for modules that are loaded late – due to ajax request – but that's not the case with EXT:form javascript modules.

I'd expect that adding an explicit JavaScript instruction also means that the required files are then loaded implicitly, automatically, without the need to tell again via tags.
Is there ever a case when I want to have a JavaScriptModuleInstruction without having the relevant JS files passed to the rendering by the ImportMap ?

I understand your "frustration", but we don't want object creations to have side effects – for that reason a created object doesn't auto-register itself.
It was simply an oversight, that the modules weren't actually loaded by PHP code, but only later by JS.

Not sure what the original intenion by the authors was on how this JavaScript stuff should be used in the end.

Please consider your tone. No one has "bad" intentions, bugs happen.

It also seems strange that ext:form registers its own JS files with the tag 'backend.contextmenu' - sounds like a hack to me to workaround similar problems as discribed in this issue (adding this tag to my extension does not work , I tried it).

This is another case and the tag `backend.contextmenu` was added to EXT:form importmap because it registers a context-menu item provider (for files).
But it turns out that the provider is based on the EXT:filellist provider and therefore doesn't require own javascript (`@typo3/filelist/context-menu-actions` is used). So this tag can actually be removed. I created a separate issue and patch for that:
https://forge.typo3.org/issues/101445
https://review.typo3.org/c/Packages/TYPO3.CMS/+/80176

Actions #14

Updated by Stefan P 10 months ago

Thanks for the explanations and the fix.

Please consider your tone. No one has "bad" intentions, bugs happen.

Where was I using the word "bad"? Please consider not interpreting an insult/rant into a neutral question by an outsider/none-core-dev of how a brand-new API is meant to be used.

Actions #15

Updated by Benjamin Franzke 10 months ago

Ok, sorry.

Actions #16

Updated by Gerrit Code Review 10 months ago

Patch set 2 for branch 12.4 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/80174

Actions #17

Updated by Anonymous 10 months ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100
Actions

Also available in: Atom PDF