angular/angular-cli

Angular CLI 16+ generates config that fails to inline stylesheet from typekit/Adobe

CITguy opened this issue · 8 comments

Command

build, new

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

v15

Description

I'm unable to get an Adobe/typekit CSS stylesheet to embed using an esbuild-based builder configuration.

The only way to get it to work with esbuild is to disable font optimization via projects.PROJECT_NAME.architect.build.configurations.production.optimization.fonts = false in angular.json. Otherwise, I have to revert back to the browser builder.

For now, I'm using the stable browser Webpack builder, so that I don't have to muck around with updating configs that may need to be reverted later when we eventually switch to esbuild. However, the esbuild scripts provide no useful console output or advanced logging to explain WHY it fails, so I have no way to troubleshoot the exact issue.

Please advise.

Minimal Reproduction

Given that the build script doesn't provide enough detailed information, I can't reliably determine if the issue resides in the build script itself or if it is a result of being behind our corporate firewall/vpn.

That being said, here's how I was able to reproduce the issue.

  1. Generate a fresh Angular 16 or 17 app using angular CLI
    • CLI v16+ seems to default to the application build script
  2. npm install
  3. Check that the production builder is using an esbuild-based script (either application or browser-esbuild)
  4. add an Adobe/typekit css import to your src/styles.scss
  5. npm run build

FYI: This seems to only be an issue with builders using esbuild. The webpack-based browser script still works fine, but doesn't actually inline the CSS file; it just passes through the CSS @import, verbatim.

Exception or Error

Failed to inline external stylesheet

$ npm run build -- --verbose

> ngapp17@0.0.0 build
> ng build --verbose

⠋ Building...

  polyfills-S3BTP7ME.js  33.2kb

⠏ Building...

  main-LRVPNULS.js  193.2kb

Application bundle generation failed. [2.388 seconds]

✘ [ERROR] Failed to inline external stylesheet 'https://use.typekit.net/q*****m.css'. [plugin angular-css-inline-fonts-plugin]

    src/styles.scss:2:12:
      2 │ @import url("https://use.typekit.net/q*****m.css");
        ╵             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Your Environment

Angular CLI: 17.3.7
Node: 18.14.0
Package Manager: npm 9.6.7
OS: darwin arm64

Angular: 17.3.8
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1703.7
@angular-devkit/build-angular   17.3.7
@angular-devkit/core            17.3.7
@angular-devkit/schematics      17.3.7
@angular/cli                    17.3.7
@schematics/angular             17.3.7
rxjs                            7.8.1
typescript                      5.4.5
zone.js                         0.14.5

Anything else relevant?

I've seen old support questions that mention that a VPN may potentially cause problems, but I've not had the chance to verify on a machine without a VPN running.

@CITguy, I am unable to replicate this problem. Can you please share a reproduction?

It seems our corporate VPN is at fault, somehow. I tested on another machine that's not behind our corporate VPN and it's working fine. Unfortunately, due to the lack of information in the error output, I still don't know how to figure out exactly why things are breaking.

Any ideas how I might be able to get better debugging data from the failure?

You can attempt to implement the modification provided in this link locally: https://github.com/angular/angular-cli/pull/27641/files. This should help reveal more information.

Seems the cause is unable to get local issuer certificate, which is strange given that I can load the URL for the CSS file in my browser with no cert issues.

I wonder if the plugin should fail gracefully in the event that optimization can't succeed.

In my mind, the inlining optimization should be a "best effort", so that even if the plugin can't successfully inline styles from a CSS @import it should leave the import as-authored and potentially display a warning message in the CLI output. Worst case scenario is that an import URL is incorrect or unreachable; the browser already knows how to handle this scenario without preventing the rest of the CSS from being loaded/parsed, so why not leave it as-authored?

If the webpack optimization is attempting to do the same as the esbuild plugin (inlining the file), it seems to be leave the import as-is (though without a warning message), instead of raising a critical error (i.e., it fails gracefully).

In webpack, global stylesheets don't support font inlining; it only occurs in the index file.

This case warrants more than just a warning. If the build runs in a CI environments warnings can be overlooked. Additionally, in CI/CD pipelines,a warning can result in deploying an unoptimized version of the app, negatively impacting Core Web Vitals (CWV).

Seems the cause is unable to get local issuer certificate, which is strange given that I can load the URL for the CSS file in my browser with no cert issues.

Thus usually means that the SSL certificate authority (CA) that issued the certificate is not recognized by your system.

nodejs/help#979