feat(perf:fast-rebuilds): Stop mutating resources param in ComponentResources emitter (#977)
* Stop mutating resources param in ComponentResources emitter * Add done rebuilding log for fast rebuilds * Move google font loading to Head component * Simplify code and fix comment
This commit is contained in:
		| @@ -19,6 +19,7 @@ const config: QuartzConfig = { | ||||
|     ignorePatterns: ["private", "templates", ".obsidian"], | ||||
|     defaultDateType: "created", | ||||
|     theme: { | ||||
|       fontOrigin: "googleFonts", | ||||
|       cdnCaching: true, | ||||
|       typography: { | ||||
|         header: "Schibsted Grotesk", | ||||
| @@ -72,7 +73,7 @@ const config: QuartzConfig = { | ||||
|     filters: [Plugin.RemoveDrafts()], | ||||
|     emitters: [ | ||||
|       Plugin.AliasRedirects(), | ||||
|       Plugin.ComponentResources({ fontOrigin: "googleFonts" }), | ||||
|       Plugin.ComponentResources(), | ||||
|       Plugin.ContentPage(), | ||||
|       Plugin.FolderPage(), | ||||
|       Plugin.TagPage(), | ||||
|   | ||||
| @@ -309,6 +309,8 @@ async function partialRebuildFromEntrypoint( | ||||
|   } | ||||
|   await rimraf([...destinationsToDelete]) | ||||
|  | ||||
|   console.log(chalk.green(`Done rebuilding in ${perf.timeSince()}`)) | ||||
|  | ||||
|   toRemove.clear() | ||||
|   release() | ||||
|   clientRefresh() | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { i18n } from "../i18n" | ||||
| import { FullSlug, joinSegments, pathToRoot } from "../util/path" | ||||
| import { JSResourceToScriptElement } from "../util/resources" | ||||
| import { googleFontHref } from "../util/theme" | ||||
| import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" | ||||
|  | ||||
| export default (() => { | ||||
| @@ -21,10 +22,11 @@ export default (() => { | ||||
|       <head> | ||||
|         <title>{title}</title> | ||||
|         <meta charSet="utf-8" /> | ||||
|         {cfg.theme.cdnCaching && ( | ||||
|         {cfg.theme.cdnCaching && cfg.theme.fontOrigin === "googleFonts" && ( | ||||
|           <> | ||||
|             <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||||
|             <link rel="preconnect" href="https://fonts.gstatic.com" /> | ||||
|             <link rel="stylesheet" href={googleFontHref(cfg.theme)} /> | ||||
|           </> | ||||
|         )} | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|   | ||||
| @@ -8,7 +8,6 @@ import popoverScript from "../../components/scripts/popover.inline" | ||||
| import styles from "../../styles/custom.scss" | ||||
| import popoverStyle from "../../components/styles/popover.scss" | ||||
| import { BuildCtx } from "../../util/ctx" | ||||
| import { StaticResources } from "../../util/resources" | ||||
| import { QuartzComponent } from "../../components/types" | ||||
| import { googleFontHref, joinStyles } from "../../util/theme" | ||||
| import { Features, transform } from "lightningcss" | ||||
| @@ -69,13 +68,8 @@ async function joinScripts(scripts: string[]): Promise<string> { | ||||
|   return res.code | ||||
| } | ||||
|  | ||||
| function addGlobalPageResources( | ||||
|   ctx: BuildCtx, | ||||
|   staticResources: StaticResources, | ||||
|   componentResources: ComponentResources, | ||||
| ) { | ||||
| function addGlobalPageResources(ctx: BuildCtx, componentResources: ComponentResources) { | ||||
|   const cfg = ctx.cfg.configuration | ||||
|   const reloadScript = ctx.argv.serve | ||||
|  | ||||
|   // popovers | ||||
|   if (cfg.enablePopovers) { | ||||
| @@ -85,12 +79,12 @@ function addGlobalPageResources( | ||||
|  | ||||
|   if (cfg.analytics?.provider === "google") { | ||||
|     const tagId = cfg.analytics.tagId | ||||
|     staticResources.js.push({ | ||||
|       src: `https://www.googletagmanager.com/gtag/js?id=${tagId}`, | ||||
|       contentType: "external", | ||||
|       loadTime: "afterDOMReady", | ||||
|     }) | ||||
|     componentResources.afterDOMLoaded.push(` | ||||
|       const gtagScript = document.createElement("script") | ||||
|       gtagScript.src = "https://www.googletagmanager.com/gtag/js?id=${tagId}" | ||||
|       gtagScript.async = true | ||||
|       document.head.appendChild(gtagScript) | ||||
|  | ||||
|       window.dataLayer = window.dataLayer || []; | ||||
|       function gtag() { dataLayer.push(arguments); } | ||||
|       gtag("js", new Date()); | ||||
| @@ -147,71 +141,29 @@ function addGlobalPageResources( | ||||
|       document.dispatchEvent(event) | ||||
|     `) | ||||
|   } | ||||
|  | ||||
|   let wsUrl = `ws://localhost:${ctx.argv.wsPort}` | ||||
|  | ||||
|   if (ctx.argv.remoteDevHost) { | ||||
|     wsUrl = `wss://${ctx.argv.remoteDevHost}:${ctx.argv.wsPort}` | ||||
|   } | ||||
|  | ||||
|   if (reloadScript) { | ||||
|     staticResources.js.push({ | ||||
|       loadTime: "afterDOMReady", | ||||
|       contentType: "inline", | ||||
|       script: ` | ||||
|           const socket = new WebSocket('${wsUrl}') | ||||
|           // reload(true) ensures resources like images and scripts are fetched again in firefox | ||||
|           socket.addEventListener('message', () => document.location.reload(true)) | ||||
|         `, | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|  | ||||
| interface Options { | ||||
|   fontOrigin: "googleFonts" | "local" | ||||
| } | ||||
|  | ||||
| const defaultOptions: Options = { | ||||
|   fontOrigin: "googleFonts", | ||||
| } | ||||
|  | ||||
| export const ComponentResources: QuartzEmitterPlugin<Options> = (opts?: Partial<Options>) => { | ||||
|   const { fontOrigin } = { ...defaultOptions, ...opts } | ||||
| // This emitter should not update the `resources` parameter. If it does, partial | ||||
| // rebuilds may not work as expected. | ||||
| export const ComponentResources: QuartzEmitterPlugin = () => { | ||||
|   return { | ||||
|     name: "ComponentResources", | ||||
|     getQuartzComponents() { | ||||
|       return [] | ||||
|     }, | ||||
|     async getDependencyGraph(ctx, content, _resources) { | ||||
|       // This emitter adds static resources to the `resources` parameter. One | ||||
|       // important resource this emitter adds is the code to start a websocket | ||||
|       // connection and listen to rebuild messages, which triggers a page reload. | ||||
|       // The resources parameter with the reload logic is later used by the | ||||
|       // ContentPage emitter while creating the final html page. In order for | ||||
|       // the reload logic to be included, and so for partial rebuilds to work, | ||||
|       // we need to run this emitter for all markdown files. | ||||
|       const graph = new DepGraph<FilePath>() | ||||
|  | ||||
|       for (const [_tree, file] of content) { | ||||
|         const sourcePath = file.data.filePath! | ||||
|         const slug = file.data.slug! | ||||
|         graph.addEdge(sourcePath, joinSegments(ctx.argv.output, slug + ".html") as FilePath) | ||||
|       } | ||||
|  | ||||
|       return graph | ||||
|     async getDependencyGraph(_ctx, _content, _resources) { | ||||
|       return new DepGraph<FilePath>() | ||||
|     }, | ||||
|     async emit(ctx, _content, resources): Promise<FilePath[]> { | ||||
|     async emit(ctx, _content, _resources): Promise<FilePath[]> { | ||||
|       const promises: Promise<FilePath>[] = [] | ||||
|       const cfg = ctx.cfg.configuration | ||||
|       // component specific scripts and styles | ||||
|       const componentResources = getComponentResources(ctx) | ||||
|       let googleFontsStyleSheet = "" | ||||
|       if (fontOrigin === "local") { | ||||
|       if (cfg.theme.fontOrigin === "local") { | ||||
|         // let the user do it themselves in css | ||||
|       } else if (fontOrigin === "googleFonts") { | ||||
|         if (cfg.theme.cdnCaching) { | ||||
|           resources.css.push(googleFontHref(cfg.theme)) | ||||
|         } else { | ||||
|       } else if (cfg.theme.fontOrigin === "googleFonts" && !cfg.theme.cdnCaching) { | ||||
|         // when cdnCaching is true, we link to google fonts in Head.tsx | ||||
|         let match | ||||
|  | ||||
|         const fontSourceRegex = /url\((https:\/\/fonts.gstatic.com\/s\/[^)]+\.(woff2|ttf))\)/g | ||||
| @@ -250,12 +202,11 @@ export const ComponentResources: QuartzEmitterPlugin<Options> = (opts?: Partial< | ||||
|           ) | ||||
|         } | ||||
|       } | ||||
|       } | ||||
|  | ||||
|       // important that this goes *after* component scripts | ||||
|       // as the "nav" event gets triggered here and we should make sure | ||||
|       // that everyone else had the chance to register a listener for it | ||||
|       addGlobalPageResources(ctx, resources, componentResources) | ||||
|       addGlobalPageResources(ctx, componentResources) | ||||
|  | ||||
|       const stylesheet = joinStyles( | ||||
|         ctx.cfg.configuration.theme, | ||||
|   | ||||
| @@ -18,6 +18,23 @@ export function getStaticResourcesFromPlugins(ctx: BuildCtx) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // if serving locally, listen for rebuilds and reload the page | ||||
|   if (ctx.argv.serve) { | ||||
|     const wsUrl = ctx.argv.remoteDevHost | ||||
|       ? `wss://${ctx.argv.remoteDevHost}:${ctx.argv.wsPort}` | ||||
|       : `ws://localhost:${ctx.argv.wsPort}` | ||||
|  | ||||
|     staticResources.js.push({ | ||||
|       loadTime: "afterDOMReady", | ||||
|       contentType: "inline", | ||||
|       script: ` | ||||
|             const socket = new WebSocket('${wsUrl}') | ||||
|             // reload(true) ensures resources like images and scripts are fetched again in firefox | ||||
|             socket.addEventListener('message', () => document.location.reload(true)) | ||||
|           `, | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   return staticResources | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -22,6 +22,7 @@ export interface Theme { | ||||
|   } | ||||
|   cdnCaching: boolean | ||||
|   colors: Colors | ||||
|   fontOrigin: "googleFonts" | "local" | ||||
| } | ||||
|  | ||||
| export type ThemeKey = keyof Colors | ||||
|   | ||||
		Reference in New Issue
	
	Block a user