feat: 删除无用依赖,shiki lang使用懒加载方式加载语言

This commit is contained in:
2026-08-16 13:29:58 +08:00
parent 070a63133d
commit be2e6f1ae0
9 changed files with 54 additions and 1131 deletions

10
.dockerignore Normal file
View File

@@ -0,0 +1,10 @@
node_modules/
.git/
.idea/
dist/
.astro/
.vscode/
.claude/
*.tar.gz
*.log
.DS_Store

View File

@@ -1,6 +1,5 @@
// @ts-check // @ts-check
import {defineConfig} from 'astro/config'; import {defineConfig} from 'astro/config';
import solidJs from '@astrojs/solid-js';
import node from '@astrojs/node'; import node from '@astrojs/node';
// https://astro.build/config // https://astro.build/config
@@ -10,16 +9,14 @@ export default defineConfig({
server: { server: {
host: "0.0.0.0", host: "0.0.0.0",
}, },
integrations: [solidJs()],
adapter: node({ adapter: node({
mode: 'standalone' mode: 'standalone'
}), }),
vite: { vite: {
plugins: [],
server: { server: {
watch: { ...(process.argv.includes('dev')
usePolling: true, ? {watch: {usePolling: true}}
}, : {}),
}, }
}, }
}); });

View File

@@ -11,17 +11,14 @@
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "11.0.2", "@astrojs/node": "11.0.2",
"@astrojs/solid-js": "^5.1.3",
"astro": "^7.0.6", "astro": "^7.0.6",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"dayjs": "^1.11.21", "dayjs": "^1.11.21",
"github-markdown-css": "^5.9.0",
"jsdom": "^29.1.1", "jsdom": "^29.1.1",
"ky": "^2.0.2", "ky": "^2.0.2",
"modern-normalize": "^3.0.1", "modern-normalize": "^3.0.1",
"photoswipe": "^5.4.4", "photoswipe": "^5.4.4",
"shiki": "^4.3.1", "shiki": "^4.3.1"
"solid-js": "^1.9.14"
}, },
"volta": { "volta": {
"node": "22.21.1" "node": "22.21.1"

1091
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,13 @@
FROM alpine:3.22 AS base FROM alpine:3.22 AS base
WORKDIR /app WORKDIR /app
RUN apk add --no-cache --update nodejs pnpm RUN apk add --no-cache --update nodejs
FROM base AS install FROM base AS install
RUN apk add --no-cache pnpm
ENV NODE_ENV=production ENV NODE_ENV=production
COPY package.json pnpm-lock.yaml ./ COPY package.json pnpm-lock.yaml ./
RUN pnpm install RUN pnpm install --frozen-lockfile
FROM install AS build FROM install AS build
COPY . . COPY . .

View File

@@ -5,41 +5,37 @@ const DEFAULT_THEME = 'github-dark-dimmed'
const highlighter = await createHighlighter({ const highlighter = await createHighlighter({
themes: [DEFAULT_THEME], themes: [DEFAULT_THEME],
langs: [ langs: []
"bash",
"json",
"yaml",
"xml",
"html",
"css",
"scss",
"javascript",
"typescript",
"jsx",
"tsx",
"vue",
"markdown",
"sql",
"python",
"go",
"dockerfile",
"nginx"
]
}) })
const resolveLang = (lang: string) => { const SUPPORTED_LANGS = [
const supported = highlighter.getLoadedLanguages?.() || [] "bash", "json", "yaml", "xml", "html", "css", "scss",
if (!lang) return 'text' "javascript", "typescript", "jsx", "tsx", "vue",
if (supported.includes(lang)) return lang "markdown", "sql", "python", "go", "dockerfile", "nginx"
return 'text' ] as const
const loadedLangs = new Set<string>(['text'])
type SupportedLang = typeof SUPPORTED_LANGS[number]
const supportedSet = new Set<string>(SUPPORTED_LANGS)
const ensureLangLoaded = async (lang: string): Promise<string> => {
if (lang === 'text' || loadedLangs.has(lang)) return lang
if (!supportedSet.has(lang)) return 'text'
try {
await highlighter.loadLanguage(lang as SupportedLang)
loadedLangs.add(lang)
return lang
} catch {
return 'text'
}
} }
export const processHtmlWithJsdom = async (rawHtml: string) => { export const processHtmlWithJsdom = async (rawHtml: string) => {
const dom = new JSDOM(rawHtml) const dom = new JSDOM(rawHtml)
const document = dom.window.document const document = dom.window.document
// 高亮处理代码块
const codeBlocks = document.querySelectorAll('pre code') const codeBlocks = document.querySelectorAll('pre code')
for (const codeBlock of codeBlocks) { for (const codeBlock of codeBlocks) {
@@ -55,9 +51,8 @@ export const processHtmlWithJsdom = async (rawHtml: string) => {
} }
} }
lang = resolveLang(lang) lang = await ensureLangLoaded(lang) // ← 唯一改动点:按需加载
// 高亮
const highlighted = highlighter.codeToHtml(codeContent, { const highlighted = highlighter.codeToHtml(codeContent, {
lang, lang,
theme: DEFAULT_THEME, theme: DEFAULT_THEME,
@@ -116,5 +111,5 @@ export const processHtmlWithJsdom = async (rawHtml: string) => {
} }
} }
return dom.serialize() return document.body.innerHTML
} }

View File

@@ -140,6 +140,8 @@ const published_at = formatDatetime(data.published_at, "YYYY.MM.DD");
const article = document.querySelector(".markdown-body")!; const article = document.querySelector(".markdown-body")!;
const images = Array.from(article.querySelectorAll("img")); const images = Array.from(article.querySelectorAll("img"));
if(images.length === 0) return
const waitImageLoaded = (img: HTMLImageElement) => { const waitImageLoaded = (img: HTMLImageElement) => {
if (img.complete && img.naturalWidth > 0 && img.naturalHeight > 0) { if (img.complete && img.naturalWidth > 0 && img.naturalHeight > 0) {
return Promise.resolve(); return Promise.resolve();

View File

View File

@@ -13,8 +13,6 @@
"@/*": [ "@/*": [
"src/*" "src/*"
] ]
}, }
"jsx": "preserve",
"jsxImportSource": "solid-js"
} }
} }