Unable to use assets in url() in scss after upgrading to Angular 10

后端 未结 1 1826
长情又很酷
长情又很酷 2021-02-05 18:31

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 t

相关标签:
1条回答
  • 2021-02-05 19:17

    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.

    Solution 1 - Using relative assets path (Recommended)

    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;
    }
    

    Pros

    1. 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.

    2. 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.

    3. 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.

    Cons

    1. (Manageable) This might be a cumbersome approach as the developer has to write the asset which needs to be relative to the assets folder.

    2. (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
      
    3. (Manageable) If you change the path of your component, you have to change the image URL as well.


    Solution 2 - Quick Fix

    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;
    }
    

    Pros

    1. You do not have to add many ../ prefixes to make it a relative URL.
    2. If you change the path of your component SCSS file, you don't have to change the path of your assets in url("").

    Cons

    1. The second solution will not work in the production build if --base-href is used (as stated here). angular-cli#18043.

    2. Your IDE keeps showing the path error even if the path is correct.

    3. You do not get the hashed URLs to burst the cache (unlike solution 1)


    Solution 3 - Fooling the Angular CLI processor (not recommended)

    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

    Pros

    1. You do not have to add many ../ prefixes to make it a relative URL.

    2. If you change the path of your component SCSS file, you don't have to change the path of your assets in url("").

    Cons

    1. This solution might get removed in the future releases as stated by one of the Angular CLI developers in #18013 (comment)
    0 讨论(0)
提交回复
热议问题