Overview

Code component dependencies need to be added in an import map, and their CSS need to be attached. See the parent issue, #3518182: [Plan] First-party code component imports, and the issue to be solved before this one, #3518185: Store imported JS components in `JavaScriptComponent` (and reflect in config dependencies).

Proposed resolution

Import maps

\Drupal\experience_builder\Plugin\ExperienceBuilder\ComponentSource\JsComponent already builds an import map for the common JS dependencies. Extend it by using the dependencies of the corresponding JavaScriptComponent entity.

Example import map:

<script type="importmap">  
  {  
    "imports": {  
      "@/components/button": "/sites/default/files/astro-island/8RXxcDE5c1RVLOC4Mvm-ZWvUTumW_bALDVy19e8J4EA.js",  
      "@/components/card": "/sites/default/files/astro-island/S_ROf_ktZmcl4uOJv12hB_yztlx_ZztgalZAedDRCqc.js",  
    }  
  }  
</script>
  • button and card in the above example are JavaScriptComponent config entity machine names. Prepend them with @/components/.
  • The paths are referencing JS files that are created for JavaScriptComponent config entities, containing the JS source code. Make sure these paths are pointing at the endpoint that serves the auto-saved version if that exists.

Attaching CSS

Attach CSS from the loaded dependencies using the generated libraries (named 'experience_builder/astro_island.' . $component→id() by experience_builder_library_info_build()).

User interface changes

None.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

balintbrews created an issue. See original summary.

balintbrews’s picture

wim leers’s picture

wim leers’s picture

Republishing after d.o unpublished 🙄

tedbow’s picture

Title: [PP-1] Build import maps for code component dependencies, attach their CSS » Build import maps for code component dependencies, attach their CSS
Assigned: Unassigned » tedbow
Status: Postponed » Active

tedbow’s picture

Status: Active » Needs work

Started but probably still rough. Need to self review more

tedbow’s picture

I think I need to update this issue based on #3508922: Regression after #3500386: import map scope mismatch when previewed code component's JS is a 307 due to it not having an auto-save/draft because I think introduced the same problem for dependencies. Shouldn't be too hard

tedbow’s picture

Assigned: tedbow » wim leers
Status: Needs work » Needs review

re #9 it is not only use the draft version of the libraries and JS files if there is an auto-save for the dependency. Hope @wim leers can confirm that since he worked on #3508922: Regression after #3500386: import map scope mismatch when previewed code component's JS is a 307 due to it not having an auto-save/draft

wim leers’s picture

Assigned: wim leers » tedbow
Status: Needs review » Needs work
tedbow’s picture

Status: Needs work » Needs review
tedbow’s picture

Status: Needs review » Needs work

test failing

tedbow’s picture

Assigned: tedbow » Unassigned
Status: Needs work » Needs review

🤞🏻 tests will pass. passed

wim leers’s picture

Assigned: Unassigned » tedbow
Status: Needs review » Needs work

#3518838: ComponentSource robustness: add `ComponentSourceTestBase::testSettings()` just landed, and now requires this to be rerolled, sorry 😬

tedbow’s picture

Assigned: tedbow » Unassigned
Status: Needs work » Needs review

Ok. ready for review again. There still isn't test coverage for the 3 new public methods added to JavaScriptComponent. They are test indirectly. so we could add the tests in a follow-up

wim leers’s picture

Component: Page builder » Component sources
Status: Needs review » Reviewed & tested by the community

In the words of @larowlan:

Looking great, that refactor was the bomb @tedbow 💥

Glad I asked for one more iteration round, this is now solid, and easy to evolve in the future 👏

Changing to Component sources, because 99% of the work here is in the JsComponent class and its test coverage.

  • wim leers committed 0afca7cf on 0.x authored by tedbow
    Issue #3518191 by tedbow, wim leers, balintbrews, larowlan: Build import...
wim leers’s picture

Status: Reviewed & tested by the community » Fixed
balintbrews’s picture

Status: Fixed » Needs work

We are missing one smaller piece here. Here is how an import map currently looks like:

{
  "scopes": {
    "/sites/default/files/astro-island/z2TNPL8SBbhdCntH5L8-nUxBDIJKHG-QMqYOC8xazRY.js": {
      "preact": "...",
      "preact/hooks": "...",
      "react/jsx-runtime": "...",
      "react": "...",
      "react-dom": "...",
      "react-dom/client": "...",
      "clsx": "...",
      "class-variance-authority": "...",
      "tailwind-merge": "...",
      "@/lib/utils": "...",
      "@/components/card": "/sites/default/files/astro-island/e7KF9ds1KTO6BgcK5ocVIBs0AwihvLBL6dq9fxvnwxI.js"
    }
  }
}

@/components/card is brought in as a dependency of another component. So far so good! 👍🏻

Now, because everything in the import map is scoped under the individual components, when the code from @/components/card is imported, the browser won't know how to map react, react/jsx-runtime etc. imported from that component. To solve that, we need to move all those to the global scope:

{
  "imports": {
    "preact": "...",
    "preact/hooks": "...",
    "react/jsx-runtime": "...",
    "react": "...",
    "react-dom": "...",
    "react-dom/client": "...",
    "clsx": "...",
    "class-variance-authority": "...",
    "tailwind-merge": "...",
    "@/lib/utils": "...",
  },
  "scopes": {
    "/sites/default/files/astro-island/z2TNPL8SBbhdCntH5L8-nUxBDIJKHG-QMqYOC8xazRY.js": {
      "@/components/card": "/sites/default/files/astro-island/e7KF9ds1KTO6BgcK5ocVIBs0AwihvLBL6dq9fxvnwxI.js"
    }
  }
}
wim leers’s picture

Assigned: Unassigned » tedbow

Thanks for that detailed analysis! 🤩🙏

tedbow’s picture

Issue summary: View changes
StatusFileSize
new92.5 KB

@balintbrews I have pushed a new MR that tries to nest the imports like you mentioned

I am not getting this error

Warning: Array to string conversion in
Drupal\Core Render Htm|ResponseAttachmentsProcessor->process-Htm|HeadLink() (line 416 of core/lib/Drupal/Core/Render/Htm/Respon-seAttachmentsProcessor.php).

$attached['html_head'][] = [$element, 'html_head_link:' . $rel . ':' . $href];

because $href is my list of imports not sure why this happening yet

larowlan’s picture

Status: Needs work » Needs review

Addressed feedback and worked with @balintbrews to confirm it was working

  • balintbrews committed e7056c6c on 0.x authored by tedbow
    Issue #3518191 by tedbow, wim leers, larowlan, balintbrews, penyaskito:...
balintbrews’s picture

Assigned: tedbow » Unassigned
Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

effulgentsia’s picture

Issue tags: -sprint