mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(common): warn if using ngSrcset without a configured image loader (#48804)
Warn the user in the console in case the `ngSrcset` is present and no loader is configured. In this case, the default loader is used and it ignores this attribute. PR Close #48804
This commit is contained in:
committed by
Jessica Janiuk
parent
5915c7236e
commit
a055196c55
@@ -19,6 +19,8 @@ export const enum RuntimeErrorCode {
|
||||
// (undocumented)
|
||||
NG_FOR_MISSING_DIFFER = -2200,
|
||||
// (undocumented)
|
||||
NGSRCSET_WITHOUT_LOADER = 2963,
|
||||
// (undocumented)
|
||||
OVERSIZED_IMAGE = 2960,
|
||||
// (undocumented)
|
||||
PARENT_NG_SWITCH_NOT_FOUND = 2000,
|
||||
|
||||
@@ -385,6 +385,7 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
|
||||
assertNoComplexSizes(this);
|
||||
}
|
||||
assertNotMissingBuiltInLoader(this.ngSrc, this.imageLoader);
|
||||
assertNoNgSrcsetWithoutLoader(this, this.imageLoader);
|
||||
if (this.priority) {
|
||||
const checker = this.injector.get(PreconnectLinkChecker);
|
||||
checker.assertPreconnect(this.getRewrittenSrc(), this.ngSrc);
|
||||
@@ -953,3 +954,17 @@ function assertNotMissingBuiltInLoader(ngSrc: string, imageLoader: ImageLoader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Warns if ngSrcset is present and no loader is configured (i.e. the default one is being used).
|
||||
*/
|
||||
function assertNoNgSrcsetWithoutLoader(dir: NgOptimizedImage, imageLoader: ImageLoader) {
|
||||
if (dir.ngSrcset && imageLoader === noopImageLoader) {
|
||||
console.warn(formatRuntimeError(
|
||||
RuntimeErrorCode.NGSRCSET_WITHOUT_LOADER,
|
||||
`${imgDirectiveDetails(dir.ngSrc)} the \`ngSrcset\` attribute is present but ` +
|
||||
`no image loader is configured (i.e. the default one is being used), ` +
|
||||
`which would result in the same image being used for all configured sizes. ` +
|
||||
`To fix this, provide a loader or remove the \`ngSrcset\` attribute from the image.`));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,5 @@ export const enum RuntimeErrorCode {
|
||||
OVERSIZED_IMAGE = 2960,
|
||||
TOO_MANY_PRELOADED_IMAGES = 2961,
|
||||
MISSING_BUILTIN_LOADER = 2962,
|
||||
NGSRCSET_WITHOUT_LOADER = 2963,
|
||||
}
|
||||
|
||||
@@ -1183,6 +1183,24 @@ describe('Image directive', () => {
|
||||
expect(consoleWarnSpy.calls.count()).toBe(0);
|
||||
});
|
||||
|
||||
it('should warn if there is no image loader but `ngSrcset` is present', () => {
|
||||
setUpModuleNoLoader();
|
||||
|
||||
const template = `<img ngSrc="img.png" ngSrcset="100w, 200w" width="150" height="50">`;
|
||||
const fixture = createTestComponent(template);
|
||||
const consoleWarnSpy = spyOn(console, 'warn');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(consoleWarnSpy.calls.count()).toBe(1);
|
||||
expect(consoleWarnSpy.calls.argsFor(0)[0])
|
||||
.toBe(
|
||||
'NG02963: The NgOptimizedImage directive (activated on an <img> element ' +
|
||||
'with the `ngSrc="img.png"`) has detected that the `ngSrcset` attribute is ' +
|
||||
'present but no image loader is configured (i.e. the default one is being used), ' +
|
||||
`which would result in the same image being used for all configured sizes. ` +
|
||||
'To fix this, provide a loader or remove the `ngSrcset` attribute from the image.');
|
||||
});
|
||||
|
||||
it('should set `src` using the image loader provided via the `IMAGE_LOADER` token to compose src URL',
|
||||
() => {
|
||||
const imageLoader = (config: ImageLoaderConfig) => `${IMG_BASE_URL}/${config.src}`;
|
||||
|
||||
@@ -6,13 +6,19 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {NgOptimizedImage} from '@angular/common';
|
||||
import {IMAGE_LOADER, ImageLoaderConfig, NgOptimizedImage} from '@angular/common';
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
const imageLoader = {
|
||||
provide: IMAGE_LOADER,
|
||||
useFactory: () => (config: ImageLoaderConfig) => config.src
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'oversized-image-passing',
|
||||
standalone: true,
|
||||
imports: [NgOptimizedImage],
|
||||
providers: [imageLoader],
|
||||
template: `
|
||||
<!-- Image is rendered within threshold range-->
|
||||
<div style="width: 500px; height: 500px">
|
||||
@@ -33,6 +39,7 @@ export class OversizedImageComponentPassing {
|
||||
selector: 'oversized-image-failing',
|
||||
standalone: true,
|
||||
imports: [NgOptimizedImage],
|
||||
providers: [imageLoader],
|
||||
template: `
|
||||
<!-- Image is rendered too small -->
|
||||
<div style="width: 300px; height: 300px">
|
||||
|
||||
Reference in New Issue
Block a user