This is not a new subject but I don't think we have a GitHub issue specific for it, so here it is.
Right now, we use two different systems for internal import/export inside a single extension, and external import/export between extensions.
Internal imports use the built-in ES module loader from webpack.
External imports use two different methods:
The flarum.compat object, for core and core extensions. Populated by a method in each extension
The flarum.extensions objects for extensions. Populated automatically with the module exports
There are various problems with those approaches:
There's no way to automatically have everything exposed. This is particularly important for core and core extensions, and we have forgotten to include some classes in the exports in the past, like flarum/framework#1933
Methods can't be extended because local imports use a different system than external imports, so it's only possible to monkey-patch a class prototype, but not a simple function. This probably could have a GitHub issue of its own
There is no standard for how to structure the export object (nested objects, or flat object with dot/slashes based keys)
Exporting everything from an extension is extremely verbose
I have researched possible improvements in the past multiple times but never had much success. But since I've found a few interesting things, I figured out I'd create an issue to keep them listed.
Maybe there would be a way to extend the JavascriptModulesPlugin to change from array-based into key-based, so that everything can use the namespaced names, and have everything in the global namespace with a single webpack module loader boot code. Maybe there are some things to look around chunkGraph.getModuleId.
That library seems to be exactly a hybrid of the built-in import/export plugin AND something like our compat array. It seems like we could use that webpack plugin in our extensions, then specify a module name and a list of file paths to export globally. It's designed to be used from different javascript files loaded from different origins, but it seems like it would work just as well inside a single, dynamically concatenated file.
This is not a new subject but I don't think we have a GitHub issue specific for it, so here it is.
Right now, we use two different systems for internal import/export inside a single extension, and external import/export between extensions.
Internal imports use the built-in ES module loader from webpack.
External imports use two different methods:
flarum.compat
object, for core and core extensions. Populated by a method in each extensionflarum.extensions
objects for extensions. Populated automatically with the module exportsThere are various problems with those approaches:
I have researched possible improvements in the past multiple times but never had much success. But since I've found a few interesting things, I figured out I'd create an issue to keep them listed.
For a long time I didn't know what library took care of compiling the import/exports. It's a webpack module, but there isn't a lot of documentation on how to customize it. It's the
JavascriptModulesPlugin
https://github.com/webpack/webpack/blob/master/lib/javascript/JavascriptModulesPlugin.js . There seem to be some interesting options, like for example the ability to disable the IIFE (Immediately invoked function expression, I discovered that word today while reading webpack source code).Maybe there would be a way to extend the
JavascriptModulesPlugin
to change from array-based into key-based, so that everything can use the namespaced names, and have everything in the global namespace with a single webpack module loader boot code. Maybe there are some things to look aroundchunkGraph.getModuleId
.Something which I discovered today and seems very new but also very relevant is https://module-federation.github.io/blog/get-started . It seems to have been recently integrated into Webpack itself https://github.com/webpack/webpack/issues/10352
That library seems to be exactly a hybrid of the built-in import/export plugin AND something like our compat array. It seems like we could use that webpack plugin in our extensions, then specify a module name and a list of file paths to export globally. It's designed to be used from different javascript files loaded from different origins, but it seems like it would work just as well inside a single, dynamically concatenated file.