-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Images used by remotes not found in the shell #21
Comments
having the same issue - tried this fix suggested here: module-federation/module-federation-examples#697 but we do not have a shared assets library - we would like to have a solution just for displaying static images from the remote app within the remote app. |
I having the same issue any solution @manfredsteyer |
How about this. document.currentScript?.getAttribute('src') which return something like: http://localhost:5001/src_bootstrap_ts.js. You would need to parse the results to only get the host and port. Then prefix your images with the result. |
I'm also having this same issue, but in my case, the image's URL is defined in CSS using background: url("..."), how can be fixed this case? |
I found a few solutions for this problem. First we need to understand the main issue: let's say the shell app is running on localhost:3000, and the remote app is running on localhost:3001. In the remote app you can use images in two ways:
When you deploy the remote app and run it directly (on localhost:3001) it will correctly resolve both links to image to url localhost:3001/assets/image.png, and image will show. But when you load the remote app in the shell app (on localhost:3000), the shell app will inject the remote html and css code inside the host DOM, and all links will be resolved relatively to the shell app url, which means on localhost:3000/assets/image.png (where the image does not exist. The solution is we have to modify the remote app code to output absolute url to images:
If you know URL where the remote app will be deployed in advance, the easiest solution is to set
With this option angular compiler will automatically convert all relative links to absolute (=all links to images in compiled HTML and CSS code will start with http://localhost:3001). When the remote app is loaded inside the shell app the images will be loaded from the correct locations. This is not a good solution when we need to build a project that can be deployable on any server, because this compiled code has absolute URLs hard coded and can only be deployed on the particular server. Another dissadvantage is if our remote app uses a lot of images, because hard-coded absolute links will make html/css files larger. Maybe in that case we can optimize the deployment process and deploy all the remote app assets to the shell server, so relative links will still work. I think currently the most elegant solution to make the remote app deployable anywhere (not having to set the deployment url in advance) is to use dynamic link resolvement in our HTML and CSS code. For that a special global javascript variable So, we can dynamically resolve absolute links to images in our remote app like this: Angular component TS file:
Angular component HTML template:
If we have images inside our CSS files the solution is quite more tricky. Angular is possible to dynamically inject variables in CSS at run-time using @HostBinding decorator, but is not very convenient solution especially for injecting URL's for images: Angular component TS file that will dynamicall handle it's CSS file:
CSS file:
Disadvantage of this solution is that we must declare CSS variable for every different image we want to inject in the CSS. It would be much easier if we could just declare a base url path variable in TS file, and in CSS to append it to our image filename, like: If you use many images in CSS files there is also a more elegant solution: put all styles that use images in your "global-remote" CSS file, where you can use relative links to images. When you deploy your remote app, browser will load the globa-remote CSS from http://localhost:3001/global-remote.css, and browser will automatically resolve all relative links relatively to localhost:3001. But for this to work you cannot use "scoped" CSS files from angular (=CSS files that are attached to angular component), because scoped CSS styles are compiled in JS code together with the component and are dynamically injected at-runtime to html DOM, so relative links to image will be resolved relatively to the shell app localhost:3000, not to the remote app). You have to compile this kind of CSS file separately, and include in your remote app separately: To compile "remote-global" CSS separately, configure it in angular.json:
Include this CSS in our remote app main App component (app.component.html):
Make sure also [rel] attribute is in brackets otherwise angular compiler will try to resolve href in compile-time and will throw syntax error. Compiler must ignore this tag that must be resolved at run-time. In app.component.ts define assetUrl variable that will resolve to absolute url of deployed remote app, like mentioned before:
|
@jure123 I tried all of the options you suggested, but unfortunately, nothing worked for me. |
@gleisonkz, I'm using all those options in my project, and they are working well. Unfortunately I cannot share the project. If you wrote more details what and how is not working I may be able to help you. |
jure123's soltion did work for me. but I had to do something more: as webpack_public_path was not defined in typescript I had to do first install webpack types:
and add types to the tsconfig.app.json:
after that I could reference images like this in the remotes html: |
What is the best solution. I am a same problem |
I'm running into the same issue but using React. Did somebody have had this same issue? |
Since I use proxies to eliminate the need for cors + relative remote path you can prefix all the relative URLs. But that is quite tedious and will be hard to maintain/communicate to all the developers.
Where But autoprefixing all relative URLs would be even better, but can't find anything that would work for http or CSS calls with both prod builds and ng serve. |
Hi Team, |
Same issue here, can't seem to find a good solution for non-monorepo implementations. |
It works fine - you just have to have a proxy on the shell that points to remote asset dir. A proxy on your shell would catch any requests to The annoying part is that you do need to hardcode that prefix everywhere in css/html. No good way to autoprefix there. |
@Ketec Yup, that is the solution I went with. I just moved my assets to a specific folder in the remote and referenced them through that folder then any call to that folder in the host I added a proxy for to point to the remote. |
I came up with this solution. We take a proxy (nginx+devServer):
As a result, any MFE will receive its assemblies from the shell on the relative path, for example '/assets/my-awesome-mfe/logo.png' will receive the file |
I have done your solution. but it work only on developMode when i want to publish my project on server let say IIS proxy config does not work. do you have any solution for product mode ? |
This solution also works on a remote server. I don't know about IIS, but it works with nginx. See point 1, I gave an example of a config there. |
This worked for me: https://stackoverflow.com/a/34583854/1623533 |
As a workaround, I fixed this issue by moving the asset images to the public folder in both the Remote and Shell apps. Now, both apps have the same assets under the public folder, which resolves the issue both in the cluster and locally (for independently running apps). |
I got the same problem with vite + react-ts. For now, I also had to solve it this way, but it is not optimal because the host should have the images of all the clients. |
Hi Manfred,
in your example I can't load images belonging to the remote app from the shell.
Your specific case works because the angular.png image exist also in the shell app and is that one that is downloaded and used by the app.
I've tried to substitute the image with anoter one that exist in the remote app only and the result is this one below.
It try to reach the image on the host app, but it doesn't exist there. If the remote app it' s run as standalone everything it's ok
How can be fixed? (without using absolute path for all the images used in the remotes)
Thank you!
The text was updated successfully, but these errors were encountered: