-
-
Save yordis/68385bf8d6e6ea823191202b239884f0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"environment": "staging" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<script> | |
(async () => { | |
// The chunks required to get this application up and running in an | |
// isolated context. | |
const isolationChunks = [ | |
"main", // The bundle that initialises the application. | |
"remoteEntry" // This applications remoteEntry file. | |
]; | |
// The chunks that point to the `remoteEntry,js` files for the other | |
// federated modules associated with the applicationthat will create | |
// the graph in conjunction with the `isolatedChunks`. | |
const remoteChunks = [ | |
"appOne", | |
"appTwo", | |
"utilities" | |
]; | |
// References to the endpoints that we need to get the configuration files | |
// from to initialise the application again the current session. | |
const configChunks = [ | |
"http://example.com/location.config.json", // Global location config. | |
"../environment.config.json" // Per environment config. | |
]; | |
// Grab our configuration files in parallel. | |
const [location, { environment }] = await Promise.all( | |
configChunks.map(chunk => fetch(chunk).then(response => response.json())) | |
); | |
// Reference our configuration files against the global window so that | |
// our dynamic `publicPath` function can grab them when initialising our | |
// bundles. | |
window.__ENVIRONMENT__ = environment; | |
window.__LOCATION__ = location; | |
// Now that we have our configuration, lets get the javascript we need to | |
// initialise the application. We parallelise the requests to keep things | |
// speedy. | |
await Promise.all([ | |
// Fetch the `remoteEntry.js` files for our federated dependancies. | |
...remoteChunks | |
.map(chunk => { | |
const { href } = location[chunk][environment]; | |
return fetch(`${href}/remoteEntry.js`).then(response => response.text()); | |
}), | |
// Get files dedicated to running this micro front-end in isolation | |
// mode. | |
...isolationChunks | |
.map(chunk => fetch(`./${chunk}.js`) | |
.then(response => response.text()) | |
) | |
]) | |
.then(scripts => scripts.forEach(script => { | |
// Now that we have our scripts, let's inject them onto the page | |
// so that we can run out application initialisation sequence. | |
const element = document.createElement("script"); | |
element.text = script; | |
document.querySelector("body").appendChild(element); | |
})); | |
})(); | |
</script> | |
</head> | |
<body></body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"shell": { | |
"development": { | |
"href": "http://localhost:8000/" | |
}, | |
"staging": { | |
"href": "http://staging.shell.example.com/" | |
}, | |
"production": { | |
"href": "http://prod.shell.example.com/" | |
} | |
}, | |
"appOne": { | |
"development": { | |
"href": "http://localhost:8001/" | |
}, | |
"staging": { | |
"href": "http://staging.app-one.example.com/" | |
}, | |
"production": { | |
"href": "http://prod.app-one.example.com/" | |
} | |
}, | |
"appTwo": { | |
"development": { | |
"href": "http://localhost:8002/" | |
}, | |
"staging": { | |
"href": "http://staging.app-two.example.com/" | |
}, | |
"production": { | |
"href": "http://prod.app-two.example.com/" | |
} | |
}, | |
"utilities": { | |
"development": { | |
"href": "http://localhost:8003/" | |
}, | |
"staging": { | |
"href": "http://staging.utilities.example.com/" | |
}, | |
"production": { | |
"href": "http://prod.utilities.example.com/" | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
/** | |
* Allows static builds to change their `publicName` dynamically at run time rather | |
* than build time. This allows builds to be environment agnostic, where we can | |
* change from Staging, UAT, to Production with the same artefact and have the | |
* `publicName` update accordingly via some run time configuration. | |
* @class | |
*/ | |
class DynamicPublicPathPlugin { | |
/** | |
* The Webpack hook to apply our plugin. | |
* @parem {Object} compiler - The Webpack compiler. | |
*/ | |
apply(compiler) { | |
compiler.hooks.make.tap("MutateRuntime", (compilation) => { | |
compilation.hooks.runtimeModule.tap("MutateRuntime", (module, chunk) => { | |
const isPublicPathRuntimeModule = module.constructor.name === "PublicPathRuntimeModule"; | |
if (!isPublicPathRuntimeModule) { return; } | |
console.log(`* Update "${chunk.name}" dynamic public path`); | |
// We extract the variable "key" (the namespace to left of the equals sign) | |
// and leave the rest behind as we are going to build our own new value | |
// and assign it back to the variable. | |
const [key] = module.getGeneratedCode().split("="); | |
// Swap out the old static string value for a function that will run in | |
// the browser session and create a public path based on the current | |
// configuration. | |
// | |
// We create the `publicPath` from the "environment.config.json" and | |
// "location.config.json" configuration files that are saved as global | |
// variables in the browser `__ENVIRONEMENT__` and `__LOCATION__`. | |
module._cachedGeneratedCode = `${key}=(function() { | |
const { __LOCATION__, __ENVIRONEMENT__ } = window; | |
const { href } = __LOCATION__.shell[__ENVIRONEMENT__]; | |
const publicPath = href + "/"; | |
return publicPath; | |
})();` | |
return module; | |
}); | |
}); | |
} | |
} | |
... | |
module.exports = async (_, args) => { | |
... | |
return { | |
... | |
plugins: [ | |
new ModuleFederationPlugin({ | |
... | |
}), | |
new DynamicPublicPathPlugin(), | |
... | |
] | |
... | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment