Skip to content

Instantly share code, notes, and snippets.

@projektorius96
Forked from mhofman/greeter.js
Created November 8, 2022 15:15
Show Gist options
  • Save projektorius96/76f3d46d038fd2628eeb3e19956b777c to your computer and use it in GitHub Desktop.
Save projektorius96/76f3d46d038fd2628eeb3e19956b777c to your computer and use it in GitHub Desktop.
ES Module Dynamic export
const greeters = {
'en': 'english',
'fr': 'french'
};
const promise = (async () => {
const greeter = greeters[navigator.language.split('-')[0]];
if (!greeter) {
throw new Error('No greeter for you!');
}
return import(`./impl-greeter-${greeter}.js`);
})();
export default promise;
export const then = promise.then.bind(promise);
export function sayHi(person) {
return `Hello ${person}`;
}
export function sayHi(person) {
return `Bonjour ${person}`;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Greeter Dynamic ES Module example</title>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script src="https://unpkg.com/iframe-resizer@^4/js/iframeResizer.min.js"></script>
<style>
iframe {
border: solid 1px #eee;
border-bottom: solid 1px #ccc;
width: 100%;
}
</style>
</head>
<body>
<script>
[
'basic-static',
'basic-dynamic',
'basic-dynamic-english',
'basic-dynamic-checks',
].forEach(test => {
let frame = document.createElement('iframe');
frame.src = `./test-${test}.html`;
frame.scrolling = "no";
document.body.appendChild(frame);
});
iFrameResize({interval: 0});
</script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dynamic Import checks</title>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script src="https://bl.ocks.org/mhofman/raw/fe170f9492196e9eb09907c84ea28999/html-console.js"></script>
<script src="https://unpkg.com/iframe-resizer@4/js/iframeResizer.contentWindow.min.js" defer></script>
<script>const log = (msg) => htmlConsole.log(`${document.title}: ${msg}`)</script>
<script type="module">
import moduleStaticPromise from './greeter.js';
(async () => {
try {
const [moduleStatic, moduleDynamic , moduleDynamicEnglish, moduleDynamicFrench] = await Promise.all([
moduleStaticPromise, import('./greeter.js'), import('./impl-greeter-english.js'), import('./impl-greeter-french.js')]);
if (moduleStatic !== moduleDynamic) throw new Error('Different modules !?');
switch (moduleDynamic) {
case moduleDynamicEnglish:
log('We loaded the english implementation');
break;
case moduleDynamicFrench:
log('We loaded the french implementation');
break;
default:
throw new Error("Implementations don't match !?");
}
}
catch(e) {
log(e.stack);
throw e;
}
})();
</script>
</head>
<body>
<div id="console"></div>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dynamic Import of implementation</title>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script src="https://bl.ocks.org/mhofman/raw/fe170f9492196e9eb09907c84ea28999/html-console.js"></script>
<script src="https://unpkg.com/iframe-resizer@4/js/iframeResizer.contentWindow.min.js" defer></script>
<script>const log = (msg) => htmlConsole.log(`${document.title}: ${msg}`)</script>
<script type="module">
// Dynamically loading the english implementation directly
(async () => {
try {
const { sayHi } = await import('./impl-greeter-english.js');
log(sayHi('await import("greeter-impl")'));
}
catch(e) {
log(e.stack);
throw e;
}
})();
</script>
</head>
<body>
<div id="console"></div>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dynamic Import</title>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script src="https://bl.ocks.org/mhofman/raw/fe170f9492196e9eb09907c84ea28999/html-console.js"></script>
<script src="https://unpkg.com/iframe-resizer@4/js/iframeResizer.contentWindow.min.js" defer></script>
<script>const log = (msg) => htmlConsole.log(`${document.title}: ${msg}`)</script>
<script type="module">
// When using a dynamic import statement, the "then" export of the module
// will automatically be called, and ultimately resolve the API
(async () => {
try {
const { sayHi } = await import('./greeter.js');
log(sayHi('await import("greeter")'));
}
catch(e) {
log(e.stack);
throw e;
}
})();
</script>
</head>
<body>
<div id="console"></div>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Static Import</title>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script src="https://bl.ocks.org/mhofman/raw/fe170f9492196e9eb09907c84ea28999/html-console.js"></script>
<script src="https://unpkg.com/iframe-resizer@^4/js/iframeResizer.contentWindow.min.js" defer></script>
<script>const log = (msg) => htmlConsole.log(`${document.title}: ${msg}`)</script>
<script type="module">
// When using a static import statement, the import has to be manually hoisted
// to the top of the current module.
// The convention is that the default value of the module is a promise to the API
import greeterPromise from './greeter.js';
(async () => {
try {
const { sayHi } = await greeterPromise;
log(sayHi('await greeterPromise'));
}
catch(e) {
log(e.stack);
throw e;
}
})();
</script>
</head>
<body>
<div id="console"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment