Kichrum
Kichrum

Reputation: 607

How to host assets with Module Federation on Angular and Nx monorepo

I need to make assets (png, svg images, fonts) from Angular remote applications available also in host applications of Webpack Module Federation.

Below are long steps to reproduce - not necessary to read if you know the solution :)


Preconditions:

Expected result:

on http://localhost:4200 (host) and http://localhost:4201/ (remote) we have 4 images visible. When building the apps (npm run build), both apps have assets (can be hosted on CDN).

login app host app

I've tried to play with package.json, webpack.config.json - didn't help (maybe did sth wrong).

For now, I have a solution: host all the assets somewhere on separate CDNs, write absolute URLs in the source code, but then I have to keep CDN and code in sync - doesn't look like a long-term solution.

UPD: Avoiding relative path usage in CSS "fixes" the problem: url('^assets/img.png') or url('/assets/img.png'). Dev and prod build work good, but the solution isn't perfect, because:

  1. IDE underlines such paths as invalid (can't find /assets in project root) - moving /assets folder to the same level as apps/ fixes it;
  2. Filenames are not extended with hashcode for better caching;
  3. Nx and Angular 13 CLI caching mechanism sometimes "forgets" to update assets, so on build w/o flag --skip-nx-cache I miss new assets.

All three points are manageable, but they are "symptoms" of tech debt, so I hope community has better solution, at least without symlinks.

Upvotes: 3

Views: 6647

Answers (4)

Ketan Panchal
Ketan Panchal

Reputation: 230

I was facing the similar issue after deployment of shell and remote apps. In local we can run remote apps separately and was okay in local with the images issues. As our shell was hosting multiple remote apps from different teams and had different repos altogether.

I found a solution which worked for me.

Hosting environment - nginx

steps

  1. Rename the assets folder with custom assets relative to remote e.g. {remoteapp}-assets and add it in angular.json to include those assets.
  2. Change the paths of application image and static files references with new assets folder.
  3. In shell -> app.conf add //it will identify the part of the request url is of remote assets

location ~ /{remoteapp}-assets/{
rewrite ^(.*) ${remotehost}$1;

//${remotehost} or $remotehost environment variable which a environment specific url of remote host }

The similar redirect/ rewrite rules are there for .net/ apache webserver as well.

Upvotes: 0

Markiewic
Markiewic

Reputation: 176

We have a variable __webpack_public_path__ from the webpack, which in runtime has the address from where the remote module was loaded. I described the solution in more detail here: https://github.com/module-federation/module-federation-examples/issues/697#issuecomment-1728421106

Upvotes: 0

ermaneng
ermaneng

Reputation: 21

you can use proxy to solve this issue as well.

create a proxy.conf in host application and redirect asset call to desired remote applications

{
    "/assets/remote":{
       "target": "http://localhost:4201",
       "secure": false 
    }
}

for more info

Upvotes: 1

Nikolay Stepin
Nikolay Stepin

Reputation: 108

you can store your assets in login app: apps/login/src/assets. Then in project.json of dashboard app add to build configuration next lines:

"assets": [
  ...,
  {
    "glob": "**/*",
    "input": "apps/login/src/assets",
    "output": "assets"
  }
],

Upvotes: 0

Related Questions