make component resources a proper emitter
This commit is contained in:
		@@ -4,7 +4,6 @@ draft: true
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## high priority
 | 
					## high priority
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- component resources should be emitted by an emitter
 | 
					 | 
				
			||||||
- https://help.obsidian.md/Editing+and+formatting/Tags#Nested+tags nested tags??
 | 
					- https://help.obsidian.md/Editing+and+formatting/Tags#Nested+tags nested tags??
 | 
				
			||||||
- watch mode for config/source code
 | 
					- watch mode for config/source code
 | 
				
			||||||
- https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Task+lists task list styling
 | 
					- https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Task+lists task list styling
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,6 +95,7 @@ const config: QuartzConfig = {
 | 
				
			|||||||
    filters: [Plugin.RemoveDrafts()],
 | 
					    filters: [Plugin.RemoveDrafts()],
 | 
				
			||||||
    emitters: [
 | 
					    emitters: [
 | 
				
			||||||
      Plugin.AliasRedirects(),
 | 
					      Plugin.AliasRedirects(),
 | 
				
			||||||
 | 
					      Plugin.ComponentResources(),
 | 
				
			||||||
      Plugin.ContentPage({
 | 
					      Plugin.ContentPage({
 | 
				
			||||||
        ...sharedPageComponents,
 | 
					        ...sharedPageComponents,
 | 
				
			||||||
        ...contentPageLayout,
 | 
					        ...contentPageLayout,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,8 +82,8 @@ const BuildArgv = {
 | 
				
			|||||||
  bundleInfo: {
 | 
					  bundleInfo: {
 | 
				
			||||||
    boolean: true,
 | 
					    boolean: true,
 | 
				
			||||||
    default: false,
 | 
					    default: false,
 | 
				
			||||||
    describe: "show detailed bundle information"
 | 
					    describe: "show detailed bundle information",
 | 
				
			||||||
  }
 | 
					  },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function escapePath(fp) {
 | 
					function escapePath(fp) {
 | 
				
			||||||
@@ -351,9 +351,9 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
 | 
				
			|||||||
      console.log(
 | 
					      console.log(
 | 
				
			||||||
        `Successfully transpiled ${Object.keys(meta.inputs).length} files (${prettyBytes(
 | 
					        `Successfully transpiled ${Object.keys(meta.inputs).length} files (${prettyBytes(
 | 
				
			||||||
          meta.bytes,
 | 
					          meta.bytes,
 | 
				
			||||||
        )})`)
 | 
					        )})`,
 | 
				
			||||||
      console.log(await esbuild.analyzeMetafile(result.metafile, { color: true })
 | 
					 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
 | 
					      console.log(await esbuild.analyzeMetafile(result.metafile, { color: true }))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { default: buildQuartz } = await import(cacheFile)
 | 
					    const { default: buildQuartz } = await import(cacheFile)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										154
									
								
								quartz/plugins/emitters/componentResources.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								quartz/plugins/emitters/componentResources.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					import { FilePath, ServerSlug } from "../../path"
 | 
				
			||||||
 | 
					import { PluginTypes, QuartzEmitterPlugin } from "../types"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// @ts-ignore
 | 
				
			||||||
 | 
					import spaRouterScript from "../../components/scripts/spa.inline"
 | 
				
			||||||
 | 
					// @ts-ignore
 | 
				
			||||||
 | 
					import plausibleScript from "../../components/scripts/plausible.inline"
 | 
				
			||||||
 | 
					// @ts-ignore
 | 
				
			||||||
 | 
					import popoverScript from "../../components/scripts/popover.inline"
 | 
				
			||||||
 | 
					import styles from "../../styles/base.scss"
 | 
				
			||||||
 | 
					import popoverStyle from "../../components/styles/popover.scss"
 | 
				
			||||||
 | 
					import { BuildCtx } from "../../ctx"
 | 
				
			||||||
 | 
					import { StaticResources } from "../../resources"
 | 
				
			||||||
 | 
					import { QuartzComponent } from "../../components/types"
 | 
				
			||||||
 | 
					import { googleFontHref, joinStyles } from "../../theme"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ComponentResources = {
 | 
				
			||||||
 | 
					  css: string[]
 | 
				
			||||||
 | 
					  beforeDOMLoaded: string[]
 | 
				
			||||||
 | 
					  afterDOMLoaded: string[]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getComponentResources(plugins: PluginTypes): ComponentResources {
 | 
				
			||||||
 | 
					  const allComponents: Set<QuartzComponent> = new Set()
 | 
				
			||||||
 | 
					  for (const emitter of plugins.emitters) {
 | 
				
			||||||
 | 
					    const components = emitter.getQuartzComponents()
 | 
				
			||||||
 | 
					    for (const component of components) {
 | 
				
			||||||
 | 
					      allComponents.add(component)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const componentResources = {
 | 
				
			||||||
 | 
					    css: new Set<string>(),
 | 
				
			||||||
 | 
					    beforeDOMLoaded: new Set<string>(),
 | 
				
			||||||
 | 
					    afterDOMLoaded: new Set<string>(),
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (const component of allComponents) {
 | 
				
			||||||
 | 
					    const { css, beforeDOMLoaded, afterDOMLoaded } = component
 | 
				
			||||||
 | 
					    if (css) {
 | 
				
			||||||
 | 
					      componentResources.css.add(css)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (beforeDOMLoaded) {
 | 
				
			||||||
 | 
					      componentResources.beforeDOMLoaded.add(beforeDOMLoaded)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (afterDOMLoaded) {
 | 
				
			||||||
 | 
					      componentResources.afterDOMLoaded.add(afterDOMLoaded)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    css: [...componentResources.css],
 | 
				
			||||||
 | 
					    beforeDOMLoaded: [...componentResources.beforeDOMLoaded],
 | 
				
			||||||
 | 
					    afterDOMLoaded: [...componentResources.afterDOMLoaded],
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function joinScripts(scripts: string[]): string {
 | 
				
			||||||
 | 
					  // wrap with iife to prevent scope collision
 | 
				
			||||||
 | 
					  return scripts.map((script) => `(function () {${script}})();`).join("\n")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function addGlobalPageResources(
 | 
				
			||||||
 | 
					  ctx: BuildCtx,
 | 
				
			||||||
 | 
					  staticResources: StaticResources,
 | 
				
			||||||
 | 
					  componentResources: ComponentResources,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  const cfg = ctx.cfg.configuration
 | 
				
			||||||
 | 
					  const reloadScript = ctx.argv.serve
 | 
				
			||||||
 | 
					  staticResources.css.push(googleFontHref(cfg.theme))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // popovers
 | 
				
			||||||
 | 
					  if (cfg.enablePopovers) {
 | 
				
			||||||
 | 
					    componentResources.afterDOMLoaded.push(popoverScript)
 | 
				
			||||||
 | 
					    componentResources.css.push(popoverStyle)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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(`
 | 
				
			||||||
 | 
					      window.dataLayer = window.dataLayer || [];
 | 
				
			||||||
 | 
					      function gtag() { dataLayer.push(arguments); }
 | 
				
			||||||
 | 
					      gtag(\`js\`, new Date());
 | 
				
			||||||
 | 
					      gtag(\`config\`, \`${tagId}\`, { send_page_view: false });
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					      document.addEventListener(\`nav\`, () => {
 | 
				
			||||||
 | 
					        gtag(\`event\`, \`page_view\`, {
 | 
				
			||||||
 | 
					          page_title: document.title,
 | 
				
			||||||
 | 
					          page_location: location.href,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });`)
 | 
				
			||||||
 | 
					  } else if (cfg.analytics?.provider === "plausible") {
 | 
				
			||||||
 | 
					    componentResources.afterDOMLoaded.push(plausibleScript)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // spa
 | 
				
			||||||
 | 
					  if (cfg.enableSPA) {
 | 
				
			||||||
 | 
					    componentResources.afterDOMLoaded.push(spaRouterScript)
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    componentResources.afterDOMLoaded.push(`
 | 
				
			||||||
 | 
					        window.spaNavigate = (url, _) => window.location.assign(url)
 | 
				
			||||||
 | 
					        const event = new CustomEvent("nav", { detail: { slug: document.body.dataset.slug } })
 | 
				
			||||||
 | 
					        document.dispatchEvent(event)`)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (reloadScript) {
 | 
				
			||||||
 | 
					    staticResources.js.push({
 | 
				
			||||||
 | 
					      loadTime: "afterDOMReady",
 | 
				
			||||||
 | 
					      contentType: "inline",
 | 
				
			||||||
 | 
					      script: `
 | 
				
			||||||
 | 
					          const socket = new WebSocket('ws://localhost:3001')
 | 
				
			||||||
 | 
					          socket.addEventListener('message', () => document.location.reload())
 | 
				
			||||||
 | 
					        `,
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const ComponentResources: QuartzEmitterPlugin = () => ({
 | 
				
			||||||
 | 
					  name: "ComponentResources",
 | 
				
			||||||
 | 
					  getQuartzComponents() {
 | 
				
			||||||
 | 
					    return []
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  async emit(ctx, _content, resources, emit): Promise<FilePath[]> {
 | 
				
			||||||
 | 
					    // component specific scripts and styles
 | 
				
			||||||
 | 
					    const componentResources = getComponentResources(ctx.cfg.plugins)
 | 
				
			||||||
 | 
					    // 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)
 | 
				
			||||||
 | 
					    const fps = await Promise.all([
 | 
				
			||||||
 | 
					      emit({
 | 
				
			||||||
 | 
					        slug: "index" as ServerSlug,
 | 
				
			||||||
 | 
					        ext: ".css",
 | 
				
			||||||
 | 
					        content: joinStyles(ctx.cfg.configuration.theme, styles, ...componentResources.css),
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					      emit({
 | 
				
			||||||
 | 
					        slug: "prescript" as ServerSlug,
 | 
				
			||||||
 | 
					        ext: ".js",
 | 
				
			||||||
 | 
					        content: joinScripts(componentResources.beforeDOMLoaded),
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					      emit({
 | 
				
			||||||
 | 
					        slug: "postscript" as ServerSlug,
 | 
				
			||||||
 | 
					        ext: ".js",
 | 
				
			||||||
 | 
					        content: joinScripts(componentResources.afterDOMLoaded),
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					    ])
 | 
				
			||||||
 | 
					    return fps
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -5,3 +5,4 @@ export { ContentIndex } from "./contentIndex"
 | 
				
			|||||||
export { AliasRedirects } from "./aliases"
 | 
					export { AliasRedirects } from "./aliases"
 | 
				
			||||||
export { Assets } from "./assets"
 | 
					export { Assets } from "./assets"
 | 
				
			||||||
export { Static } from "./static"
 | 
					export { Static } from "./static"
 | 
				
			||||||
 | 
					export { ComponentResources } from "./componentResources"
 | 
				
			||||||
@@ -1,82 +1,7 @@
 | 
				
			|||||||
import { GlobalConfiguration } from "../cfg"
 | 
					 | 
				
			||||||
import { QuartzComponent } from "../components/types"
 | 
					 | 
				
			||||||
import { StaticResources } from "../resources"
 | 
					import { StaticResources } from "../resources"
 | 
				
			||||||
import { joinStyles } from "../theme"
 | 
					import { PluginTypes } from "./types"
 | 
				
			||||||
import { EmitCallback, PluginTypes } from "./types"
 | 
					 | 
				
			||||||
import styles from "../styles/base.scss"
 | 
					 | 
				
			||||||
import { FilePath, ServerSlug } from "../path"
 | 
					import { FilePath, ServerSlug } from "../path"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ComponentResources = {
 | 
					 | 
				
			||||||
  css: string[]
 | 
					 | 
				
			||||||
  beforeDOMLoaded: string[]
 | 
					 | 
				
			||||||
  afterDOMLoaded: string[]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function getComponentResources(plugins: PluginTypes): ComponentResources {
 | 
					 | 
				
			||||||
  const allComponents: Set<QuartzComponent> = new Set()
 | 
					 | 
				
			||||||
  for (const emitter of plugins.emitters) {
 | 
					 | 
				
			||||||
    const components = emitter.getQuartzComponents()
 | 
					 | 
				
			||||||
    for (const component of components) {
 | 
					 | 
				
			||||||
      allComponents.add(component)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const componentResources = {
 | 
					 | 
				
			||||||
    css: new Set<string>(),
 | 
					 | 
				
			||||||
    beforeDOMLoaded: new Set<string>(),
 | 
					 | 
				
			||||||
    afterDOMLoaded: new Set<string>(),
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (const component of allComponents) {
 | 
					 | 
				
			||||||
    const { css, beforeDOMLoaded, afterDOMLoaded } = component
 | 
					 | 
				
			||||||
    if (css) {
 | 
					 | 
				
			||||||
      componentResources.css.add(css)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (beforeDOMLoaded) {
 | 
					 | 
				
			||||||
      componentResources.beforeDOMLoaded.add(beforeDOMLoaded)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (afterDOMLoaded) {
 | 
					 | 
				
			||||||
      componentResources.afterDOMLoaded.add(afterDOMLoaded)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    css: [...componentResources.css],
 | 
					 | 
				
			||||||
    beforeDOMLoaded: [...componentResources.beforeDOMLoaded],
 | 
					 | 
				
			||||||
    afterDOMLoaded: [...componentResources.afterDOMLoaded],
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function joinScripts(scripts: string[]): string {
 | 
					 | 
				
			||||||
  // wrap with iife to prevent scope collision
 | 
					 | 
				
			||||||
  return scripts.map((script) => `(function () {${script}})();`).join("\n")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function emitComponentResources(
 | 
					 | 
				
			||||||
  cfg: GlobalConfiguration,
 | 
					 | 
				
			||||||
  res: ComponentResources,
 | 
					 | 
				
			||||||
  emit: EmitCallback,
 | 
					 | 
				
			||||||
): Promise<FilePath[]> {
 | 
					 | 
				
			||||||
  const fps = await Promise.all([
 | 
					 | 
				
			||||||
    emit({
 | 
					 | 
				
			||||||
      slug: "index" as ServerSlug,
 | 
					 | 
				
			||||||
      ext: ".css",
 | 
					 | 
				
			||||||
      content: joinStyles(cfg.theme, styles, ...res.css),
 | 
					 | 
				
			||||||
    }),
 | 
					 | 
				
			||||||
    emit({
 | 
					 | 
				
			||||||
      slug: "prescript" as ServerSlug,
 | 
					 | 
				
			||||||
      ext: ".js",
 | 
					 | 
				
			||||||
      content: joinScripts(res.beforeDOMLoaded),
 | 
					 | 
				
			||||||
    }),
 | 
					 | 
				
			||||||
    emit({
 | 
					 | 
				
			||||||
      slug: "postscript" as ServerSlug,
 | 
					 | 
				
			||||||
      ext: ".js",
 | 
					 | 
				
			||||||
      content: joinScripts(res.afterDOMLoaded),
 | 
					 | 
				
			||||||
    }),
 | 
					 | 
				
			||||||
  ])
 | 
					 | 
				
			||||||
  return fps
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function getStaticResourcesFromPlugins(plugins: PluginTypes) {
 | 
					export function getStaticResourcesFromPlugins(plugins: PluginTypes) {
 | 
				
			||||||
  const staticResources: StaticResources = {
 | 
					  const staticResources: StaticResources = {
 | 
				
			||||||
    css: [],
 | 
					    css: [],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,89 +1,14 @@
 | 
				
			|||||||
import path from "path"
 | 
					import path from "path"
 | 
				
			||||||
import fs from "fs"
 | 
					import fs from "fs"
 | 
				
			||||||
import { PerfTimer } from "../perf"
 | 
					import { PerfTimer } from "../perf"
 | 
				
			||||||
import {
 | 
					import { getStaticResourcesFromPlugins } from "../plugins"
 | 
				
			||||||
  ComponentResources,
 | 
					 | 
				
			||||||
  emitComponentResources,
 | 
					 | 
				
			||||||
  getComponentResources,
 | 
					 | 
				
			||||||
  getStaticResourcesFromPlugins,
 | 
					 | 
				
			||||||
} from "../plugins"
 | 
					 | 
				
			||||||
import { EmitCallback } from "../plugins/types"
 | 
					import { EmitCallback } from "../plugins/types"
 | 
				
			||||||
import { ProcessedContent } from "../plugins/vfile"
 | 
					import { ProcessedContent } from "../plugins/vfile"
 | 
				
			||||||
import { FilePath } from "../path"
 | 
					import { FilePath } from "../path"
 | 
				
			||||||
 | 
					 | 
				
			||||||
// @ts-ignore
 | 
					 | 
				
			||||||
import spaRouterScript from "../components/scripts/spa.inline"
 | 
					 | 
				
			||||||
// @ts-ignore
 | 
					 | 
				
			||||||
import plausibleScript from "../components/scripts/plausible.inline"
 | 
					 | 
				
			||||||
// @ts-ignore
 | 
					 | 
				
			||||||
import popoverScript from "../components/scripts/popover.inline"
 | 
					 | 
				
			||||||
import popoverStyle from "../components/styles/popover.scss"
 | 
					 | 
				
			||||||
import { StaticResources } from "../resources"
 | 
					 | 
				
			||||||
import { QuartzLogger } from "../log"
 | 
					import { QuartzLogger } from "../log"
 | 
				
			||||||
import { googleFontHref } from "../theme"
 | 
					 | 
				
			||||||
import { trace } from "../trace"
 | 
					import { trace } from "../trace"
 | 
				
			||||||
import { BuildCtx } from "../ctx"
 | 
					import { BuildCtx } from "../ctx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function addGlobalPageResources(
 | 
					 | 
				
			||||||
  ctx: BuildCtx,
 | 
					 | 
				
			||||||
  staticResources: StaticResources,
 | 
					 | 
				
			||||||
  componentResources: ComponentResources,
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  const cfg = ctx.cfg.configuration
 | 
					 | 
				
			||||||
  const reloadScript = ctx.argv.serve
 | 
					 | 
				
			||||||
  staticResources.css.push(googleFontHref(cfg.theme))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // popovers
 | 
					 | 
				
			||||||
  if (cfg.enablePopovers) {
 | 
					 | 
				
			||||||
    componentResources.afterDOMLoaded.push(popoverScript)
 | 
					 | 
				
			||||||
    componentResources.css.push(popoverStyle)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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(`
 | 
					 | 
				
			||||||
    window.dataLayer = window.dataLayer || [];
 | 
					 | 
				
			||||||
    function gtag() { dataLayer.push(arguments); }
 | 
					 | 
				
			||||||
    gtag(\`js\`, new Date());
 | 
					 | 
				
			||||||
    gtag(\`config\`, \`${tagId}\`, { send_page_view: false });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    document.addEventListener(\`nav\`, () => {
 | 
					 | 
				
			||||||
      gtag(\`event\`, \`page_view\`, {
 | 
					 | 
				
			||||||
        page_title: document.title,
 | 
					 | 
				
			||||||
        page_location: location.href,
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });`)
 | 
					 | 
				
			||||||
  } else if (cfg.analytics?.provider === "plausible") {
 | 
					 | 
				
			||||||
    componentResources.afterDOMLoaded.push(plausibleScript)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // spa
 | 
					 | 
				
			||||||
  if (cfg.enableSPA) {
 | 
					 | 
				
			||||||
    componentResources.afterDOMLoaded.push(spaRouterScript)
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    componentResources.afterDOMLoaded.push(`
 | 
					 | 
				
			||||||
      window.spaNavigate = (url, _) => window.location.assign(url)
 | 
					 | 
				
			||||||
      const event = new CustomEvent("nav", { detail: { slug: document.body.dataset.slug } })
 | 
					 | 
				
			||||||
      document.dispatchEvent(event)`)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (reloadScript) {
 | 
					 | 
				
			||||||
    staticResources.js.push({
 | 
					 | 
				
			||||||
      loadTime: "afterDOMReady",
 | 
					 | 
				
			||||||
      contentType: "inline",
 | 
					 | 
				
			||||||
      script: `
 | 
					 | 
				
			||||||
        const socket = new WebSocket('ws://localhost:3001')
 | 
					 | 
				
			||||||
        socket.addEventListener('message', () => document.location.reload())
 | 
					 | 
				
			||||||
      `,
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function emitContent(ctx: BuildCtx, content: ProcessedContent[]) {
 | 
					export async function emitContent(ctx: BuildCtx, content: ProcessedContent[]) {
 | 
				
			||||||
  const { argv, cfg } = ctx
 | 
					  const { argv, cfg } = ctx
 | 
				
			||||||
  const perf = new PerfTimer()
 | 
					  const perf = new PerfTimer()
 | 
				
			||||||
@@ -98,27 +23,8 @@ export async function emitContent(ctx: BuildCtx, content: ProcessedContent[]) {
 | 
				
			|||||||
    return pathToPage
 | 
					    return pathToPage
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // initialize from plugins
 | 
					 | 
				
			||||||
  const staticResources = getStaticResourcesFromPlugins(cfg.plugins)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // component specific scripts and styles
 | 
					 | 
				
			||||||
  const componentResources = getComponentResources(cfg.plugins)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // 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, staticResources, componentResources)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  let emittedFiles = 0
 | 
					  let emittedFiles = 0
 | 
				
			||||||
  const emittedResources = await emitComponentResources(cfg.configuration, componentResources, emit)
 | 
					  const staticResources = getStaticResourcesFromPlugins(cfg.plugins)
 | 
				
			||||||
  if (argv.verbose) {
 | 
					 | 
				
			||||||
    for (const file of emittedResources) {
 | 
					 | 
				
			||||||
      emittedFiles += 1
 | 
					 | 
				
			||||||
      console.log(`[emit:Resources] ${file}`)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // emitter plugins
 | 
					 | 
				
			||||||
  for (const emitter of cfg.plugins.emitters) {
 | 
					  for (const emitter of cfg.plugins.emitters) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const emitted = await emitter.emit(ctx, content, staticResources, emit)
 | 
					      const emitted = await emitter.emit(ctx, content, staticResources, emit)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user