{"id":2562,"date":"2021-02-25T12:23:24","date_gmt":"2021-02-25T12:23:24","guid":{"rendered":"https:\/\/salientsoft.co.uk\/?p=2562"},"modified":"2021-02-25T12:23:24","modified_gmt":"2021-02-25T12:23:24","slug":"angular-11-remote-loading-of-angular-element-from-separately-deployed-webpack-bundle","status":"publish","type":"post","link":"https:\/\/salientsoft.co.uk\/?p=2562","title":{"rendered":"Angular 11 &#8211; remote loading of Angular Element from separately deployed webpack bundle"},"content":{"rendered":"\n<p>This follows on from my original post <a href=\"https:\/\/salientsoft.co.uk\/?p=2323\"><strong>here<\/strong> <\/a>for Angular 6.<\/p>\n<p>In Angular 11, the up-and-coming approach to this is to use Module Federation for remote loading of microapps\/micro-frontends. Manfred Steyer has a new article series on this whole approach <a href=\"https:\/\/www.angulararchitects.io\/aktuelles\/multi-framework-and-version-micro-frontends-with-module-federation-the-good-the-bad-the-ugly\/\"><strong>here<\/strong><\/a>, and the second article about using Angular for this may be found <a href=\"https:\/\/www.angulararchitects.io\/aktuelles\/the-microfrontend-revolution-part-2-module-federation-with-angular\/\"><strong>here<\/strong><\/a>.<\/p>\n<p>My issue with module federation at present is that it is still appears too nascent to simply &#8216;just work as standard&#8217; with angular &#8211; the above posts need a number of workarounds including the use of yarn, and I was unwilling to switch to this method just for my present requirement which is just the generation of simple proof of concept work.<\/p>\n<p><span style=\"font-size: inherit;\">At present, I am therefore continuing to use <\/span><a style=\"font-size: inherit;\" href=\"https:\/\/salientsoft.co.uk\/?p=2323\"><strong>my original approach as above<\/strong><\/a><span style=\"font-size: inherit;\"> for my POC work, as it still works with Angular 11. I have tweaked the approach a little to allow performing production builds, by disabling the hashes added to the filenames (I already use my own alternative method for cache busting\/cache avoidance using a query string parameter). Details are shown below.<\/span><\/p>\n<p><strong>package.json scripts section<\/strong><\/p>\n<blockquote>\n<pre>{<br \/>  \"name\": \"microapp-fabric-prototype\",<br \/>  \"version\": \"0.0.0\",<br \/>  \"scripts\": {<br \/>    \"ng\": \"ng\",<br \/>    \"start\": \"ng serve\",<br \/>    \"prebuild\": \"npm run scss\",<br \/>    \"build\": \"ng build\",<br \/>    \"postbuild\": \"node post-build.js\",<br \/>    \"test\": \"ng test\",<br \/>    \"lint\": \"ng lint\",<br \/>    \"e2e\": \"ng e2e\",<br \/>    \"scss\": \"npm run scss1\",<br \/>    \"scss1\": \"cd src\/assets\/resources\/themes\/salient-v11-violet &amp;&amp; sass theme.scss:theme.css --source-map .\",<br \/>    \"prebuildProd\": \"npm run scss\",<br \/>    \"buildProd\": \"ng build --prod --output-hashing none\",<br \/>    \"postbuildProd\": \"node post-build-prod.js\"<br \/>  },<\/pre>\n<\/blockquote>\n<p><strong>post-build.js<\/strong><\/p>\n<blockquote>\n<pre>\/* Do post build actions on the webpack bundle.<br \/> * Rename the webpack jsonp objects throughout, to prevent invalid multiple bootstraps due to name collisions<br \/> * This is due to an angular bug - see here: https:\/\/github.com\/angular\/angular\/issues\/23732<br \/> * This script requires the npm replace package: https:\/\/www.npmjs.com\/package\/replace<br \/> * To install use: \"npm install replace -g\" *\/<br \/><br \/>var replace = require(\"replace\");<br \/><br \/>doWebpackReplace('MicroappFabric','microapp-fabric-prototype',<br \/> ['main.js', 'polyfills.js', 'runtime.js', 'vendor.js']);<br \/><br \/>function doWebpackReplace(name, filename, paths) {<br \/> replace({<br \/>   regex: '\\\\[\"webpackJsonp\"\\\\]',<br \/>   replacement: `[\"webpackJsonp${name}\"]`,<br \/>   paths: paths.map((p) =&gt; `dist\\\\${filename}\\\\${p}`),<br \/>   recursive: false,<br \/>   silent: false,<br \/> });<br \/>}<\/pre>\n<\/blockquote>\n<p><strong>post-build-prod.js<\/strong><\/p>\n<blockquote>\n<pre>\/* Do post production build actions on the webpack bundle.<br \/> * Rename the webpack jsonp objects throughout, to prevent invalid multiple bootstraps due to name collisions<br \/> * This is due to an angular bug - see here: https:\/\/github.com\/angular\/angular\/issues\/23732<br \/> * This script requires the npm replace package: https:\/\/www.npmjs.com\/package\/replace<br \/> * To install use: \"npm install replace -g\" *\/<br \/><br \/>var replace = require(\"replace\");<br \/><br \/>doWebpackReplace('MicroappFabric','microapp-fabric-prototype',<br \/> ['main.js', 'polyfills.js', 'runtime.js']);<br \/><br \/>function doWebpackReplace(name, filename, paths) {<br \/> replace({<br \/>   regex: 'window\\\\.webpackJsonp',<br \/>   replacement: `window.webpackJsonp${name}`,<br \/>   paths: paths.map((p) =&gt; `dist\\\\${filename}\\\\${p}`),<br \/>   recursive: false,<br \/>   silent: false,<br \/> });<br \/>}<\/pre>\n<\/blockquote>\n<p>At present, I will continue to monitor the situation with Module Federation, and will likely switch to using it when it really is working &#8216;out of the box&#8217; with no tweaks or complications.<\/p>\n<p>\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This follows on from my original post here for Angular 6. In Angular 11, the up-and-coming approach to this is to use Module Federation for remote loading of microapps\/micro-frontends. Manfred Steyer has a new article series on this whole approach here, and the second article about using Angular for this may be found here. My [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[198,1,77,223],"tags":[],"_links":{"self":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2562"}],"collection":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2562"}],"version-history":[{"count":8,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2562\/revisions"}],"predecessor-version":[{"id":2570,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/2562\/revisions\/2570"}],"wp:attachment":[{"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2562"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2562"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salientsoft.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2562"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}