Closed maethu closed 2 years ago
Followup
I have now a webpack config with module federation:
const path = require("path");
const { VueLoaderPlugin } = require("vue-loader");
const package_json = require("./package.json");
const mf_config = require("@patternslib/patternslib/webpack/webpack.mf");
module.exports = (env) => {
let config = {
entry: {
"mylib.min": path.resolve(
__dirname,
"./path/to/js/js/src/main.js"
),
},
...
plugins: [new VueLoaderPlugin()],
...
},
};
config.plugins.push(
mf_config({
filename: "mylib-remote.min.js",
package_json: package_json,
remote_entry: config.entry["mylib.min"],
})
);
return config;
};
So far so good.
Problem
window.bootstrap is still not available -> It is loaded though, since bootstrap registered it's plugins as JQuery plugins as well. Which is accessible as window.JQuery.fn.modal
.
If I do import { Modal } from "bootstrap";
in my code, which actually works kinda, but I have weird side effects. Seems like bootstrap gets initialised multiple times. The workaround via the JQuery plugin seems to work fine though.
Everything else seems to work as expected!! Thanks so much to put in the work to introduce module federation!
stumbled upon this too today ... @thet tried to fix it here, but still not working for me: #1177
@petschki @thet
I think something is really odd with bootstrap 5.2, or there might be integration issues with webpacks module federeation.
If I do await import("bootstrap")
or import "bootstrap"
anywhere in my code. DropDowns for example do no longer work.
The mentioned workaround via jQuery does not always work, since it does depend on load order.
Example: This shows all events registered on a click event for a dropdown button
If I import a Plugin for bootstrap, for example import { Collapse } from "bootstrap";
, alle events are then twice registered.
Which does lead to side effects.
Any idea how I can mitigate this? Th solution from https://github.com/plone/mockup/pull/1177 most likely will work.
I do not know how to solve this yet but it seems to me that registering modules globally and MF configured modules are conceptually a bit against each other.
The MF configuration of @patternslib/dev
(the new base package of mf_config
... see https://github.com/plone/mockup/blob/upgrade-dev/webpack.config.js#L6) registers the remote
bundles to a special prefixed global namespace (https://github.com/Patternslib/dev/blob/main/webpack/webpack.mf.js#L42) and initialized these when the DOM is loaded (https://github.com/Patternslib/Patterns/blob/master/webpack/module_federation.js#L34) ... so far so good since we have jQuery
and bootstrap
as separate remote bundles.
But that means if you have your own "non-MF" configured addon-bundle loaded after the plone
bundle and you want to use window.$
or window.bootstrap
it does not exists (or may not exist).
So I think we should offer 2 possible "usages" for addon developers:
Simple usage -> Use globally registered modules: This should be very straight forward and easy to use, for example if you have a simple <script>
in your template and you want to use $
or bootstrap
it should simply work (many addons depend on constructs like (function($) { ... })(jQuery)
in their JS ... for eg the bda.plone.shop
bundle).
Advanced usage -> Configure your addon bundle with Module Federation and use all its benefits. Here you should be able to use for eg. import "bootstrap"
and it shouldn't get initialized twice on the page.
Now the big question is, can both usages coexist without too much downgrades (page load etc.)?
Another question: if bootstrap
is registered globally, how does module federation know about it and use it?
@thet we really should fix that soon and write some docs about it.
I do not know how to solve this yet but it seems to me that registering modules globally and MF configured modules are conceptually a bit against each other.
I totally agree.
I like the MF approach a lot. It also mostly works fine, for example with jQuery. I can do import $ from "jQuery"
and it loads the module correctly. The webpack config seems to be quite easy as well, I just followed the steps documented and it did work right away.
Fixed here: https://github.com/plone/mockup/pull/1185
With the release 5.0.0-alpha.0 (before webpack module federation) there was a bootstrap object globally available.
With this I was for example able to control Modal instances via script
This is no longer possible. I'm not sure why, For example jQuery ist still there (via https://github.com/plone/mockup/blob/master/src/index-jquery.js)
@thet You may have an idea?