Relative media path resolution for url(), when using a SCSS mixin, requires a path relative to mixin file #29412
Labels
angular/build:application
area: @angular/build
freq1: low
Only reported by a handful of users who observe it rarely
severity5: regression
type: bug/fix
Command
build
Is this a regression?
The previous version in which this bug was not present was
17
Description
I apologize if this might not be considered a bug, but rather a future improvement. I opted for a bug because the behavior has changed since v17, and I couldn't find any mentions of intentional change, which is not to say there might have been.
The issue is specific to the new
@angular-devkit/build-angular:application
builder, and a change that seems to have occurred with Angular v18, and is still present in v19.The issue being that the resolution behavior for relatively referenced media files (resource), used with url(), when calling SCSS mixins, seems to have changed. I'm talking about the rebasing, fingerprinting and copying of image files to the output folder, when building an application.
Previously, using v17 and the new
@angular-devkit/build-angular:application
builder, as well as the webpack based builder in prior versions, the relative path to the media file had to be relative to the SCSS in which it was "declared", even when passing the path to SCSS mixin in another location, should that mixin end up being the one that contains the CSS url() declaration.E.g., having a simple mixin such as the one below
Would require that it's called with a relative path based on the calling file, regardless of the mixin location.
Using such a mixin inside application and/or component stylesheet would require the relative path to written based on that file's location, and not the location of the mixin. E.g.:
Such resolution behavior is still present when using the old, webpack based
@angular-devkit/build-angular:browser
, as well as when creating libraries using the@angular-devkit/build-angular:ng-packagr
builder. It worked using the new@angular-devkit/build-angular:application
builder` in version 17.But since v18, in case of the
@angular-devkit/build-angular:application
builder, the required path that is passed to the mixins needs to be relative to the mixin location, presumably because that's where the style using the url() is located. Meaning the above code needs to change to e.g.:I think the new behavior, compared to the previous one, has negative side effects:
I realize the above points might not really matter in terms of officially supported / intended behavior. Personally, I think the new inconsistency between
@angular-devkit/build-angular:ng-packagr
and@angular-devkit/build-angular:application
is the most problematic, since you effectively can't consume libraries in your workspace via their source, instead of build output, in applications that you also have in the same workspace. Well, you can, provided you either avoid such mixins completely, or turn off css inlining for libraries.Minimal Reproduction
You can checkout https://github.com/AmadejBukorovic/ng-18-mixin-resource-resolve. The repository contains an application and library, which the application depends upon, showcasing the differences mentioned above.
Run
npm run build
to build the library and consuming application successfully. The changes in Angular v18+ have no direct effect on this behavior, when consuming libraries from the workspace via build outputs, other than the obvious differences in how to correctly write relative paths forurl()
.Run
ng serve
, which will fail as it attempts to utilize thetsconfig.app-dev.json
to bypass the requirement to build the dependant library for development purposes (if you will). This fails due to differences in the behavior of SCSS resource resolution between different builders. Something that is not an issue in v17 and prior.Exception or Error
Your Environment
Anything else relevant?
No response
The text was updated successfully, but these errors were encountered: