Skip to content

Instantly share code, notes, and snippets.

@ls-joris-desmedt
Last active July 13, 2020 22:56
Show Gist options
  • Select an option

  • Save ls-joris-desmedt/29d297250f84338e82a89458fb30b447 to your computer and use it in GitHub Desktop.

Select an option

Save ls-joris-desmedt/29d297250f84338e82a89458fb30b447 to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from 'react';
import { useDynamicScript } from 'use-dynamic-script';
const RemoteComponent = ({
scope,
module,
props,
}: {
scope: string;
module: string;
props: any;
}) => {
const { ready, failed } = useDynamicScript('http://localhost:8080/remoteEntry.js');
const [initialised, setInitialised] = useState(false);
useEffect(() => {
if (ready && !failed && !initialised) {
if (global[scope] && global[scope].init) {
global[scope].init(
Object.assign(
{
react: {
get: () => Promise.resolve(() => require('react')),
loaded: true,
},
'emotion-theming': {
get: () => Promise.resolve(() => require('emotion-theming')),
loaded: true,
},
'@emotion/core': {
get: () => Promise.resolve(() => require('@emotion/core')),
loaded: true,
},
'@emotion/styled': {
get: () => Promise.resolve(() => require('@emotion/styled')),
loaded: true,
},
},
// eslint-disable-next-line
// @ts-ignore
global.__webpack_require__ ? global.__webpack_require__.o : {},
),
);
setInitialised(true);
}
}
}, [ready, failed, initialised, scope]);
if (!ready || failed || !initialised || !global) {
return null;
}
const Component = React.lazy(() =>
global[scope].get(module).then((factory) => {
const Module = factory();
return Module;
}),
);
return (
<React.Suspense fallback={<div>Loading...</div>}>
<Component {...props} />
</React.Suspense>
);
};
export default RemoteComponent;
import React, { useState, useEffect } from 'react';
export const useDynamicScript = (url: string) => {
const [ready, setReady] = React.useState(false);
const [failed, setFailed] = React.useState(false);
React.useEffect(() => {
if (!url) {
return;
}
if (document.querySelector(`script[src="${url}"]`)) {
setReady(true);
}
const element = document.createElement('script');
element.src = url;
element.type = 'text/javascript';
element.async = true;
setReady(false);
setFailed(false);
element.onload = () => {
console.log(`Dynamic Script Loaded: ${url}`);
setReady(true);
};
element.onerror = () => {
console.error(`Dynamic Script Error: ${url}`);
setReady(false);
setFailed(true);
};
document.head.appendChild(element);
return () => {
console.log(`Dynamic Script Removed: ${url}`);
document.head.removeChild(element);
};
}, [url]);
return {
ready,
failed,
};
};
@jherr
Copy link

jherr commented Jul 7, 2020

This is amazing! Can't wait to try it out!

@ScriptedAlchemy
Copy link

very nice!

@Jordan-Gilliam
Copy link

This is beautiful 😍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment