Skip to content

Commit

Permalink
feat: add inlineStylesheets configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
lilnasy authored Mar 29, 2023
1 parent f0b732d commit 4475b42
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/friendly-fishes-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': minor
---

add a configuration option (build.inlineStylsheets) to let the user include small stylsheets in the html
3 changes: 3 additions & 0 deletions packages/astro/src/core/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '../render/index.js';
import { RouteCache } from '../render/route-cache.js';
import {
createInlineStyleElementSet,
createLinkStylesheetElementSet,
createModuleScriptElement,
} from '../render/ssr-element.js';
Expand Down Expand Up @@ -173,6 +174,7 @@ export class App {
const pathname = '/' + this.removeBase(url.pathname);
const info = this.#routeDataToRouteInfo.get(routeData!)!;
const links = createLinkStylesheetElementSet(info.links);
const styles = createInlineStyleElementSet(info.styles);

let scripts = new Set<SSRElement>();
for (const script of info.scripts) {
Expand All @@ -195,6 +197,7 @@ export class App {
pathname,
componentMetadata: this.#manifest.componentMetadata,
scripts,
styles,
links,
route: routeData,
status,
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface RouteInfo {
// Hoisted
| { type: 'inline' | 'external'; value: string }
)[];
styles: string[];
}

export type SerializedRouteInfo = Omit<RouteInfo, 'routeData'> & {
Expand Down
21 changes: 19 additions & 2 deletions packages/astro/src/core/build/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ import { AstroError } from '../errors/index.js';
import { debug, info } from '../logger/core.js';
import { createEnvironment, createRenderContext, renderPage } from '../render/index.js';
import { callGetStaticPaths } from '../render/route-cache.js';
import { createLinkStylesheetElementSet, createModuleScriptsSet } from '../render/ssr-element.js';
import {
createLinkStylesheetElementSet,
createInlineStyleElementSet,
createModuleScriptsSet,
} from '../render/ssr-element.js';
import { createRequest } from '../request.js';
import { matchRoute } from '../routing/match.js';
import { getOutputFilename } from '../util.js';
Expand Down Expand Up @@ -155,6 +159,7 @@ async function generatePage(
const pageInfo = getPageDataByComponent(internals, pageData.route.component);
const linkIds: string[] = sortedCSS(pageData);
const scripts = pageInfo?.hoistedScript ?? null;
const styles = pageInfo?.inlineStyles ?? null;

const pageModule = ssrEntry.pageMap?.get(pageData.component);

Expand All @@ -174,6 +179,7 @@ async function generatePage(
internals,
linkIds,
scripts,
styles,
mod: pageModule,
renderers,
};
Expand Down Expand Up @@ -264,6 +270,7 @@ interface GeneratePathOptions {
internals: BuildInternals;
linkIds: string[];
scripts: { type: 'inline' | 'external'; value: string } | null;
styles: string[] | null;
mod: ComponentInstance;
renderers: SSRLoadedRenderer[];
}
Expand Down Expand Up @@ -331,7 +338,15 @@ async function generatePath(
gopts: GeneratePathOptions
) {
const { settings, logging, origin, routeCache } = opts;
const { mod, internals, linkIds, scripts: hoistedScripts, pageData, renderers } = gopts;
const {
mod,
internals,
linkIds,
scripts: hoistedScripts,
styles: _styles,
pageData,
renderers,
} = gopts;

// This adds the page name to the array so it can be shown as part of stats.
if (pageData.route.type === 'page') {
Expand All @@ -345,6 +360,7 @@ async function generatePath(
hoistedScripts ? [hoistedScripts] : [],
settings.config.base
);
const styles = createInlineStyleElementSet(_styles ?? []);

if (settings.scripts.some((script) => script.stage === 'page')) {
const hashedFilePath = internals.entrySpecifierToBundleMap.get(PAGE_SCRIPT_ID);
Expand Down Expand Up @@ -407,6 +423,7 @@ async function generatePath(
request: createRequest({ url, headers: new Headers(), logging, ssr }),
componentMetadata: internals.componentMetadata,
scripts,
styles,
links,
route: pageData.route,
});
Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/core/build/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export async function collectPagesData(
propagatedStyles: new Map(),
propagatedScripts: new Map(),
hoistedScript: undefined,
inlineStyles: [],
};

clearInterval(routeCollectionLogTimeout);
Expand All @@ -80,6 +81,7 @@ export async function collectPagesData(
propagatedStyles: new Map(),
propagatedScripts: new Map(),
hoistedScript: undefined,
inlineStyles: [],
};
}

Expand Down
24 changes: 24 additions & 0 deletions packages/astro/src/core/build/plugins/plugin-css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,30 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
}
},
},
{
name: 'astro:rollup-plugin-inline-stylesheets',
// enforce: 'post',
async generateBundle(_outputOptions, bundle) {
if (settings.config.build.inlineStylesheets !== true) return;
const assetInlineLimit = settings.config.vite?.build?.assetsInlineLimit ?? 4096;
for (const [id, stylesheet] of Object.entries(bundle)) {
if (
stylesheet.type === 'asset' &&
stylesheet.name?.endsWith('.css') &&
typeof stylesheet.source === 'string' &&
Buffer.byteLength(stylesheet.source) <= assetInlineLimit
) {
for (const pageData of eachPageData(internals)) {
if (pageData.css.has(stylesheet.fileName)) {
pageData.inlineStyles.push(stylesheet.source);
pageData.css.delete(stylesheet.fileName);
delete bundle[id];
}
}
}
}
},
},
];
}

Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/core/build/plugins/plugin-ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ function buildManifest(
file,
links: [],
scripts: [],
styles: [],
routeData: serializeRouteData(pageData.route, settings.config.trailingSlash),
});
staticFiles.push(file);
Expand Down Expand Up @@ -192,6 +193,7 @@ function buildManifest(
.filter((script) => script.stage === 'head-inline')
.map(({ stage, content }) => ({ stage, children: content })),
],
styles: pageData.inlineStyles,
routeData: serializeRouteData(pageData.route, settings.config.trailingSlash),
});
}
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/build/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface PageBuildData {
propagatedStyles: Map<string, Set<string>>;
propagatedScripts: Map<string, Set<string>>;
hoistedScript: { type: 'inline' | 'external'; value: string } | undefined;
inlineStyles: string[];
}
export type AllPagesData = Record<ComponentPath, PageBuildData>;

Expand Down
9 changes: 9 additions & 0 deletions packages/astro/src/core/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = {
server: './dist/server/',
assets: '_astro',
serverEntry: 'entry.mjs',
inlineStylesheets: false,
},
server: {
host: false,
Expand Down Expand Up @@ -98,6 +99,10 @@ export const AstroConfigSchema = z.object({
.transform((val) => new URL(val)),
assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry),
inlineStylesheets: z
.boolean()
.optional()
.default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets),
})
.optional()
.default({}),
Expand Down Expand Up @@ -223,6 +228,10 @@ export function createRelativeSchema(cmd: string, fileProtocolRoot: URL) {
.transform((val) => new URL(val, fileProtocolRoot)),
assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry),
inlineStylesheets: z
.boolean()
.optional()
.default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets),
})
.optional()
.default({}),
Expand Down
13 changes: 13 additions & 0 deletions packages/astro/src/core/render/ssr-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ export function createLinkStylesheetElementSet(hrefs: string[], base?: string) {
return new Set<SSRElement>(hrefs.map((href) => createLinkStylesheetElement(href, base)));
}

export function createInlineStyleElement(text: string): SSRElement {
return {
props: {
type: 'text/css',
},
children: text,
};
}

export function createInlineStyleElementSet(texts: string[]) {
return new Set(texts.map(createInlineStyleElement));
}

export function createModuleScriptElement(
script: { type: 'inline' | 'external'; value: string },
base?: string
Expand Down

0 comments on commit 4475b42

Please sign in to comment.