Skip to content

Commit 8cfd070

Browse files
committed
build: update beasties to 0.5.1
Updates Beasties to version 0.5.1 and simplifies the inline critical CSS implementation in @angular/build and @angular/ssr by using Beasties' native preload: 'media-script' and nonce callback support. Additionally, refactors `inlineCriticalCss` in @angular/build into a standalone function and relocates `InlineCriticalCssProcessor` into @angular-devkit/build-angular for Webpack-based builders.
1 parent 2dc9aae commit 8cfd070

28 files changed

Lines changed: 606 additions & 713 deletions

packages/angular/build/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"@inquirer/confirm": "6.2.0",
2525
"@parcel/watcher": "2.6.0",
2626
"@vitejs/plugin-basic-ssl": "2.3.0",
27-
"beasties": "0.4.3",
27+
"beasties": "0.5.1",
2828
"browserslist": "^4.26.0",
2929
"chokidar": "5.0.0",
3030
"esbuild": "0.28.2",

packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
141141
indexFileContent.toContain('app-shell works!');
142142
indexFileContent.toContain('p{color:#000}');
143143
indexFileContent.toContain(
144-
`<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">`,
144+
`<link rel="stylesheet" href="styles.css" media="print" data-beasties-media="all">`,
145145
);
146146
});
147147

@@ -170,7 +170,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
170170
indexFileContent.toContain('app-shell works!');
171171
indexFileContent.toContain('p{color:#000}');
172172
indexFileContent.toContain(
173-
`<link rel="stylesheet" href="styles.css" media="print" ngCspMedia="all">`,
173+
`<link rel="stylesheet" href="styles.css" media="print" data-beasties-media="all">`,
174174
);
175175
indexFileContent.toContain('<style nonce="{% nonce %}">p{color:#000}');
176176
indexFileContent.toContain('<style nonce="{% nonce %}" ng-app-id="ng">');

packages/angular/build/src/builders/application/tests/options/optimization-inline-critical_spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
3535
harness
3636
.expectFile('dist/browser/index.html')
3737
.content.toContain(
38-
`<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">`,
38+
`<link rel="stylesheet" href="styles.css" media="print" data-beasties-media="all">`,
3939
);
4040
harness.expectFile('dist/browser/index.html').content.toContain(`body{color:#000}`);
4141
});
@@ -53,7 +53,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
5353
harness
5454
.expectFile('dist/browser/index.html')
5555
.content.toContain(
56-
`<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">`,
56+
`<link rel="stylesheet" href="styles.css" media="print" data-beasties-media="all">`,
5757
);
5858
harness.expectFile('dist/browser/index.html').content.toContain(`body{color:#000}`);
5959
});
@@ -71,7 +71,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
7171
harness
7272
.expectFile('dist/browser/index.html')
7373
.content.toContain(
74-
`<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">`,
74+
`<link rel="stylesheet" href="styles.css" media="print" data-beasties-media="all">`,
7575
);
7676
harness.expectFile('dist/browser/index.html').content.toContain(`body{color:#000}`);
7777
});
@@ -130,7 +130,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
130130
harness
131131
.expectFile('dist/browser/index.html')
132132
.content.toContain(
133-
`<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">`,
133+
`<link rel="stylesheet" href="styles.css" media="print" data-beasties-media="all">`,
134134
);
135135
harness.expectFile('dist/browser/index.html').content.toContain(`body{color:#000}`);
136136
});

packages/angular/build/src/private.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,6 @@ export {
8080
type IndexHtmlTransform,
8181
} from './utils/index-file/index-html-generator';
8282
export type { FileInfo } from './utils/index-file/augment-index-html';
83-
export {
84-
type InlineCriticalCssProcessOptions,
85-
InlineCriticalCssProcessor,
86-
type InlineCriticalCssProcessorOptions,
87-
} from './utils/index-file/inline-critical-css';
8883
export { loadProxyConfiguration } from './utils/load-proxy-config';
8984
export { type TranslationLoader, createTranslationLoader } from './utils/load-translations';
9085
export { purgeStaleBuildCache } from './utils/purge-cache';

packages/angular/build/src/tools/esbuild/index-html-generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export async function generateIndexHtml(
106106
crossOrigin: crossOrigin,
107107
deployUrl: buildOptions.publicPath,
108108
postTransform: indexHtmlOptions.transformer,
109+
outputPath: virtualOutputPath,
109110
generateDedicatedSSRContent: !!(
110111
buildOptions.ssrOptions ||
111112
buildOptions.prerenderOptions ||
@@ -120,7 +121,6 @@ export async function generateIndexHtml(
120121
return indexHtmlGenerator.process({
121122
baseHref,
122123
lang,
123-
outputPath: virtualOutputPath,
124124
files: [...initialFiles]
125125
.filter(([, file]) => !file.serverFile)
126126
.map(([file, record]) => ({

packages/angular/build/src/utils/index-file/index-html-generator.ts

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { NormalizedOptimizationOptions } from '../normalize-optimization';
1313
import { addEventDispatchContract } from './add-event-dispatch-contract';
1414
import { CrossOriginValue, Entrypoint, FileInfo, augmentIndexHtml } from './augment-index-html';
1515
import { autoCsp } from './auto-csp';
16-
import { InlineCriticalCssProcessor } from './inline-critical-css';
16+
import { inlineCriticalCss } from './inline-critical-css';
1717
import { InlineFontsProcessor } from './inline-fonts';
1818
import { addNgcmAttribute } from './ngcm-attribute';
1919
import { addNonce } from './nonce';
@@ -28,7 +28,6 @@ export type HintMode = 'prefetch' | 'preload' | 'modulepreload' | 'preconnect' |
2828
export interface IndexHtmlGeneratorProcessOptions {
2929
lang: string | undefined;
3030
baseHref: string | undefined;
31-
outputPath: string;
3231
files: FileInfo[];
3332
hints?: { url: string; mode: HintMode; as?: string }[];
3433
}
@@ -49,6 +48,7 @@ export interface IndexHtmlGeneratorOptions {
4948
imageDomains?: string[];
5049
generateDedicatedSSRContent?: boolean;
5150
autoCsp?: AutoCspOptions;
51+
outputPath: string;
5252

5353
/**
5454
* Integrity metadata for module URLs not directly referenced in the index
@@ -89,7 +89,7 @@ export class IndexHtmlGenerator {
8989

9090
// CSR plugins
9191
if (options?.optimization?.styles?.inlineCritical) {
92-
this.csrPlugins.push(inlineCriticalCssPlugin(this, !!options.autoCsp));
92+
this.csrPlugins.push(inlineCriticalCssPlugin(this));
9393
}
9494

9595
this.csrPlugins.push(addNoncePlugin());
@@ -182,10 +182,11 @@ function augmentIndexHtmlPlugin(generator: IndexHtmlGenerator): IndexHtmlGenerat
182182
entrypoints,
183183
imageDomains,
184184
chunksIntegrity,
185+
outputPath,
185186
} = generator.options;
186187

187188
return async (html, options) => {
188-
const { lang, baseHref, outputPath = '', files, hints } = options;
189+
const { lang, baseHref, files, hints } = options;
189190

190191
return augmentIndexHtml({
191192
html,
@@ -209,22 +210,15 @@ function inlineFontsPlugin({ options }: IndexHtmlGenerator): IndexHtmlGeneratorP
209210
minify: options.optimization?.styles.minify,
210211
});
211212

212-
return async (html) => inlineFontsProcessor.process(html);
213+
return (html) => inlineFontsProcessor.process(html);
213214
}
214215

215-
function inlineCriticalCssPlugin(
216-
generator: IndexHtmlGenerator,
217-
autoCsp: boolean,
218-
): IndexHtmlGeneratorPlugin {
219-
const inlineCriticalCssProcessor = new InlineCriticalCssProcessor({
220-
minify: generator.options.optimization?.styles.minify,
221-
deployUrl: generator.options.deployUrl,
222-
readAsset: (filePath) => generator.readAsset(filePath),
223-
autoCsp,
224-
});
216+
function inlineCriticalCssPlugin(generator: IndexHtmlGenerator): IndexHtmlGeneratorPlugin {
217+
const { outputPath, deployUrl, optimization } = generator.options;
218+
const { minify = false } = optimization?.styles ?? {};
225219

226-
return async (html, options) =>
227-
inlineCriticalCssProcessor.process(html, { outputPath: options.outputPath });
220+
return (html) =>
221+
inlineCriticalCss(html, outputPath, deployUrl, minify, (path) => generator.readAsset(path));
228222
}
229223

230224
function addNoncePlugin(): IndexHtmlGeneratorPlugin {

0 commit comments

Comments
 (0)