build: add static-site target, macro placeholders, and heading guardrails - #1369
build: add static-site target, macro placeholders, and heading guardrails#1369paulirish wants to merge 10 commits into
Conversation
|
You can look at https://github.com/GoogleChrome/modern-web-guidance-src/actions/runs/32760160368?pr=1369 to see the net effect of the guide macro changes. (i see a bug im about to fix.. EDIT: just kidding its fine. the nuance was retained! woo.) |
| content: (args, filePath, options) => { | ||
| const [featureId, bcdKey] = args; | ||
| if (options?.target === 'static-site') { | ||
| return `[BASELINE_STATUS: ${featureId}]`; |
There was a problem hiding this comment.
I assume this requires a script on the DevSite side to convert this format into the BaselineStatus macro.
Why not output the DevSite macro directly? Do we expect to use any other static sites than DevSite?
| return `[BASELINE_STATUS: ${featureId}]`; | |
| return `{{ macros.BaselineStatus('${featureId}') }}`; |
Alternatively, we could keep the unrendered MWG macro syntax as the placeholder, rather than introducing the new square bracket format.
| content: (args, filePath, options) => { | ||
| const [featureId, bcdKey] = args; | ||
| if (options?.target === 'static-site') { | ||
| return `[BASELINE_STATUS: ${featureId}]`; |
There was a problem hiding this comment.
do we need to include the bcdKey here too?
| const h1Match = markdownBody.match(/^#\s+(.+)$/m); | ||
| const title = h1Match ? h1Match[1].trim() : (data.title || formatTitle(id)); |
There was a problem hiding this comment.
use marked here?
const tokens = marked.lexer(markdownBody);
const h1Token = tokens.find((t: any) => t.type === 'heading' && t.depth === 1);
const title = h1Token ? (h1Token as any).text.trim() : (data.title || formatTitle(id));
| fs.copyFileSync(paths.cachedTs, OUTPUT_FILE); | ||
| } else if (target === 'static-site') { | ||
| fs.mkdirSync(outputDir, { recursive: true }); | ||
| fs.cpSync(paths.cachedGuides, outputDir, { recursive: true }); |
There was a problem hiding this comment.
remove existing outputDir if it exists? to prune stale files
if (fs.existsSync(outputDir)) {
fs.rmSync(outputDir, { recursive: true, force: true });
}
| * Validates that a non-stub guide has either a frontmatter title or an explicit H1 heading, | ||
| * and that any H1 heading is not vague. | ||
| */ | ||
| export function validateGuideTitle(body: string, relativePath: string, data?: GuideData, options?: { requireTitle?: boolean }): string[] { |
There was a problem hiding this comment.
this function is unused except in test
| const target = options?.target || 'local-dev'; | ||
|
|
||
| if (target === 'static-site') { | ||
| return `[${guideInfo.name}](../${guideInfo.category}/${guideInfo.name}.md)`; |
There was a problem hiding this comment.
should the part in [ ] be the formatted name? [${formatTitle(guideInfo.name)}]
Provides a dedicated
static-sitecompilation pipeline to export processed markdown guides for DevSite and external documentation platforms, serializes macro placeholders for downstream hydration, and introduces linting guardrails for heading titles and HTML tag escaping.Key Changes
Static-Site Build Target (
serving/scripts/build-guides.ts):--target static-site(pnpm run build:static-site) to generate standalone markdown guides indist/static-site-guideswithout calculating vector embeddings.title,description,category) with safe string escaping while preserving author H1 titles and stripping duplicates from compiled bodies.dist/.cache/static-site) to skip rebuilding unchanged guides.Macro Compilation for External Sites (
serving/lib/macros.ts):BASELINE_STATUS: Serializes into placeholder tags ([BASELINE_STATUS: <feature-id>]) for downstream DevSite hydration rather than baking in static text.GUIDE_REF: Emits standard relative markdown links ([title](../<category>/<guide-name>.md)) understatic-siteinstead of CLI retrieve commands (npx modern-web-guidance retrieve ...).Validation Guardrails (
lib/guide-validation.ts):validateHeadingsandvalidateGuideTitleto disallow vague top-level H1s (# Overview,# Introduction,# Guide,# Title) and require a clear title on non-stub guides while permitting subsection overviews (e.g.## Overview).validateHtmlTagsto catch unescaped HTML element literals with accurate line number tracking while permitting safe typographic inline tags (<kbd>,<br>,<wbr>) and comments.Guide Title Hygiene:
html,persistent-top-layer-ui,move-dom-element-without-losing-state, andagentic-javascript-tools.# Overviewindeclarative-dialog-popover-controlwith# Declarative Dialog and Popover Control.