Component libraries have CSS and JS assets and they should be able to define their own asset libraries instead of relying on a module or theme to define them.

Issue fork components-2707849

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

JohnAlbin created an issue. See original summary.

johnalbin’s picture

See \Drupal\Core\Asset\LibraryDiscoveryCollector::getLibraryDefinitions() and \Drupal\Core\Asset\LibraryDiscoveryParser::buildByExtension().

cyb_tachyon’s picture

This functionality has been built out in a small way for Progressively Decoupled blocks here: https://github.com/mrjmd/pdb/issues/5#issuecomment-218887118

We're thinking it would be a good idea to fully genericize that code and pull out that functionality into the components module and add a dependency for components to PDB.

wim leers’s picture

Title: Allow a component library to define library assets » Allow a component library to define asset libraries
Version: » 8.x-1.x-dev
Issue summary: View changes
wim leers’s picture

Assigned: Unassigned » wim leers
wim leers’s picture

Status: Active » Needs review
StatusFileSize
new17.07 KB

This is as close to a 1:1 port of the logic/patch in #2702061: Unify & simplify render & theme system: component-based rendering (enables pattern library, style guides, interface previews, client-side re-rendering) as possible.

Differences:

  1. uses hook_library_info_alter() instead of modifying \Drupal\Core\Asset\LibraryDiscoveryParser
  2. uses the same ComponentDiscovery.php class, but doesn't actually use it for component discovery; only uses it for asset-library-for-a-component discovery
wim leers’s picture

#6 assumes that all components live at /path/to/extension/components, i.e. in a components subdirectory.

But the components module currently has the concept of component-libraries: any extension can include multiple component libraries. From STARTERKIT.info.yml:

# This section is used by the contrib module, Component Libraries. It allows you
# to reference .twig files in your sass/ directory by using the Twig namespace:
# @STARTERKIT
component-libraries:
  STARTERKIT:
    paths:
      - components
      - templates

This would be fine to support, except that this is then used inconsistently:

  • STARTERKIT/templates contains directories which contain Twig templates (plus metadata): single level
  • STARTERKIT/components contains directories which contain directories which contain Twig templates (plus metadata): multiple levels

So, it's not clear how this ought to behave. It's also not clear why "templates" are considered to be a component library.


Consequently, the patch in #6 does not work with STARTERKIT, because it contains multiple levels in STARTERKIT/components, whereas #2702061: Unify & simplify render & theme system: component-based rendering (enables pattern library, style guides, interface previews, client-side re-rendering) was designed to only allow a single level for simplicity.

wim leers’s picture

StatusFileSize
new17.58 KB
new1.81 KB

This adds support for up to two levels of directories inside the components directory. IOW: this allows components/components/box rather than only components/box. So this means you are allowed one extra level of directories for organization purposes.

For example, the STARTERKIT theme uses

  1. components/layouts/something
  2. components/components/something
  3. components/containers/something
wim leers’s picture

It's also not clear why "templates" are considered to be a component library.

This remains true. IMO this is a design flaw in the current "components" module. Removing this would also mean we can remove the need for this:

# This section is used by the contrib module, Component Libraries. It allows you
# to reference .twig files in your sass/ directory by using the Twig namespace:
# @STARTERKIT
component-libraries:
  STARTERKIT:
    paths:
      - components
      - templates

Opened #2834748: Remove confusing 'component-libraries' key in THEME.info.yml to fix that.

wim leers’s picture

This then updates Zen's STARTERKIT theme to take advantage of this patch; it removes the need to define asset libraries in STARTERKIT.libraries.yml.

wim leers’s picture

Assigned: wim leers » Unassigned

Still to do:

  1. require assets to live inside the component directory (the Zen theme has e.g. components/components/box/box.scss and then has its CSS file at components/asset-builds/css/box.css). This violates the principle of self-containedness.
  2. determine which direction to go with \Drupal\components\Theme\ComponentDiscovery:
    • EITHER remove all the component-related stuff and keep only the asset library-related things
    • OR keep all the component-related stuff, get rid of JSON-based component definitions in favor of YAML and remove \Drupal\components\Template\Loader\ComponentLibraryLoader (because it provides only a subset of what \Drupal\components\Theme\ComponentDiscovery provides)
rainbowarray’s picture

There are a lot of reasons why a front-end developer might want the production CSS in a separate folder from the source component. That's sometimes necessary in order to sync CSS with a style guide/pattern library for example. Requiring production CSS files to be in a certain location seems problematic to me. There may also be cases where CSS does live in the component folder and that works well. I'd just be reluctant to set a hard and fast rule with this.

mariohernandez’s picture

Totally agree with @mdrummond. Front-end is constantly changing and having the flexibility to specify a location for source CSS or JS is a plus.

briangervais’s picture

The 2707849-8.patch patch allowed for libraries to be attached directly from a component template, which is awesome. Also agree with @mdrummond and @mariohernandez that it is preferable to have the flexibility to specify a destination outside of a component for a compiled CSS or JS file.

pixelwhip’s picture

Is the idea here that each individual component will have its own [component].libraries.yml file or would there be one [component-library].libraries.yml per component library namespace? Or am I misunderstanding the intent altogether?

cyb_tachyon’s picture

keep all the component-related stuff, get rid of JSON-based component definitions in favor of YAML and remove \Drupal\components\Template\Loader\ComponentLibraryLoader (because it provides only a subset of what \Drupal\components\Theme\ComponentDiscovery provides)

Personally I like this approach - I'm tinkering with auto-ingesting components as blocks and using a block plugin to expose them to Presenter Mapping inside Drupal as well as Outside-In support. This would make these sorts of experiments easier IMHO.

@pixelwhip

Is the idea here that each individual component will have its own [component].libraries.yml file

I believe this is one of the solutions we are proposing here, similar to how https://www.drupal.org/project/pdb handles things.

or would there be one [component-library].libraries.yml per component library namespace?

This is closer to what we're currently doing - one or more component libraries per theme/module that exists in a Twig namespace as defined in that theme/module's {{ extension }}.libraries.yml.

jacine’s picture

Howdy!

+++ b/STARTERKIT/components/components/messages/messages.yml
@@ -0,0 +1,4 @@
+extends: false

I'm confused about the extends key... I see in the patch, extends gets set to false for modules, and true for themes by default, and yet, in this Zen patch, it's false.

What exactly does it facilitate? Is it whether or not a component template can be overridden? Does it have anything to do with Twig's extends tag?

Thanks :)

aleksip’s picture

I have just released a module that enables component-specific .libraries.yml and .layouts.yml files: https://www.drupal.org/project/multiple_definition_files

robloach’s picture

Whoa! It's been more than 2 years. Would ya'll like me to commit this?

cyb_tachyon’s picture

I think there are two remaining items that Wim mentioned which need to be worked before committing:

  • Require assets to live inside the component directory (the Zen theme has e.g. components/components/box/box.scss and then has its CSS file at components/asset-builds/css/box.css which violates the principle of self-containedness).
  • Keep all the component-related stuff, get rid of JSON-based component definitions in favor of YAML and remove \Drupal\components\Template\Loader\ComponentLibraryLoader (because it provides only a subset of what \Drupal\components\Theme\ComponentDiscovery provides)

Most of my efforts have been focused on PatternKit, which ingests component libraries into blocks and provides mappings for them. Similar to UI_Patterns, but more enterprise grade and no schema modifications.

johnalbin’s picture

Version: 8.x-1.x-dev » 8.x-2.x-dev
johnalbin’s picture

Version: 8.x-2.x-dev » 3.x-dev

New features will need to go in Components 3.x.

johnalbin’s picture

Title: Allow a component library to define asset libraries » Allow components to define asset libraries

Drupal core now has FrontMatter. That may come in useful for defining JS and CSS files for a Twig file. See #3203523: Investigate FrontMatter integration

youngelpaso’s picture

I'm with @mdrummond as well on this. By default, sure have the CSS/JS (and I think images) co-located next to *.twig but have the option to look elsewhere (i.e. wherever your SCSS/Less/PostCSS is built to). There's a good chance someone uses a pre-processor or a utility CSS file that's common to multiple components, but should only be referred to or 'imported' per component when necessary. Even more true for JavaScript dependencies.

Frontmatter might work.

However, since this module provides the ability to use custom namespaces, is there any plans for using those? It would be great if there was a general asset-loader Twig function/YAML definition, whatever the implementation that gells with the '@foobar/foobar.twig' format.

That might be another issue, though I think it's very closely related. In a sense this is all about asset management and Symfony etc extends Twig to better handle assets of any kind using namespaces, perhaps that might be inspirational?

TLDR: why not use a custom Twig function combined w/ namespaces like so?

#info.yml

components:
  namespaces:
    foobar:
      - foobar.twig
      - foobar.js
#foobar.twig
 {{ component_asset(@foobar/foobar.js) }}
mxt’s picture

I'm wondering if it would be possible to simply copy / take as inspiration the ui_patterns code which already now allows you to declare the libraries for each component?

ui_patterns allows you to write the component's yml inside the component folder itself (which also contains all component's assets: css/js/imgs/twig...), and here's how you can declare the component libraries (just an example):

../my-component-folder/my-component-name.ui_patterns.yml

my_component:
  label: Hero
  description: An Hero block with title and a background image.

  fields:
    title:
      type: text
      label: Title
      description: A short title (max 40 characters).
      preview: "Here's the Hero title"
    image:
      type: text
      label: Image
      description: An optimized landscape photograph (1200 x 528)
      preview: /themes/custom/my_theme/images/example-landscape-image.jpg

  libraries:
    - my_theme/paragraph
    - my_component:
        css:
          component:
            ./my_component.css: {}
        js:
          ./my_component.js: {}
        dependencies:
          - my_theme/shared-animations
          - core/drupal
asherry’s picture

StatusFileSize
new17.81 KB

I'm not sure about the status of patch #8, but, I did my best to re-roll it for version 3.x using Drupal 9.

Status: Needs review » Needs work

The last submitted patch, 26: 2707849.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

andypost’s picture

finnsky’s picture

Hello! Added patch with usage of Frontmatter for defining layouts and libraries.
https://www.drupal.org/project/drupal/issues/3075427#comment-14259227

cobadger’s picture

robloach’s picture

Priority: Normal » Major

Nice work, all. Patch applies well. I like where this is going, but the new asset library integration is missing some tests. Would it be possible to add a small check to see if library assets are applied?

For those who prefer git over .patches:

johnalbin’s picture

Status: Needs work » Closed (outdated)

Drupal 10.3.0 was released on 21 Jun 2024 and includes SDC, which implements all of this better, IMO.

Thank you for all your hard work. I'm going to credit all of you and close the issue. Feel free to re-open if you have strong opinions that this should still go in.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.