The Design-System-Team has taken the feedback from the code splitting proposal (T344386) into an actionable implementation plan (T349423). As part of this, there is a series of open questions that we'd like assistance from the MW Platform team on answering.
From the task description of T344386:
- How can we provide backwards compatibility for code that depends on the @wikimedia/codex module and expects that to load the full library? Or is this not feasible, and do we have to accept this as a breaking change (making that code use e.g. codex-all instead)?
- One way we might be able to do this: add some sort of special treatment for the @wikimedia/codex module in RL so that other modules can call require( '@wikimedia/codex' ) even if that module isn't loaded, and can add things to the object that that require call returns. Then modules using CodexModule would not depend on the @wikimedia/codex module and it wouldn't be loaded. The @wikimedia/codex module would contain the full library and would only be loaded if it was explicitly depended on.
- If we want to provide a custom error message for code that attempts to access missing components (see implementation plan step 1), then we would need a way to wrap the object returned by require( '@wikimedia/codex' ) in a Proxy. Perhaps we could accomplish this through a feature similar to skipFunction that allows a module to run a short snippet of code to provide the value require() should return when the module has not yet been loaded?
- Is there (or could there be) a cleaner way to override the packageFiles property in ResourceLoader\FileModule? Overriding getPackageFiles doesn't work, because getDefinitionSummary calls the private expandPackageFiles method that then pollutes a cache that getPackageFiles uses. We can work around this by overriding getDefinitionSummary, but if any other methods were to call expandPackageFiles in the future we'd have to override them too, so that doesn't seem like a great approach.
- How does a module using CodexModule add components to the collector module when it executes? Does it wrap the main script with a new file that adds the components before calling the old main file?
- How do we ensure cache invalidation behaves correctly for a module using CodexModule? What do we need to do in getDefinitionSummary and/or elsewhere to make this work?
- We need to invalidate the cache when one of the Codex files changes, or when the set of files that is loaded changes. The latter can happen when the manifest files change, or when the module's list of dependencies changes, or when one of the module's dependencies changes which Codex files it loads.
- Adding the Codex files to the packageFiles and styles properties should take care of invalidating the cache when those files change. Should we just add the list of files that will be loaded to getDefinitionSummary?
- Should we cache reading the manifest files and deriving the information we need from them? Would it make sense to build a data structure derived from the manifest files that is in a more convenient format for building module contents, and caching that in memcached, invalidated by a hash of the contents of the manifest file or something like that?