Background
The FileModule is the default and most-used module type used by MediaWiki core components and MediaWiki extensions use to define their CSS and JavaScript bundles in ResourceLoader.
Other module types use instead (or additionally) contents from a source other than files in a directory relating to this module, such as CodexModule, or WikiModule (wiki pages such as user scripts, site scripts, and gadgets).
Problem 1: Discovery
It is not apparent from reviewing existing code that the functionality for using localisation messages in a stylesheet comes from a custom module type, so code that works in one module doesn't in another until you figure out that the code was registered in extension.json via a module subclass, and that is what adds this behaviour to otherwise normal-looking .less files.
This can then lead into the next problem, which is that once you know you need to use the LessVarModule subclass, your code may be using the CodexModule subclass, which is incompatible and has no way to "enable" this feature.
Problem 2: Splitting
The functionality for adding localisation messages in a stylesheet is in the LessVarModule subclass, extending FileModule. This means a module can either augment itself with Codex or adopt localisation in its stylesheets, despite being orthogonal use cases. There's not any less a chance to need Codex when using localised stylesheets or vice versa, thus requiring developers to split up the code and register two separate bundles on all page views to workaround this.
The impact of this is described in MediaWiki Engineering - Frontend best practices § Startup manifest and Wikipedia’s JavaScript initialisation on a budget (2019 blogpost). The best practices guide in particular recommends "three modules" for a given feature, which is hard to abide when a module needs to be split in two for this kind of reason.
CodexModule is still relatively new so far this has come up once as part of T392522: IP reveal: IP reveal fails if the temporary account is expired. The workaround was to register two modules for the same purpose, and to carefully queue both in consuming pages.
'mediawiki.interface.helpers.linker.styles' => [ 'class' => CodexModule::class, 'codexStyleOnly' => true, 'codexComponents' => [ 'CdxTooltip', ], ], 'mediawiki.interface.helpers.styles' => [ …, 'class' => LessVarFileModule::class, 'lessMessages' => [ 'comma-separator', 'parentheses-start', 'parentheses-end', … ], 'styles' => [ 'linker.styles.less', ], ],
Solution
Fold the LessVarModule functionality into FileModule, where the other .less functionality exists as well.
Some of the internal fields clash, so we'll need to rename those.
And we'll need to make sure cache invalidation / change propagation still works as expected, especially for message blobs after localisation updates.