JavaScriptComponent config entities should have mutable machineNames

Created on 30 January 2025, 3 months ago

Overview

During the implementation of โœจ HTTP API for code component config entities Active , something tangentially related was discussed between @balintbrews, @effulgentsia and @larowlan. That led to this comment by Bรกlint:

I would like to propose that we don't use the machineName property as the id entity key in the JavaScriptComponent entity. We would like to allow users to update the machine name of a code component, which is not possible if that property is the id.

We could use the UUID as the id instead, which would be ideal for the HTTP API.

I already had a conversation about this with @larowlan and @effulgentsia, and got ๐Ÿ‘๐Ÿ‘. If this significantly delays landing this issue, a follow-up is fine, I already have the code written in โœจ Managing code components in library Active with machineName as the id.

#3499931-23: HTTP API for code component config entities โ†’ .

However, this caused some additional consequences, in particular wrt XB product requirement 14. Configuration management. @wimleers surfaced concerns about that in #3499931-25: HTTP API for code component config entities โ†’ . In โœจ HTTP API for code component config entities Active @wimleers decided to

Proposed resolution

  1. Bring back what @larowlan did in https://git.drupalcode.org/project/experience_builder/-/merge_requests/5... through https://git.drupalcode.org/project/experience_builder/-/merge_requests/5....
  2. but first discuss the consequences for config management that @wimleers surfaced
  3. and first discuss the consequences for allowing "code component" machine names to be changed at any time

User interface changes

None.

๐Ÿ“Œ Task
Status

Active

Version

0.0

Component

Config management

Created by

๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @wim leers
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    This is not actionable until decisions are made with solid answers WRT the concerns I surfaced.

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    #3499931-25: HTTP API for code component config entities โ†’ The trade-off as I understand it seems to be about the flexibility we provide within Experience Builder and ease of auditing the code components. It seems that we should prioritize the experience within Experience Builder. While code components must support deployment via config system, that's not the primary use case (especially in cases where you'd have full blown review step). It seems that most users who are going to audit the components, would use the CLI tool to integrate their components so that they can fully control the design system in Git. If this is proven wrong, we could still solve this with tooling in the CLI tool, e.g. a command that prints the component dependency tree in a human readable format.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    You responded to comment 25, but not to 26, in which I articulated a concrete proposal that would make it less disruptive.

    Quoting relevant part of comment 26:

    So, not throwing away what @larowlan did, just extracting that into a follow-up MR. I think all of those changes could happen as planned, with a few changes: disallow changing the machine name once a corresponding Component exists (which requires modifying the new constraint @larowlan added), and continue to use the machine name to refer to it.

    I think we could even use the \Drupal\Core\Entity\EntityTypeInterface::getKey() infrastructure for this, and use a new xb_component_local_source_id to identify that actually the machine name should be used, not the JavaScriptComponent config entity ID โ€” related: ๐Ÿ“Œ Allow component source plugins that don't have a plugin_id setting Active . That would result in the stored component trees again having meaningful names for every component instance (much better for debuggability/DX!). The only place where you'd then continue to see UUIDs showing up instead of the machine name is in the config dependencies. That'd be more balanced IMHO.

    But still, the overall direction is clear: we should proceed with this. Thanks!

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    disallow changing the machine name once a corresponding Component exists (which requires modifying the new constraint @larowlan added), and continue to use the machine name to refer to it.

    I don't like the impact this limitation introduces to the UX. Similar to this, I already raised concerns around not being able to edit props / slots for components ( ๐ŸŒฑ Plan to allow editing props and slots for exposed code components Active ). I think we should try to find a solution without this limitation.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    I do not understand why it is unreasonable to lock the machine name at the time where it's being adopted.

    This is not the label, just the machine name. Why is only being able to change the label after component instances are being created not reasonable?

    What benefit does it bring to be able to change the machine name at any time?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States effulgentsia

    I don't think we have an issue for it yet, but one feature we still need to add is the ability for a JS component to import from another JS component. So, for example, if you have a Card component, and it wants to include a Button (as part of its design, not as something a content editor places into a slot), the code for the Card component would have:

    import Button from '@/components/button'
    ...
    // Now in my code I can do: <Button ...>
    

    The string following the last '/' in the import statement is similar to a machine name. One possibility is we use the config entity's machine name instead of needing yet another identifier. However, if we do this, we'd want it to be mutable. Just like when you're editing code in an IDE it's nice to be able to refactor your file names / class names / function names, as you gain more clarity on what purpose that file/class/function is fulfilling.

    I don't know if this is the only use case for wanting a mutable machine name, but it's potentially one of the use cases.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    The string following the last '/' in the import statement is similar to a machine name.

    So that's another reason to have a stable/immutable name (here: not when a code component is "added to the components library" aka has its Component sibling created, but when another code component imports it).

    However, if we do this, we'd want it to be mutable.

    ๐Ÿคฏ That's the opposite conclusion of what I just wrote! ๐Ÿ˜… Why?!

    Just like when you're editing code in an IDE it's nice to be able to refactor your file names / class names / function names, as you gain more clarity on what purpose that file/class/function is fulfilling.

    Right, that's fair. But โ€ฆ how are you going to then automatically update all of the code components that are importing the code component you're renaming? We literally can't do that on the server side, because the server side has zero awareness of the JS code in a code component, all it knows is the string with the raw user input/source code, plus another string with the compiled JS, which only the client side can do the compiling for ๐Ÿ˜…

    Don't get me wrong: I'm actually very glad that there's another use case for mutable machine names, that actually means we are now able to think this through more holistically. Updated the issue summary accordingly! ๐Ÿ˜„

    I'm really curious how @balintbrews and @effulgentsia think we can rename code component A when code components C and F are importing it ๐Ÿ˜‡

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL

    Here is a rough outline I've been thinking about. I'll have more time to elaborate after Atlanta.

    1. Going with @effulgentsia's example of the Card component including Button, and having the following import statement:
      import Button from '@/components/button'
      

      The code editor UI โ€” and also the soon-to-be-worked-on CLI tool โ€” can parse this, recognize button as the machine name, and translate it to the UUID of the Button component's config entity. (We already use @babel/parser to verify that the code contains a default export, which is currently a requirement.)

    2. Now that we have the UUIDs for every dependency in the client, we can send that info along with the code component data to the backend, and it can be stored in a js_dependencies property. (This is where third-party dependencies can also be stored later.) Then the config entity dependencies can be calculated.
    3. To make these import statements work, the backend can generate an import map, where e.g. @/components/button can be mapped to the hydrated JS file.

    How about renaming code components?

    With this approach, we have all the data in the client (both UI and CLI) to tell people what components need to be updated. I think this is enough as the first step. Then, to further improve this, nothing stops us from automatically carrying out those updates โ€” again, still client-side.

  • Assigned to effulgentsia
  • Status changed to Postponed: needs info 30 days ago
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    #14: That is not a complete solution. Because is not good enough: we can't trust the client (even if just because the laptop could be closed, network connection lost, etc.) to update all affected JavaScriptComponents that were using the old machine name to import the JavaScriptComponent being renamed.

    Now that "imports" are being worked on in ๐ŸŒฑ [Plan] First-party code component imports Active , this concern re-surfaced: #3518185-5: Store imported JS components in `JavaScriptComponent` (and reflect in config dependencies) โ†’ .

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL

    #15: That specific part was suggested as a potential improvement on top of what was outlined before โ€” which I think should be considered as a complete solution. So ignoring that additional part, what are your thoughts?

Production build 0.71.5 2024