Description
First of all, my project has multiple localizations defined in angular.json, so when running
ng build --configuration=production --localize
there are 3 subdirectories created in dist
output path. Each of them has different base href in their index.html file.
Second, in angular.json I have assets subsection defined like:
"assets": [
"src/favicon.ico",
"src/assets"
],
and in assets/images there are these image files (among others):
- bg_login_compressed.jpg (blured version of image, small size)
- bg_login.jpg (full version of image, large size)
Then I have a component in some nested directory within the project, that is using following css classes:
.background-init {
background-image: url("/assets/images/bg_login_compressed.jpg");
}
.background-loaded {
background-image: url("/assets/images/bg_login.jpg");
}
As you can see, I am using root path to assets folder (starting with '/'), which is obviously wrong for base href that is not '/'.
My goal is to have div initialized with blured version of image, which is later replaced by full version. This is how I am doing it:
Template:
<div [class.background-init]="!backgroundIsLoaded" [class.background-loaded]="backgroundIsLoaded">
Typescript:
public backgroundIsLoaded = false;
ngOnInit() {
const img = new Image();
img.src = './assets/images/bg_login.jpg';
img.onload = () => {
this.backgroundIsLoaded= true;
};
}
This is ok during local development when running ng serve
without base href parameter:
- .css images are found
- .ts image is found and loaded
- both .css and .ts bg_login.jpg file is searched in the same path (= refer to the same file)
If I run ng serve --base-href /de/
, which simulates run from production environment on IIS:
- .css images are not found (they are searched in path '/assets/images/' instead of '/de/assets/images/')
- .ts image is found and loaded
- as a result, no images are shown as the background
Ok: let's switch to relative paths in .css url path, as advised in #4778 (comment):
.background-init {
background-image: url("../../../assets/images/bg_login_compressed.jpg");
}
.background-loaded {
background-image: url("../../../assets/images/bg_login.jpg");
}
On local development without base href it is working fine, as well as with --base-href /de/.
BUT what this causes when building? The files used in relative paths are copied from /assets/images/ to root directory of each localized build. This is unwanted and inpractical for many reasons described e.g. here: #14587 (comment) !!!
Side effect of this solution is:
- .css image bg_login.jpg is searched in root path (of the build)
- .ts image bg_login.jpg is searched in /assets/images/ path
- that's why the code for replacing the background images will not work as desired (the image is loaded twice instead of once on the same path)
Other solutions that I tried:
- using of rebaseRootRelativeCssUrls: not working on production and considered deprecated
- using tilde in the .css path, such as url('~/assets/images/bg_login.jpg'): not working on production
- using caret in the .css path, such as url('^assets/images/bg_login.jpg'): not working on production and officially not supported (Can't use relative paths in url() in scss files #12797 (comment))
I am searching for a clean solution which:
- finds the images in the paths
- doesn't copy the images when using relative css paths
- is able to link to the same file when loading both from css and from ts
- works on local and on production environment
Unfortunately, many of similar issues here on git are already locked due to inactivity, that's why I am creating this new one.
🌍 Your Environment
Angular CLI: 9.0.6
Node: 12.16.0
OS: win32 x64
Angular: 9.0.6
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes
Package Version
------------------------------------------------------------
@angular-devkit/architect 0.900.6
@angular-devkit/build-angular 0.900.6
@angular-devkit/build-ng-packagr 0.900.6
@angular-devkit/build-optimizer 0.900.6
@angular-devkit/build-webpack 0.900.6
@angular-devkit/core 9.0.6
@angular-devkit/schematics 9.0.6
@angular/cdk 9.1.3
@ngtools/webpack 9.0.6
@schematics/angular 9.0.6
@schematics/update 0.900.6
ng-packagr 9.0.3
rxjs 6.5.4
typescript 3.7.5
webpack 4.41.2