2025-02-24 16:18:36 +08:00
|
|
|
|
// @ts-check
|
2025-03-28 22:14:16 +08:00
|
|
|
|
import { defineConfig } from "astro/config";
|
2025-02-24 16:18:36 +08:00
|
|
|
|
|
2025-03-28 22:14:16 +08:00
|
|
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
|
|
|
import mdx from "@astrojs/mdx";
|
|
|
|
|
import react from "@astrojs/react";
|
|
|
|
|
import remarkEmoji from "remark-emoji";
|
|
|
|
|
import rehypeExternalLinks from "rehype-external-links";
|
|
|
|
|
import sitemap from "@astrojs/sitemap";
|
|
|
|
|
import fs from "node:fs";
|
|
|
|
|
import path from "node:path";
|
2025-04-19 11:43:47 +08:00
|
|
|
|
import swup from "@swup/astro"
|
2025-03-28 22:14:16 +08:00
|
|
|
|
import { SITE_URL } from "./src/consts";
|
2025-04-25 00:01:44 +08:00
|
|
|
|
import pagefind from "astro-pagefind";
|
|
|
|
|
import compressor from "astro-compressor";
|
2025-03-08 18:16:42 +08:00
|
|
|
|
|
2025-03-28 22:14:16 +08:00
|
|
|
|
import vercel from "@astrojs/vercel";
|
2025-03-09 14:37:44 +08:00
|
|
|
|
|
2025-04-25 00:01:44 +08:00
|
|
|
|
import expressiveCode from "astro-expressive-code";
|
|
|
|
|
import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers";
|
|
|
|
|
import { pluginCollapsibleSections } from "@expressive-code/plugin-collapsible-sections";
|
|
|
|
|
|
2025-03-08 18:16:42 +08:00
|
|
|
|
function getArticleDate(articleId) {
|
|
|
|
|
try {
|
2025-03-10 21:12:16 +08:00
|
|
|
|
// 处理多级目录的文章路径
|
2025-03-28 22:14:16 +08:00
|
|
|
|
const mdPath = path.join(process.cwd(), "src/content", articleId + ".md");
|
|
|
|
|
const mdxPath = path.join(process.cwd(), "src/content", articleId + ".mdx");
|
|
|
|
|
|
2025-03-10 21:12:16 +08:00
|
|
|
|
let filePath = fs.existsSync(mdPath) ? mdPath : mdxPath;
|
2025-03-28 22:14:16 +08:00
|
|
|
|
|
2025-03-10 21:12:16 +08:00
|
|
|
|
if (fs.existsSync(filePath)) {
|
2025-03-28 22:14:16 +08:00
|
|
|
|
const content = fs.readFileSync(filePath, "utf-8");
|
2025-03-08 18:16:42 +08:00
|
|
|
|
const match = content.match(/date:\s*(\d{4}-\d{2}-\d{2})/);
|
|
|
|
|
if (match) {
|
|
|
|
|
return new Date(match[1]).toISOString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2025-03-28 22:14:16 +08:00
|
|
|
|
console.error("Error reading article date:", error);
|
2025-03-08 18:16:42 +08:00
|
|
|
|
}
|
2025-03-10 21:12:16 +08:00
|
|
|
|
return new Date().toISOString(); // 如果没有日期,返回当前时间
|
2025-03-08 18:16:42 +08:00
|
|
|
|
}
|
2025-03-03 21:16:16 +08:00
|
|
|
|
|
2025-02-24 16:18:36 +08:00
|
|
|
|
// https://astro.build/config
|
2025-03-03 21:16:16 +08:00
|
|
|
|
export default defineConfig({
|
2025-03-09 14:37:44 +08:00
|
|
|
|
site: SITE_URL,
|
2025-03-28 22:14:16 +08:00
|
|
|
|
output: "static",
|
|
|
|
|
trailingSlash: "ignore",
|
2025-03-09 14:37:44 +08:00
|
|
|
|
|
2025-03-08 18:16:42 +08:00
|
|
|
|
build: {
|
2025-03-28 22:14:16 +08:00
|
|
|
|
format: "directory",
|
2025-03-08 18:16:42 +08:00
|
|
|
|
},
|
2025-03-09 14:37:44 +08:00
|
|
|
|
|
2025-03-03 21:16:16 +08:00
|
|
|
|
vite: {
|
2025-03-09 01:11:43 +08:00
|
|
|
|
plugins: [tailwindcss()],
|
2025-03-03 21:16:16 +08:00
|
|
|
|
},
|
|
|
|
|
|
2025-03-08 18:16:42 +08:00
|
|
|
|
integrations: [
|
2025-04-25 00:01:44 +08:00
|
|
|
|
expressiveCode({
|
|
|
|
|
themes: ['github-light', 'dracula'],
|
|
|
|
|
themeCssSelector: (theme) =>
|
|
|
|
|
theme.name === 'dracula' ? '[data-theme=dark]' : '[data-theme=light]',
|
|
|
|
|
useDarkModeMediaQuery: false,
|
|
|
|
|
|
|
|
|
|
plugins: [
|
|
|
|
|
pluginLineNumbers(),
|
|
|
|
|
pluginCollapsibleSections(),
|
2025-03-10 15:15:30 +08:00
|
|
|
|
],
|
2025-04-25 00:01:44 +08:00
|
|
|
|
defaultProps: {
|
|
|
|
|
showLineNumbers: true,
|
|
|
|
|
collapseStyle: 'collapsible-auto',
|
|
|
|
|
},
|
|
|
|
|
frames: {
|
|
|
|
|
extractFileNameFromCode: true,
|
|
|
|
|
},
|
|
|
|
|
styleOverrides: {
|
|
|
|
|
// 核心样式设置
|
|
|
|
|
borderRadius: '0.5rem',
|
|
|
|
|
borderWidth: '0.5px',
|
|
|
|
|
codeFontSize: '0.9rem',
|
|
|
|
|
codeFontFamily: "'JetBrains Mono', Menlo, Monaco, Consolas, 'Courier New', monospace",
|
|
|
|
|
codeLineHeight: '1.5',
|
|
|
|
|
codePaddingInline: '1.5rem',
|
|
|
|
|
codePaddingBlock: '1.2rem',
|
|
|
|
|
// 框架样式设置
|
|
|
|
|
frames: {
|
|
|
|
|
shadowColor: 'rgba(0, 0, 0, 0.12)',
|
|
|
|
|
editorActiveTabBackground: '#ffffff',
|
|
|
|
|
editorTabBarBackground: '#f5f5f5',
|
|
|
|
|
terminalBackground: '#1a1a1a',
|
|
|
|
|
terminalTitlebarBackground: '#333333',
|
|
|
|
|
},
|
|
|
|
|
// 文本标记样式
|
|
|
|
|
textMarkers: {
|
|
|
|
|
defaultChroma: 'rgba(255, 255, 0, 0.2)',
|
|
|
|
|
},
|
2025-03-28 22:14:16 +08:00
|
|
|
|
},
|
2025-03-10 15:15:30 +08:00
|
|
|
|
}),
|
2025-04-25 00:01:44 +08:00
|
|
|
|
|
|
|
|
|
// MDX 集成配置
|
|
|
|
|
mdx(),
|
2025-04-19 11:43:47 +08:00
|
|
|
|
swup(),
|
2025-03-08 18:16:42 +08:00
|
|
|
|
react(),
|
2025-04-25 00:01:44 +08:00
|
|
|
|
pagefind(),
|
2025-03-08 18:16:42 +08:00
|
|
|
|
sitemap({
|
2025-03-28 22:14:16 +08:00
|
|
|
|
filter: (page) => !page.includes("/api/"),
|
2025-03-08 18:16:42 +08:00
|
|
|
|
serialize(item) {
|
|
|
|
|
if (!item) return undefined;
|
|
|
|
|
|
|
|
|
|
// 文章页面
|
2025-03-28 22:14:16 +08:00
|
|
|
|
if (item.url.includes("/articles/")) {
|
2025-03-08 18:16:42 +08:00
|
|
|
|
// 从 URL 中提取文章 ID
|
2025-03-28 22:14:16 +08:00
|
|
|
|
const articleId = item.url
|
|
|
|
|
.replace(SITE_URL + "/articles/", "")
|
|
|
|
|
.replace(/\/$/, "");
|
2025-03-08 18:16:42 +08:00
|
|
|
|
const publishDate = getArticleDate(articleId);
|
2025-03-10 21:12:16 +08:00
|
|
|
|
return {
|
|
|
|
|
...item,
|
|
|
|
|
priority: 0.8,
|
2025-03-28 22:14:16 +08:00
|
|
|
|
lastmod: publishDate,
|
2025-03-10 21:12:16 +08:00
|
|
|
|
};
|
2025-03-08 18:16:42 +08:00
|
|
|
|
}
|
|
|
|
|
// 其他页面
|
|
|
|
|
else {
|
|
|
|
|
let priority = 0.7; // 默认优先级
|
2025-03-28 22:14:16 +08:00
|
|
|
|
|
2025-03-08 18:16:42 +08:00
|
|
|
|
// 首页最高优先级
|
2025-03-28 22:14:16 +08:00
|
|
|
|
if (item.url === SITE_URL + "/") {
|
2025-03-08 18:16:42 +08:00
|
|
|
|
priority = 1.0;
|
|
|
|
|
}
|
|
|
|
|
// 文章列表页次高优先级
|
2025-03-28 22:14:16 +08:00
|
|
|
|
else if (item.url === SITE_URL + "/articles/") {
|
2025-03-08 18:16:42 +08:00
|
|
|
|
priority = 0.9;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...item,
|
2025-03-28 22:14:16 +08:00
|
|
|
|
priority,
|
2025-03-08 18:16:42 +08:00
|
|
|
|
};
|
|
|
|
|
}
|
2025-03-28 22:14:16 +08:00
|
|
|
|
},
|
|
|
|
|
}),
|
2025-04-25 00:01:44 +08:00
|
|
|
|
// 添加压缩插件 (必须放在最后位置)
|
|
|
|
|
compressor()
|
2025-03-08 18:16:42 +08:00
|
|
|
|
],
|
2025-03-09 14:37:44 +08:00
|
|
|
|
|
2025-03-03 21:16:16 +08:00
|
|
|
|
// Markdown 配置
|
|
|
|
|
markdown: {
|
2025-04-25 00:01:44 +08:00
|
|
|
|
syntaxHighlight: false, // 禁用默认的语法高亮,使用expressiveCode代替
|
2025-03-03 21:16:16 +08:00
|
|
|
|
remarkPlugins: [
|
2025-03-29 16:09:16 +08:00
|
|
|
|
[remarkEmoji, { emoticon: false, padded: true }]
|
2025-03-03 21:16:16 +08:00
|
|
|
|
],
|
|
|
|
|
rehypePlugins: [
|
|
|
|
|
[rehypeExternalLinks, { target: '_blank', rel: ['nofollow', 'noopener', 'noreferrer'] }]
|
|
|
|
|
],
|
2025-03-10 15:15:30 +08:00
|
|
|
|
gfm: true,
|
2025-03-28 22:14:16 +08:00
|
|
|
|
// 设置 remark-rehype 选项,以控制HTML处理
|
|
|
|
|
remarkRehype: {
|
|
|
|
|
// 保留原始HTML格式,但仅在非代码块区域
|
|
|
|
|
allowDangerousHtml: true,
|
|
|
|
|
// 确保代码块内容不被解析
|
|
|
|
|
passThrough: ['code']
|
|
|
|
|
},
|
2025-03-09 14:37:44 +08:00
|
|
|
|
},
|
|
|
|
|
|
2025-03-28 22:14:16 +08:00
|
|
|
|
adapter: vercel(),
|
|
|
|
|
});
|