diff --git a/.changeset/tiny-snails-dance.md b/.changeset/tiny-snails-dance.md new file mode 100644 index 000000000..ef25e0459 --- /dev/null +++ b/.changeset/tiny-snails-dance.md @@ -0,0 +1,17 @@ +--- +'astro': minor +--- + +Adds an opt-in way to minify the HTML output. + +Using the `compressHTML` option Astro will remove whitespace from Astro components. This only applies to components written in `.astro` format and happens in the compiler to maximize performance. You can enable with: + +```js +import { defineConfig } from 'astro/config'; + +export default defineConfig({ + compressHTML: true +}); +``` + +Compression occurs both in development mode and in the final build. diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 19606b070..2441238aa 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -466,6 +466,24 @@ export interface AstroUserConfig { */ site?: string; + + /** + * @docs + * @name compressHTML + * @type {boolean} + * @default `false` + * @description + * This is an option to minify your HTML output and reduce the size of your HTML files. When enabled, Astro removes all whitespace from your HTML, including line breaks, from `.astro` components. This occurs both in development mode and in the final build. + * To enable this, set the `compressHTML` flag to `true`. + * + * ```js + * { + * compressHTML: true + * } + * ``` + */ + compressHTML?: boolean; + /** * @docs * @name base diff --git a/packages/astro/src/core/compile/compile.ts b/packages/astro/src/core/compile/compile.ts index 7554ec119..4c76c4c65 100644 --- a/packages/astro/src/core/compile/compile.ts +++ b/packages/astro/src/core/compile/compile.ts @@ -37,6 +37,7 @@ export async function compile({ // use `sourcemap: "both"` so that sourcemap is included in the code // result passed to esbuild, but also available in the catch handler. transformResult = await transform(source, { + compact: astroConfig.compressHTML, filename, normalizedFilename: normalizeFilename(filename, astroConfig.root), sourcemap: 'both', diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts index 15dcd7bfd..2948b2fd9 100644 --- a/packages/astro/src/core/config/schema.ts +++ b/packages/astro/src/core/config/schema.ts @@ -23,6 +23,7 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = { assets: '_astro', serverEntry: 'entry.mjs', }, + compressHTML: false, server: { host: false, port: 3000, @@ -72,6 +73,7 @@ export const AstroConfigSchema = z.object({ .default(ASTRO_CONFIG_DEFAULTS.cacheDir) .transform((val) => new URL(val)), site: z.string().url().optional(), + compressHTML: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.compressHTML), base: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.base), trailingSlash: z .union([z.literal('always'), z.literal('never'), z.literal('ignore')]) @@ -225,6 +227,10 @@ export function createRelativeSchema(cmd: string, fileProtocolRoot: URL) { .string() .default(ASTRO_CONFIG_DEFAULTS.srcDir) .transform((val) => new URL(appendForwardSlash(val), fileProtocolRoot)), + compressHTML: z + .boolean() + .optional() + .default(ASTRO_CONFIG_DEFAULTS.compressHTML), publicDir: z .string() .default(ASTRO_CONFIG_DEFAULTS.publicDir) diff --git a/packages/astro/src/runtime/server/render/page.ts b/packages/astro/src/runtime/server/render/page.ts index ce2d165a7..f4a02a75f 100644 --- a/packages/astro/src/runtime/server/render/page.ts +++ b/packages/astro/src/runtime/server/render/page.ts @@ -79,7 +79,6 @@ export async function renderPage( result._metadata.headInTree = result.componentMetadata.get((componentFactory as any).moduleId)?.containsHead ?? false; const pageProps: Record = { ...(props ?? {}), 'server:root': true }; - let output: ComponentIterable; let head = ''; try { diff --git a/packages/astro/test/fixtures/minification-html/astro.config.mjs b/packages/astro/test/fixtures/minification-html/astro.config.mjs new file mode 100644 index 000000000..4cc49df62 --- /dev/null +++ b/packages/astro/test/fixtures/minification-html/astro.config.mjs @@ -0,0 +1,7 @@ +import { defineConfig } from 'astro/config'; + +// https://astro.build/config +export default defineConfig({ + compressHTML: true, + +}); diff --git a/packages/astro/test/fixtures/minification-html/package.json b/packages/astro/test/fixtures/minification-html/package.json new file mode 100644 index 000000000..01c5bd4b8 --- /dev/null +++ b/packages/astro/test/fixtures/minification-html/package.json @@ -0,0 +1,8 @@ +{ + "name": "@test/minification-html", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/minification-html/src/pages/aside.astro b/packages/astro/test/fixtures/minification-html/src/pages/aside.astro new file mode 100644 index 000000000..3a388c276 --- /dev/null +++ b/packages/astro/test/fixtures/minification-html/src/pages/aside.astro @@ -0,0 +1,3 @@ +--- +--- +
2
diff --git a/packages/astro/test/fixtures/minification-html/src/pages/index.astro b/packages/astro/test/fixtures/minification-html/src/pages/index.astro new file mode 100644 index 000000000..8feb4e2e0 --- /dev/null +++ b/packages/astro/test/fixtures/minification-html/src/pages/index.astro @@ -0,0 +1,21 @@ +--- +import Aside from './aside.astro' +import Page from './page.astro' +--- + + + + + minimum html + + + +