flarum / flarum/issue-archive

Unify javascript imports, exports and compat from core and extensions

Open
#166 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

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.

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](https://en.wikipedia.org/wiki/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 around `chunkGraph.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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.