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

Sha*_*wal 24 angular

我将我的 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 | }
Run Code Online (Sandbox Code Playgroud)

资产的 Angular 10 错误

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

  1. https://github.com/angular/angular-cli/issues/12797
  2. https://github.com/angular/angular/issues/32811

Sha*_*wal 47

不确定 Angular 10 有什么变化?

但我找到了三个解决方案。我知道的第一个解决方案是可行的,但在现有的中型应用程序中实施需要时间。但是,如果您只有少数资产需要修复,那么您应该只选择第一个解决方案。

解决方案 1 - 使用相对资产路径(推荐)

解决方案是使用.scss资产的相对路径(来自您的文件)。基本上添加../直到到达assets文件夹。

:host {
    display: block;
    min-height: 500px;
    // Using relative path
    background: url('../../../assets/images/about-us.png') no-repeat center;
}
Run Code Online (Sandbox Code Playgroud)

优点

  1. 这种方法可以对静态资产进行散列。一旦您的应用程序构建(使用ng build --prod),您的资产 URL 将被替换为 MD5 哈希值以突增缓存。

    所以你的网址

    background: url('../../../assets/images/about-us.png') no-repeat center;
    
    Run Code Online (Sandbox Code Playgroud)

    将被替换为

    background: url('about-us.add9979f32e1c969e6f8.png') no-repeat center;
    
    Run Code Online (Sandbox Code Playgroud)

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

    在这里阅读更多知识。

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

    IDE 错误消失

  3. 你得到目录链接。这意味着如果我按 Ctrl 并单击上面 URL 中的目录,IDE 将打开该目录。

缺点

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

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

    https://example.com/assets/images/about-us.png
    
    Run Code Online (Sandbox Code Playgroud)

    将使用以下 URL-

    https://example.com/about-us.add9979f32e1c969e6f8.png
    
    Run Code Online (Sandbox Code Playgroud)
  3. (可管理) 如果您更改组件的路径,您也必须更改图像 URL。


解决方案 2 - 快速修复

根据此处发布的答案https://github.com/angular/angular-cli/issues/10004#issuecomment-375969537/在 URL 前面添加有效。

https://example.com/assets/images/about-us.png
Run Code Online (Sandbox Code Playgroud)

优点

  1. 你不必添加很多 ../前缀来使其成为相对 URL。
  2. 如果您更改组件 SCSS 文件的路径,则不必更改url("").

缺点

  1. 如果第二个解决方案将不会在生产构建工作--base-href使用(如说明这里)。角度cli#18043

  2. 即使路径正确,您的 IDE 也会不断显示路径错误。

    IDE路径错误

  3. 你没有得到散列的 URL 来破坏缓存(与解决方案 1 不同)


解决方案 3 - 欺骗 Angular CLI 处理器(不推荐)

我查看了 CLI 代码并发现如果 URL 以 开头^,Angular 会绕过 URL 来忽略资产。

https://example.com/about-us.add9979f32e1c969e6f8.png
Run Code Online (Sandbox Code Playgroud)

源代码- 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 文件的路径,则不必更改url("").

缺点

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


btd*_*337 11

如果您的assets文件夹位于src文件夹内,请尝试以下操作:

background: url("~src/assets/images/some/path/image.png")
Run Code Online (Sandbox Code Playgroud)

该解决方案将与base-href