Skip to content

Commit

Permalink
feat: Allow bundle name spacing (#1774)
Browse files Browse the repository at this point in the history
* use worker threads for webpack dev server if possible

* feat: ✨ Allow bundle namespacing

Currently everything gets read from bundleAssets and put it under window.xarcv1.rt.bundles directly. This PR adds namespacing capabilities to have multiple bundle assets and allows subapps to be loaded from different namespaces.

Co-authored-by: Joel Chen <[email protected]>
Co-authored-by: Joel Chen <[email protected]>
  • Loading branch information
3 people authored Jan 4, 2021
1 parent 27f6236 commit 2d56858
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 20 deletions.
12 changes: 7 additions & 5 deletions packages/subapp-web/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ export function loadSubApp(info, renderStart, options) {
info = makeSubAppSpec(info);

const name = info.name;
const ns = info.ns;

let subApp = xarc.getSubApp(name) || { info };

// mark the subapp's webpack bundle as loaded
if (!xarc.getBundle(name)) {
xarc.setBundle(name, true);
if (!xarc.getBundle(name, ns)) {
xarc.setBundle(name, true, ns);
}

// subapp already loaded, do nothing and return the info
Expand Down Expand Up @@ -182,7 +184,7 @@ export function isLoaded(name) {
return Boolean(xarc.getSubApp(name));
}

export function lazyLoadSubApp({ name, id, timeout = 15000, onLoad, onError, fallback }) {
export function lazyLoadSubApp({ name, id, timeout = 15000, onLoad, onError, fallback, ns }) {
// TODO: timeout and callback
const lname = name.toLowerCase();

Expand All @@ -205,8 +207,8 @@ export function lazyLoadSubApp({ name, id, timeout = 15000, onLoad, onError, fal
return false;
};

if (xarc.getBundle(name) === undefined) {
xarc.loadSubAppBundles(lname);
if (xarc.getBundle(name, ns) === undefined) {
xarc.loadSubAppBundles(lname, null, ns);
} else if (!id && !onLoad) {
const inlined = renderInline();
if (inlined) {
Expand Down
53 changes: 38 additions & 15 deletions packages/subapp-web/src/subapp-web.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

let xv1;

const DEFAULT_NAMESPACE = "root";

const ensureNamespace = (namespace = DEFAULT_NAMESPACE) => namespace;

return (w.xarcV1 = xv1 = {
IS_BROWSER: true,
HAS_WINDOW: typeof window !== "undefined",
Expand Down Expand Up @@ -112,12 +116,20 @@
return defer.promise;
},

getBundle(name) {
return name ? runtimeInfo.bundles[name.toLowerCase()] : undefined;
getBundle(name, namespace) {
namespace = ensureNamespace(namespace);

if (!name || !runtimeInfo.bundles[namespace] || !runtimeInfo.bundles[namespace][name.toLowerCase()]) {
return;
}

return runtimeInfo.bundles[namespace][name.toLowerCase()];
},

setBundle(name, state) {
runtimeInfo.bundles[name.toLowerCase()] = state;
setBundle(name, state, namespace) {
namespace = ensureNamespace(namespace);
runtimeInfo.bundles[namespace] = runtimeInfo.bundles[namespace] || {};
runtimeInfo.bundles[namespace][name.toLowerCase()] = state;
},

getSubApp(name) {
Expand Down Expand Up @@ -290,30 +302,41 @@
xv1.watchSubAppOnLoad(true);
},

markBundlesLoaded(ids) {
markBundlesLoaded(ids, namespace) {
[].concat(ids).forEach(id => {
xv1.setBundle(id.toString(), 1);
xv1.setBundle(id.toString(), 1, namespace);
});
},

getBundleAssets() {
getBundleAssets(namespace) {
namespace = ensureNamespace(namespace);

if (!runtimeInfo.bundleAssets) {
runtimeInfo.bundleAssets = xv1.dyn("bundleAssets");
xv1.cdnInit(runtimeInfo.bundleAssets);
runtimeInfo.bundleAssets = {};
}
return runtimeInfo.bundleAssets;

if (!runtimeInfo.bundleAssets[namespace]) {
const bundleName = namespace === DEFAULT_NAMESPACE ? "bundleAssets": `${namespace}Assets`;
runtimeInfo.bundleAssets[namespace] = xv1.dyn(bundleName);

const updater = xv1.rt.md === "undefined" ? xv1.cdnInit : xv1.cdnUpdate;
updater(runtimeInfo.bundleAssets[namespace]);
}

return runtimeInfo.bundleAssets[namespace];
},

loadSubAppBundles(names, done) {
loadSubAppBundles(names, done, namespace) {
done = done || (() => {});
namespace = ensureNamespace(namespace);

const toLoad = [].concat(names).filter(x => xv1.getBundle(x) === undefined);
const toLoad = [].concat(names).filter(x => xv1.getBundle(x, namespace) === undefined);

if (toLoad.length === 0) {
return done();
}

const ba = xv1.getBundleAssets();
const ba = xv1.getBundleAssets(namespace);
const loaded = [];
const assetsToLoad = toLoad
.reduce((a, name) => {
Expand All @@ -332,8 +355,8 @@
}, [])
.filter(({ id }) => {
id = id.toString();
if (xv1.getBundle(id) === undefined) {
xv1.setBundle(id, 0); // mark as loading
if (xv1.getBundle(id, namespace) === undefined) {
xv1.setBundle(id, 0, namespace); // mark as loading

return true;
}
Expand Down
20 changes: 20 additions & 0 deletions packages/subapp-web/test/spec/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,26 @@ describe("subapp-web", function() {
expect(subApp._started).to.exist;
});

it("loadSubApp with namespace should run load subapp under correct path", async () => {
require("../../src/subapp-web");
const xarc = require("../../src/xarc").default;
const index = require("../../src/index");
const subAppInfo = {
name: "testsubapp",
Component: () => "asdf",
ns: "test-namespace"
};
index.loadSubApp(subAppInfo);
const subApp = xarc.getSubApp("testsubapp");

expect(xarc.rt.bundles).to.deep.equal({
"test-namespace": {
testsubapp: true
}
});
expect(subApp._started).to.exist;
});

it("loadSubApp should call preStart, preRender, signalReady", async () => {
let preStartCalled = false;
let preRenderCalled = false;
Expand Down

0 comments on commit 2d56858

Please sign in to comment.