Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions jest/setup-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,6 @@
import "core-js/stable";
import "regenerator-runtime/runtime";

import jquery from "jquery";
global.$ = global.jQuery = jquery;

jquery.expr.pseudos.visible = function () {
// Fix jQuery ":visible" selector always returns false in JSDOM.
// https://github.com/jsdom/jsdom/issues/1048#issuecomment-401599392
return true;
};

// pat-fullscreen
document.requestFullscreen = jest.fn();
document.exitFullscreen = jest.fn();
Expand Down Expand Up @@ -67,17 +58,6 @@ global.IntersectionObserver = class IntersectionObserver {
}
};

// Do not output error messages
import logging from "@patternslib/patternslib/src/core/logging";
logging.setLevel(50); // level: FATAL

// patch dom.is_visible to not rely on jest-unavailable offsetWidth/Height but
// simply on el.hidden.
import dom from "@patternslib/patternslib/src/core/dom";
dom.is_visible = (el) => {
return !el.hidden;
};

// jsDOM does not add ``getClientRects`` or ``getBoundingClientRect`` to a ``document.createRange()``
// Originally from pat-tiptap to allow scroloing into the view when focusing the editor.
Range.prototype.getClientRects = () => [];
Expand Down
23 changes: 9 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,25 @@
"dependencies": {
"@babel/core": "^7.19.3",
"@babel/eslint-parser": "^7.19.1",
"@babel/preset-env": "^7.19.3",
"@babel/preset-env": "^7.19.4",
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
"@release-it/conventional-changelog": "^5.1.0",
"@release-it/conventional-changelog": "^5.1.1",
"babel-loader": "^8.2.5",
"core-js": "3.25.3",
"core-js": "3.25.5",
"css-loader": "^6.7.1",
"eslint": "^8.24.0",
"eslint": "^8.25.0",
"eslint-config-prettier": "^8.5.0",
"husky": "^8.0.1",
"identity-obj-proxy": "^3.0.0",
"imports-loader": "^4.0.1",
"jest": "^29.1.1",
"jest-environment-jsdom": "^29.1.1",
"jest": "^29.2.0",
"jest-environment-jsdom": "^29.2.0",
"jest-watch-typeahead": "^2.2.0",
"prettier": "^2.7.1",
"regenerator-runtime": "^0.13.9",
"release-it": "^15.4.2",
"regenerator-runtime": "^0.13.10",
"release-it": "^15.5.0",
"sass": "^1.55.0",
"sass-loader": "^13.0.2",
"sass-loader": "^13.1.0",
"style-loader": "^3.3.0",
"terser-webpack-plugin": "^5.3.6",
"timezone-mock": "^1.3.4",
Expand All @@ -36,10 +35,6 @@
"whybundled": "^2.0.0",
"yarn": "^1.22.19"
},
"devDependencies": {
"@patternslib/patternslib": "*",
"jquery": "^3.6.1"
},
"scripts": {
"test": "jest"
},
Expand Down
40 changes: 40 additions & 0 deletions webpack/module_federation--dynamic-federation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Author: Manfred Steyer <manfred.steyer@gmx.net>
// Author: Johannes Raggam <thetetet@gmail.com>

// From:
// https://github.com/manfredsteyer/plugin-demo.git
// https://github.com/thet/module-federation-minimaltest.git

/**
* Load remote module / bundle.
*
* Wrapper around webpack runtime API
*
* Usage: get_container("bundle-name-xyz")
*
* @param {string} remote - the remote global name
* @returns {Promise<object>} - Federated Module Container
*/
const container_map = {};
let is_default_scope_initialized = false;

export default async function get_container(remote) {
const container = window[remote];

// Do we still need to initialize the remote?
if (container_map[remote]) {
return container;
}

// Do we still need to initialize the shared scope?
if (!is_default_scope_initialized) {
await __webpack_init_sharing__("default"); // eslint-disable-line no-undef
is_default_scope_initialized = true;
}

await container.init(__webpack_share_scopes__.default); // eslint-disable-line no-undef

// Remember that the container has been initialized.
container_map[remote] = true;
return container;
}
71 changes: 71 additions & 0 deletions webpack/module_federation--getOrLoadRemote.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Author: ScriptedAlchemy <zackary.l.jackson@gmail.com>
// Author: Johannes Raggam <thetetet@gmail.com>

// From:
// https://twitter.com/ScriptedAlchemy/status/1505135006158532612
// https://gist.github.com/ScriptedAlchemy/3a24008ef60adc47fad1af7d3299a063
// https://github.com/module-federation/module-federation-examples/blob/master/dynamic-system-host/app1/src/utils/getOrLoadRemote.js

/**
* Load remote module / bundle.
*
* Usage: get_container("bundle-name-xyz", "default", "http://theRemote.com")
*
*
* @param {string} remote - the remote global name
* @param {string} share_scope - the scope key
* @param {string} remote_fallback_url - fallback url for remote module
* @returns {Promise<object>} - Federated Module Container
*/
export default function get_container(
remote,
share_scope = "default",
remote_fallback_url = undefined
) {
new Promise((resolve, reject) => {
if (!window[remote]) {
// Remote not yet globally available.

// onload hook when Module Federated resource is loaded.
const onload = async () => {
// When remote is loaded, initialize it if it wasn't already.
if (!window[remote].__initialized) {
await window[remote].init(__webpack_share_scopes__[share_scope]); // eslint-disable-line no-undef
// Mark remote as initialized.
window[remote].__initialized = true;
}
// Resolve promise so marking remote as loaded.
resolve(window[remote]);
};

// Search dom to see if the remote exists as script tag.
// It might still be loading (async).
const existing_remote = document.querySelector(`[data-webpack="${remote}"]`);

if (existing_remote) {
// If remote exists but was not loaded, hook into its onload
// and wait for it to be ready.
existing_remote.onload = onload;
existing_remote.onerror = reject;
} else if (remote_fallback_url) {
// Inject remote if a fallback exists and call the same onload
// function
const script = document.createElement("script");
script.type = "text/javascript";
// Mark as data-webpack so runtime can track it internally.
script.setAttribute("data-webpack", `${remote}`);
script.async = true;
script.onerror = reject;
script.onload = onload;
script.src = remote_fallback_url;
document.getElementsByTagName("head")[0].appendChild(script);
} else {
// No remote and no fallback exist, reject.
reject(`Cannot Find Remote ${remote} to inject`);
}
} else {
// Remote already instantiated, resolve
resolve(window[remote]);
}
});
}
57 changes: 57 additions & 0 deletions webpack/module_federation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Initialize dynamic module federation.
*/
import get_container from "./module_federation--dynamic-federation";

// Patternslib Module Federation bundle prefix.
// This is used to filter for module federation enabled bundles.
// NOTE: This is also defined in ``webpack.mf.js``.
export const MF_NAME_PREFIX = "__patternslib_mf__";

if (typeof window.__patternslib_container_map === "undefined") {
window.__patternslib_container_map = {};
}
const container_map = window.__patternslib_container_map;

export async function initialize_remote({ remote_name, exposed_module = "./main" }) {
if (container_map[`${remote_name}-${exposed_module}`]) {
// already initialized, return.
return;
}
const container = await get_container(remote_name);
const factory = await container.get(exposed_module);
const module = factory();

container_map[`${remote_name}-${exposed_module}`] = true;

console.debug(
`Patternslib Module Federation: Loaded and initialized bundle "${remote_name}".`
);

return module;
}

function document_ready(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}

document_ready(function () {
// Automatically initialize all Module Federation enabled Patternslib based
// bundles by filtering for the prefix ``__patternslib_mf__``.
// Do this on document ready, as this is the time where all MF bundles have
// been registered in the global namespace.
const bundles = Object.keys(window).filter((it) => it.indexOf(MF_NAME_PREFIX) === 0);
for (const bundle_name of bundles) {
// Now load + initialize each bundle.
initialize_remote({ remote_name: bundle_name });
}
document.dispatchEvent(
new Event("patternslib__mf--loaded", { bubbles: true, cancelable: false })
);
});
9 changes: 0 additions & 9 deletions webpack/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,6 @@ const config_factory = (env, argv, config, babel_include = [], package_json) =>
exclude: new RegExp(babel_exclude),
loader: "babel-loader",
},
// TODO: Remove with next major version.
{
test: /showdown-prettify/,
use: [
{
loader: "imports-loader?showdown,google-code-prettify",
},
],
},
{
test: /\.(?:sass|scss|css)$/i,
use: [
Expand Down
Loading