升级到 Angular 10 后无法在 scss 中的 url() 中使用资源

问题描述 投票:0回答:3

我将 Angular 应用程序从 v9 升级到 v10。几乎一切都有效,但我在

url("assets/images/some/path/image.png")
中使用的所有图像都开始抛出异常 -

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

Angular 10 error of assets

我尝试了各种旧链接,但没有一个有效。

  1. https://github.com/angular/angular-cli/issues/12797
  2. https://github.com/angular/angular/issues/32811
angular
3个回答
72
投票

不太确定 Angular 10 中发生了什么变化?

但我找到了三种解决方案。我知道的第一个解决方案可以工作,但是在“现有”中型应用程序中实施需要时间。但如果您只有少数资产需要修复,则应该仅采用第一个解决方案。 解决方案1 - 使用相对资产路径(推荐)

解决方案是使用资产的相对路径(来自您的

.scss

文件)。基本上添加

../
直到到达
assets
文件夹。
:host {
    display: block;
    min-height: 500px;
    // Using relative path
    background: url('../../../assets/images/about-us.png') no-repeat center;
}

优点

    这种方法可以对静态资产进行哈希处理。一旦您的应用程序构建完成(使用
  1. ng build --prod

    ),您的资产 URL 将被替换为 MD5 哈希值以破坏缓存。

    所以你的网址

    background: url('../../../assets/images/about-us.png') no-repeat center;

    将被替换为

    background: url('about-us.add9979f32e1c969e6f8.png') no-repeat center;

    这基本上是图像内容的 MD5 校验和。所以基本上,当图像改变一个像素时,这个校验和就会被 Angular 改变。这可以帮助您在将来更改图像时突发缓存,同时保持文件名不变。

    阅读更多

    此处

    以获取知识。

  2. IDE(我使用IntelliJ IDEA)不会显示您的SCSS文件中资源的错误,这意味着如果文件路径错误,IDE会提前告诉您。
  3. IDE Errors Gone

  4. 您将获得目录链接。这意味着如果我按 Ctrl 并单击上面 URL 中的目录,IDE 将打开该目录。
  5. 缺点

  1. 可管理

    )这可能是一种麻烦的方法,因为开发人员必须编写需要与资产文件夹相关的资产。

  2. 可管理

    )散列资产(在本例中为图像)将被复制到构建中的根文件夹(默认情况下为dist)目录,这可能会使您的任何类型的 URL 规则(例如,缓存规则)失败)。所以而不是-

    https://example.com/assets/images/about-us.png
    

    将使用以下网址-

    https://example.com/about-us.add9979f32e1c969e6f8.png

  3. 可管理

    )如果更改组件的路径,则还必须更改图像 URL。

解决方案 2 - 快速修复

根据此处发布的答案

https://github.com/angular/angular-cli/issues/10004#issuecomment-375969537

,在 URL 前面添加 / 有效。

:host {
    display: block;
    min-height: 500px;
    background: url('/assets/images/about-us.png') no-repeat center;
}

优点

您不必添加许多
    ../
  1. 前缀即可使其成为相对 URL。
    如果更改组件 SCSS 文件的路径,则无需更改 
  2. url("")
  3. 中的资源路径。
    
    
  4. 缺点

    如果使用
  1. --base-href

    (如

    此处
    所述),则第二个解决方案将无法在生产版本中工作。 角度-cli#18043.

  2. 即使路径正确,您的 IDE 仍不断显示路径错误。
  3. IDE path error

  4. 您不会获得散列 URL 来破坏缓存(与解决方案 1 不同)
解决方案 3 - 欺骗 Angular CLI 处理器(不推荐)

我查看了 CLI 代码并发现,如果 URL 以

^

开头,Angular 会绕过该 URL 来忽略资产。

:host {
    display: block;
    min-height: 500px;
    background: url('^assets/images/about-us.png') no-repeat center;
}

源代码 - 
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

优点

    您不必添加许多
  1. ../

    前缀即可使其成为相对 URL。

    
    

  2. 如果更改组件 SCSS 文件的路径,则无需更改
  3. url("")

    中资源的路径。

    
    

  4. 缺点

正如一位 Angular CLI 开发人员在
    #18013(评论)中所述,该解决方案可能会在未来版本中被删除

11
投票
assets

文件夹位于

src
文件夹内,请尝试以下操作:
background: url("~src/assets/images/some/path/image.png")

此解决方案适用于 
base-href

    


0
投票
@btd1337

使用~src/assets的答案与

@shashank-agrawal
的解决方案1相同,但好处是不必处理相对路径。 无论如何,资产文件都被复制到两个解决方案中的根文件夹

如果您不想将这些资源文件复制到根文件夹,那么使用

@shashank-agrawal

的解决方案 3 应该可以实现

© www.soinside.com 2019 - 2024. All rights reserved.