Skip to content

Flexible source vs dist folders/clientlibs management #144

@infloent

Description

@infloent

Proposal: filename-based dist folder control for multi-clientlib components

I have a working implementation of the features described below, including tests and documentation. If this proposal is approved, I can open a PR with the full change ready to review.


AEM requires one folder per clientlib. A component with publish, author, and feature variants needs multiple clientlibs, meaning multiple source folders today, just to satisfy the clientlibs folder constraint.

This proposes three new flags that would let the build read the folder structure from the filename, so all files for a component stay together in source and fan out correctly in dist.

A separate flag would also generate the clientlib metadata files (.content.xml, js.txt) for webpack splitChunks groups, and checkChunk would expose the source filename to test functions so chunk grouping can follow the same naming convention.


New options

All would default to false / []. Existing projects would be unaffected unless they opt in.

Filename-based dist folders (config.general)

Option What it does
sourceKey: string or string[] Match one or multiple source suffixes (e.g. 'clientlibs' or ['clientlibs', 'publishlibs', 'authorlibs'])
sourceKeyAsDistFolder: true Promote the matched sourceKey suffix to a dist subfolder
fileNameDotSuffixesAsDistFolder: true Promote dot-segments between name and sourceKey suffix to dist subfolders
excludeFileNameDotSuffixes: string[] Opt specific values out of folder promotion (migration safety valve)

Split chunks clientlibs (config.clientlibs)

Option What it does
generateSplitChunksClientlibs: true Auto-generate .content.xml + js.txt for webpack splitChunks / runtimeChunk output folders

This would be independent of the filename-based flags above. checkChunk would also expose module.resource (the full file path including filename) to splitChunks cache group test functions, making it possible to also route files by name convention into dedicated chunk groups.


The idea

All files for a component live in one folder (not mandatory). One ls returns the complete picture of what it does and how it splits, useful for developers navigating the codebase and for AI tools that rely on directory context to understand component scope.

When an AI needs context to fix or extend a component, one directory read is enough instead of correlating multiple parallel trees, which means fewer tool calls and less context consumed.

sourceKey: ['clientlibs', 'publishlibs', 'authorlibs'],
sourceKeyAsDistFolder: true,
fileNameDotSuffixesAsDistFolder: true,
excludeFileNameDotSuffixes: ['clientlibs']
src/components/cmp/v1/cmp/
  cmp.main.publishlibs.js       ← The main cmp functionality
  cmp.main.publishlibs.scss     ← The default cmp styles
  cmp.main.authorlibs.js        ← The main cmp author functionality when needed
  cmp.main.authorlibs.scss.     ← The default cmp author styles overwrites
  cmp.layout1.publishlibs.scss  ← loaded only when needed based on cmp config
  cmp.layout1.authorlibs.scss   ← some layout/feature might need author css overwrites
  cmp.layout2.publishlibs.scss  ← loaded only when needed based on cmp config
  cmp.tracking.clientlibs.js    ← loaded if tracking is enabled
  cmp.dialog.clientlibs.js       ← loaded as extra clientlib in dialog
  cmp.dialog.clientlibs.scss     ← loaded as extra clientlib in dialog
  cmp.editor.clientlibs.scss     ← custom granite editor toolbars widgets
dist/components/cmp/v1/cmp
  main/
    publishlibs/
      .content.xml
      js.txt
      css.txt
      cmp.bundle.js
      cmp.bundle.css
    authorlibs/
      .content.xml
      js.txt
      css.txt
      cmp.bundle.js
      cmp.bundle.css
  layout1/
    publishlibs/
      .content.xml
      css.txt
      cmp.layout1.bundle.css
    authorlibs/
      .content.xml
      css.txt
      cmp.layout1.bundle.css
  layout2/
    publishlibs/
      .content.xml
      css.txt
      cmp.layout2.bundle.css
  tracking/
    .content.xml
    js.txt
    cmp.tracking.bundle.js
  dialog/
    .content.xml
    js.txt
    css.txt
    cmp.dialog.bundle.js
    cmp.dialog.bundle.css
  editor/
    .content.xml
    css.txt
    cmp.editor.bundle.css

Scope

Core logic - utils/generateEntries.js, utils/checkChunk.js
Tasks - tasks/clientlibs.js (split chunks support), tasks/styles.js (watcher compatibility with array sourceKey and new flags)
Config - config/general.config.js, config/clientlibs.config.js, config/optimization.config.js
Tests - new fixture sets for feature-segments and multi-sourcekey scenarios, covering all flag combinations

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions