From 8f91a56ab2e55fb27d7dbdea2b2fe2cfe9433537 Mon Sep 17 00:00:00 2001 From: Alan Daniel Date: Sat, 18 Apr 2026 18:42:28 -0400 Subject: [PATCH] ci(dashboard): redeploy on UI package changes; fix SSR shiki stub Trigger production deploy when workspace packages the dashboard depends on change. Extend the Cloudflare SSR shiki stub for shiki/core and fine-grained @shikijs/langs and @shikijs/themes imports so Rollup can build server chunks. --- .../workflows/dashboard-deploy-production.yml | 3 ++ apps/dashboard/vite.config.ts | 51 +++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dashboard-deploy-production.yml b/.github/workflows/dashboard-deploy-production.yml index a077ba3..c50e0f9 100644 --- a/.github/workflows/dashboard-deploy-production.yml +++ b/.github/workflows/dashboard-deploy-production.yml @@ -5,6 +5,9 @@ on: branches: [main] paths: - "apps/dashboard/**" + - "packages/ui/**" + - "packages/icons/**" + - "packages/typescript-config/**" - "scripts/generate-wrangler-dashboard-config.mjs" - "scripts/run-d1-migrations.mjs" - ".github/workflows/dashboard-deploy-production.yml" diff --git a/apps/dashboard/vite.config.ts b/apps/dashboard/vite.config.ts index ad0742b..bbfdadf 100644 --- a/apps/dashboard/vite.config.ts +++ b/apps/dashboard/vite.config.ts @@ -91,7 +91,7 @@ function getTunnelServerConfig(): import("vite").UserConfig["server"] { // client-side so the server never needs the real implementation. function shikiSSRStub(): import("vite").Plugin { const SHIKI_RE = /^(shiki|@shikijs\/)/; - const STUB = ` + const DEFAULT_STUB = ` export const bundledLanguages = {}; export const bundledThemes = {}; export const createHighlighter = () => Promise.resolve({}); @@ -105,6 +105,36 @@ export const stringifyTokenStyle = () => ""; export const transformerStyleToClass = () => ({}); export default {};`; + // "shiki/core" re-exports "@shikijs/core" (fine-grained / createHighlighterCore). + // "@shikijs/rehype" imports isSpecialLang from "shiki/core" during SSR analysis. + const CORE_STUB = ` +const mockHighlighter = {}; +export async function createHighlighterCore() { + return mockHighlighter; +} +export function createHighlighterCoreSync() { + return mockHighlighter; +} +export const getSingletonHighlighterCore = createHighlighterCore; +export function makeSingletonHighlighterCore(fn) { + return (opts) => fn(opts); +} +export function isPlainLang(lang) { + return !lang || ["plaintext", "txt", "text", "plain"].includes(lang); +} +export function isSpecialLang(lang) { + return lang === "ansi" || isPlainLang(lang); +} +export function isNoneTheme(theme) { + return theme === "none"; +} +export function isSpecialTheme(theme) { + return isNoneTheme(theme); +}`; + + const LANG_STUB = "export default [];"; + const THEME_STUB = "export default Object.freeze({});"; + return { name: "shiki-ssr-stub", enforce: "pre", @@ -116,9 +146,24 @@ export default {};`; }, }, load(id) { - if (id.startsWith("\0shiki-stub:")) { - return STUB; + if (!id.startsWith("\0shiki-stub:")) { + return; + } + const source = id.slice("\0shiki-stub:".length); + if ( + source === "shiki/core" || + source === "@shikijs/core" || + source.startsWith("@shikijs/core/") + ) { + return CORE_STUB; + } + if (source.startsWith("@shikijs/langs/")) { + return LANG_STUB; + } + if (source.startsWith("@shikijs/themes/")) { + return THEME_STUB; } + return DEFAULT_STUB; }, }; }