I upgraded my Angular application from v9 to v10. Almost everything worked but all my images used in url("assets/images/some/path/image.png")
started to throw the exception-
ERROR in ./src/app/pages/about-us/about-us.component.scss Module Error (from ./node_modules/postcss-loader/src/index.js): (Emitted value instead of an instance of Error) CssSyntaxError: /Users/shashank/Projects/curika/temp-ssr/src/app/pages/about-us/about-us.component.scss:4:20: Can't resolve './assets/images/about-us.png' in '/Users/shashank/Projects/curika/temp-ssr/src/app/pages/about-us' 2 | display: block; 3 | min-height: 500px; > 4 | background: url("./assets/images/about-us.png") no-repeat center; | ^ 5 | }
I tried various old links but none worked.
With the help of Angular CLI, you can install CSS or SCSS on your project and start working on that in a suitable way. If you are working with the CSS or SCSS in your angular project then it is very easy for you as compared to most other frameworks.
The application renders fine with a mix of css and scss files. I assume this styleExt parameter is just there for the default component style ( css, scss, less ) file generation when adding components via angular-cli commands.
Not really sure what's changed in Angular 10?
But I found three solutions. The first solution I knew will work but that's time taking to implement in an existing mid-size application. But if you have only a few assets to fix, you should go for the first solution only.
The solution is to use the relative path (from your .scss
file) of your assets. Basically adding ../
until the assets
folder is reached.
:host { display: block; min-height: 500px; // Using relative path background: url('../../../assets/images/about-us.png') no-repeat center; }
This approach enables the hashing of your static assets. Once your application is built (using ng build --prod
), your asset URL will be replaced with an MD5 hash to burst the caching.
So your URL
background: url('../../../assets/images/about-us.png') no-repeat center;
will be replaced as
background: url('about-us.add9979f32e1c969e6f8.png') no-repeat center;
This is basically an MD5 checksum of the content of the image. So basically, when the image changes even by one pixel, this checksum will be changed by Angular. This helps you to burst caching in future when you change your image while keeping the file name the same.
Read more here for knowledge.
IDE (I use IntelliJ IDEA) does not show errors of the assets in your SCSS files that means if the file path is wrong, IDE will tell you in advance.
You get the directory linking. That means if I press Ctrl & click on a directory in the URL above, IDE will open up that directory.
(Manageable) This might be a cumbersome approach as the developer has to write the asset which needs to be relative to the assets folder.
(Manageable) The hashed asset (image in this case) will be copied to the root folder in the build (i.e. dist
by default) directory which might fail your any kind of URL rules (for example, caching rules). So instead of-
https://example.com/assets/images/about-us.png
the following URL will be used-
https://example.com/about-us.add9979f32e1c969e6f8.png
(Manageable) If you change the path of your component, you have to change the image URL as well.
Based on the answer posted here https://github.com/angular/angular-cli/issues/10004#issuecomment-375969537, adding /
in front of the URL worked.
:host { display: block; min-height: 500px; background: url('/assets/images/about-us.png') no-repeat center; }
../
prefixes to make it a relative URL.url("")
.The second solution will not work in the production build if --base-href
is used (as stated here). angular-cli#18043.
Your IDE keeps showing the path error even if the path is correct.
You do not get the hashed URLs to burst the cache (unlike solution 1)
I looked into the CLI code & figured out that if a URL starts with ^
, Angular ignores the asset by bypassing the URL.
:host { display: block; min-height: 500px; background: url('^assets/images/about-us.png') no-repeat center; }
Source code- https://github.com/angular/angular-cli/blob/v10.0.0/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/postcss-cli-resources.ts#L72
You do not have to add many ../
prefixes to make it a relative URL.
If you change the path of your component SCSS file, you don't have to change the path of your assets in url("")
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With