【问题标题】:Unable to use assets in url() in scss after upgrading to Angular 10升级到 Angular 10 后无法在 scss 中使用 url() 中的资产
【发布时间】:2021-06-05 07:47:57
【问题描述】:

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

我尝试了各种旧链接,但都没有成功。

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

【问题讨论】:

    标签: angular


    【解决方案1】:

    不确定 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 改变。这有助于您在将来更改图像时突发缓存,同时保持文件名相同。

      阅读更多here 以获取知识。

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

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

    缺点

    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。
    2. 如果更改组件 SCSS 文件的路径,则无需更改 url("") 中资产的路径。

    缺点

    1. 如果使用--base-href(如here 所述),则第二个解决方案在生产版本中将不起作用。 angular-cli#18043.

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

    3. 您不会获得散列 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 文件的路径,则无需更改 url("") 中的资产路径。

    缺点

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

    【讨论】:

    • 嗨。一个问题。您确定第一个解决方案在编译后会起作用吗?因为在ng build 之后,文件夹的结构会发生变化。谢谢你的第二个解决方案我不知道我一直使用第三个解决方案。
    • 是的@AshotAleqsanyan 所有解决方案都适用于ng build --prod。即使是第一个解决方案也有好处。我将在答案中更新相同的内容。
    • 如果我们希望背景 url 根据语言之类的东西改变怎么办?background: url('../../../assets/en/images/common-bg.png')无重复中心;或背景: url('../../../assets/fr/images/common-bg.png') 无重复中心;另外,我们想让路径成为一个 scss 变量;因为我们希望不同的组件引用同一个文件。但是不同的组件可能在不同的文件夹级别,所以从组件 scss 到 common-bg.png 的相对路径会有所不同。有什么建议吗?
    • 不,我的意思是您的帖子帮助了很多,我对此表示感谢 - 必须努力在所有 scss 文件中修复此类问题似乎微不足道。我记得不久前我在另一个 Angular 升级中遇到了类似的问题,我必须通过 angular.json 文件中的 stylePreprocessorOptions 选项指定一个位置,这解决了我当时的问题 link for reference。但是现在,由于某种原因,它甚至不再起作用了。
    • 明白你的意思@JohanAspeling。我很高兴它对你有所帮助。看了你之前的参考资料,谢谢分享。
    【解决方案2】:

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

    background: url("~src/assets/images/some/path/image.png")
    

    此解决方案适用于base-href

    【讨论】:

    • ng build 将图像从资产复制到根文件夹
    猜你喜欢
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 2020-12-06
    • 1970-01-01
    • 2017-06-09
    • 2020-12-04
    • 2017-04-09
    相关资源
    最近更新 更多