remove the white space after the doctype according to the property co… (#7242)

This commit is contained in:
Jerry_wu 2023-06-05 16:02:04 +08:00 committed by GitHub
parent ef410fa30b
commit 890a2bc989
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 9 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
remove the white space after the doctype according to the property compressHTML

View file

@ -506,11 +506,11 @@ async function generatePath(
onRequest as MiddlewareResponseHandler, onRequest as MiddlewareResponseHandler,
apiContext, apiContext,
() => { () => {
return renderPage({ mod, renderContext, env, apiContext }); return renderPage({ mod, renderContext, env, apiContext, isCompressHTML: settings.config.compressHTML });
} }
); );
} else { } else {
response = await renderPage({ mod, renderContext, env, apiContext }); response = await renderPage({ mod, renderContext, env, apiContext, isCompressHTML: settings.config.compressHTML });
} }
} catch (err) { } catch (err) {
if (!AstroError.is(err) && !(err as SSRError).id && typeof err === 'object') { if (!AstroError.is(err) && !(err as SSRError).id && typeof err === 'object') {

View file

@ -108,9 +108,10 @@ export type RenderPage = {
renderContext: RenderContext; renderContext: RenderContext;
env: Environment; env: Environment;
apiContext?: APIContext; apiContext?: APIContext;
isCompressHTML?: boolean
}; };
export async function renderPage({ mod, renderContext, env, apiContext }: RenderPage) { export async function renderPage({ mod, renderContext, env, apiContext, isCompressHTML = false }: RenderPage) {
// Validate the page component before rendering the page // Validate the page component before rendering the page
const Component = mod.default; const Component = mod.default;
if (!Component) if (!Component)
@ -152,6 +153,7 @@ export async function renderPage({ mod, renderContext, env, apiContext }: Render
renderContext.props, renderContext.props,
null, null,
env.streaming, env.streaming,
isCompressHTML,
renderContext.route renderContext.route
); );

View file

@ -30,6 +30,7 @@ function nonAstroPageNeedsHeadInjection(pageComponent: NonAstroPageComponent): b
async function iterableToHTMLBytes( async function iterableToHTMLBytes(
result: SSRResult, result: SSRResult,
iterable: ComponentIterable, iterable: ComponentIterable,
isCompressHTML: boolean,
onDocTypeInjection?: (parts: HTMLParts) => Promise<void> onDocTypeInjection?: (parts: HTMLParts) => Promise<void>
): Promise<Uint8Array> { ): Promise<Uint8Array> {
const parts = new HTMLParts(); const parts = new HTMLParts();
@ -39,7 +40,7 @@ async function iterableToHTMLBytes(
if (i === 0) { if (i === 0) {
i++; i++;
if (!/<!doctype html/i.test(String(chunk))) { if (!/<!doctype html/i.test(String(chunk))) {
parts.append('<!DOCTYPE html>\n', result); parts.append(`${isCompressHTML ? '<!DOCTYPE html>' : '<!DOCTYPE html>\n'}`, result);
if (onDocTypeInjection) { if (onDocTypeInjection) {
await onDocTypeInjection(parts); await onDocTypeInjection(parts);
} }
@ -73,6 +74,7 @@ export async function renderPage(
props: any, props: any,
children: any, children: any,
streaming: boolean, streaming: boolean,
isCompressHTML: boolean,
route?: RouteData | undefined route?: RouteData | undefined
): Promise<Response> { ): Promise<Response> {
if (!isAstroComponentFactory(componentFactory)) { if (!isAstroComponentFactory(componentFactory)) {
@ -113,7 +115,7 @@ export async function renderPage(
} }
// Accumulate the HTML string and append the head if necessary. // Accumulate the HTML string and append the head if necessary.
const bytes = await iterableToHTMLBytes(result, output, async (parts) => { const bytes = await iterableToHTMLBytes(result, output, isCompressHTML, async (parts) => {
parts.append(head, result); parts.append(head, result);
}); });
@ -152,7 +154,7 @@ export async function renderPage(
if (isHTMLString(chunk)) { if (isHTMLString(chunk)) {
if (i === 0) { if (i === 0) {
if (!/<!doctype html/i.test(String(chunk))) { if (!/<!doctype html/i.test(String(chunk))) {
controller.enqueue(encoder.encode('<!DOCTYPE html>\n')); controller.enqueue(encoder.encode(`${isCompressHTML ? '<!DOCTYPE html>' : '<!DOCTYPE html>\n'}`));
} }
} }
} }
@ -187,7 +189,7 @@ export async function renderPage(
}, },
}); });
} else { } else {
body = await iterableToHTMLBytes(result, iterable); body = await iterableToHTMLBytes(result, iterable, isCompressHTML);
headers.set('Content-Length', body.byteLength.toString()); headers.set('Content-Length', body.byteLength.toString());
} }

View file

@ -5,7 +5,7 @@ import testAdapter from './test-adapter.js';
const NEW_LINES = /[\r\n]+/gm; const NEW_LINES = /[\r\n]+/gm;
/** /**
* The doctype declaration is on a line between the rest of the HTML. * The doctype declaration is on a line between the rest of the HTML in SSG.
* This function removes the doctype so that we can check if the rest of the HTML is without * This function removes the doctype so that we can check if the rest of the HTML is without
* whitespace. * whitespace.
*/ */
@ -53,7 +53,7 @@ describe('HTML minification', () => {
it('should emit compressed HTML in the emitted file', async () => { it('should emit compressed HTML in the emitted file', async () => {
const html = await fixture.readFile('/index.html'); const html = await fixture.readFile('/index.html');
expect(NEW_LINES.test(removeDoctypeLine(html))).to.equal(false); expect(NEW_LINES.test(html)).to.equal(false);
}); });
}); });