feat: optimize blog build and deployment
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
node_modules
|
||||
dist
|
||||
src/.vuepress/dist
|
||||
src/.vuepress/.cache
|
||||
src/.vuepress/.temp
|
||||
.cache
|
||||
.temp
|
||||
.npm
|
||||
.env
|
||||
.git
|
||||
.gitignore
|
||||
*.log
|
||||
coverage
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ENCRYPT_PASSWORD=local-dev-password
|
||||
@@ -3,7 +3,6 @@ node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
package-lock.json
|
||||
|
||||
# VuePress
|
||||
src/.vuepress/.cache/
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
node_modules
|
||||
src/.vuepress/.cache
|
||||
src/.vuepress/.temp
|
||||
src/.vuepress/dist
|
||||
package-lock.json
|
||||
*.md
|
||||
src/**/*.md
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.md",
|
||||
"options": {
|
||||
"proseWrap": "preserve"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+9
-2
@@ -2,12 +2,19 @@ FROM node:20-alpine AS build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ARG ENCRYPT_PASSWORD
|
||||
ENV ENCRYPT_PASSWORD=$ENCRYPT_PASSWORD
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
RUN --mount=type=cache,target=/root/.npm npm install --include=optional
|
||||
|
||||
COPY . .
|
||||
RUN npm run docs:build
|
||||
|
||||
FROM nginx:1.25-alpine
|
||||
FROM nginx:1.27-alpine
|
||||
|
||||
COPY --from=build /app/src/.vuepress/dist /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
||||
CMD wget -qO- http://127.0.0.1/ >/dev/null 2>&1 || exit 1
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
.PHONY: up down
|
||||
.PHONY: up down ensure-env
|
||||
|
||||
up:
|
||||
docker compose up -d --build
|
||||
ensure-env:
|
||||
@if [ ! -f .env ]; then \
|
||||
cp .env.example .env; \
|
||||
echo "Created .env from .env.example. Edit ENCRYPT_PASSWORD in .env for deployment."; \
|
||||
fi
|
||||
|
||||
up: ensure-env
|
||||
docker compose --env-file .env up -d --build
|
||||
|
||||
down:
|
||||
docker compose down
|
||||
docker compose --env-file .env down
|
||||
|
||||
@@ -3,6 +3,34 @@ services:
|
||||
image: myblog:latest
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
ENCRYPT_PASSWORD: ${ENCRYPT_PASSWORD:?Set ENCRYPT_PASSWORD in .env or shell before building}
|
||||
environment:
|
||||
ENCRYPT_PASSWORD: ${ENCRYPT_PASSWORD:?Set ENCRYPT_PASSWORD in .env or shell before starting}
|
||||
ports:
|
||||
- '51888:80'
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ['CMD', 'wget', '-qO-', 'http://127.0.0.1/']
|
||||
interval: 30s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: '10m'
|
||||
max-file: '3'
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.00'
|
||||
memory: 256M
|
||||
reservations:
|
||||
memory: 64M
|
||||
networks:
|
||||
- myblog-net
|
||||
|
||||
networks:
|
||||
myblog-net:
|
||||
driver: bridge
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import js from '@eslint/js';
|
||||
import vue from 'eslint-plugin-vue';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: [
|
||||
'node_modules/**',
|
||||
'src/.vuepress/.cache/**',
|
||||
'src/.vuepress/.temp/**',
|
||||
'src/.vuepress/dist/**',
|
||||
],
|
||||
},
|
||||
js.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
...vue.configs['flat/recommended'],
|
||||
{
|
||||
files: ['**/*.{ts,vue}'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
clearTimeout: 'readonly',
|
||||
console: 'readonly',
|
||||
document: 'readonly',
|
||||
fetch: 'readonly',
|
||||
setTimeout: 'readonly',
|
||||
window: 'readonly',
|
||||
},
|
||||
parserOptions: {
|
||||
parser: tseslint.parser,
|
||||
extraFileExtensions: ['.vue'],
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/html-indent': ['error', 2],
|
||||
'vue/max-attributes-per-line': 'off',
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['src/.vuepress/**/*.ts'],
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
},
|
||||
},
|
||||
];
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types
|
||||
application/javascript
|
||||
application/json
|
||||
application/xml
|
||||
image/svg+xml
|
||||
text/css
|
||||
text/plain
|
||||
text/xml;
|
||||
|
||||
location ~* \.(?:css|js|mjs|woff2?|ttf|otf|eot|ico|png|jpg|jpeg|gif|webp|avif|svg)$ {
|
||||
try_files $uri =404;
|
||||
access_log off;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
}
|
||||
|
||||
location ~* \.html$ {
|
||||
try_files $uri =404;
|
||||
add_header Cache-Control "no-cache";
|
||||
}
|
||||
|
||||
location = /robots.txt {
|
||||
try_files $uri =404;
|
||||
add_header Cache-Control "public, max-age=3600";
|
||||
}
|
||||
|
||||
location = /sitemap.xml {
|
||||
try_files $uri =404;
|
||||
add_header Cache-Control "public, max-age=3600";
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
add_header Cache-Control "no-cache";
|
||||
}
|
||||
}
|
||||
Generated
+9211
File diff suppressed because it is too large
Load Diff
+14
-6
@@ -9,15 +9,23 @@
|
||||
"docs:clean-dev": "vuepress-vite dev src --clean-cache",
|
||||
"docs:dev": "vuepress-vite dev src",
|
||||
"docs:update-package": "npx vp-update",
|
||||
"format": "prettier \"*.{js,json,yml}\" \"src/.vuepress/**/*.{ts,vue,scss}\" --write",
|
||||
"format:check": "prettier \"*.{js,json,yml}\" \"src/.vuepress/**/*.{ts,vue,scss}\" --check",
|
||||
"lint": "eslint \"src/.vuepress/**/*.{ts,vue}\" eslint.config.js",
|
||||
"update:browsers": "npx update-browserslist-db@latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vuepress/bundler-vite": "2.0.0-rc.22",
|
||||
"@vuepress/plugin-git": "2.0.0-rc.99",
|
||||
"@vuepress/plugin-search": "2.0.0-rc.99",
|
||||
"sass-embedded": "^1.87.0",
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@vuepress/bundler-vite": "^2.0.0-rc.28",
|
||||
"@vuepress/plugin-git": "^2.0.0-rc.128",
|
||||
"@vuepress/plugin-search": "^2.0.0-rc.128",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-vue": "^10.6.1",
|
||||
"prettier": "^3.6.2",
|
||||
"sass-embedded": "^1.99.0",
|
||||
"typescript-eslint": "^8.46.4",
|
||||
"vue": "^3.5.13",
|
||||
"vuepress": "2.0.0-rc.22",
|
||||
"vuepress-theme-hope": "2.0.0-rc.85"
|
||||
"vuepress": "^2.0.0-rc.28",
|
||||
"vuepress-theme-hope": "^2.0.0-rc.106"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,148 @@
|
||||
<script setup lang="ts">
|
||||
import BlogHero from "vuepress-theme-hope/blog/components/BlogHero.js";
|
||||
import HitokotoBlogHero from "vuepress-theme-hope/presets/HitokotoBlogHero.js";
|
||||
import { computed } from 'vue';
|
||||
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { usePageFrontmatter, withBase } from 'vuepress/client';
|
||||
|
||||
import HeroSlideDownButton from 'vuepress-theme-hope/components/home/HeroSlideDownButton';
|
||||
import 'vuepress-theme-hope/styles/blog/blog-hero.scss';
|
||||
import 'vuepress-theme-hope/presets/hitokoto-blog-hero.scss';
|
||||
|
||||
interface BlogHomeFrontmatter {
|
||||
bgImage?: string | false;
|
||||
bgImageDark?: string | false;
|
||||
bgImageStyle?: string | Record<string, string>;
|
||||
hero?: boolean;
|
||||
heroFullScreen?: boolean;
|
||||
}
|
||||
|
||||
interface HitokotoResult {
|
||||
hitokoto: string;
|
||||
from?: string;
|
||||
}
|
||||
|
||||
const fallbackText = '山高路远,看世界,也找自己。';
|
||||
const fallbackAuthor = '氓氓小栈';
|
||||
const defaultHero = '//theme-hope-assets.vuejs.press/hero/default.jpg';
|
||||
const frontmatter = usePageFrontmatter<BlogHomeFrontmatter>();
|
||||
|
||||
const resolveImage = (image: string): string =>
|
||||
image.startsWith('//') || /^https?:\/\//.test(image) ? image : withBase(image);
|
||||
|
||||
const background = computed(() => ({
|
||||
image:
|
||||
typeof frontmatter.value.bgImage === 'string'
|
||||
? resolveImage(frontmatter.value.bgImage)
|
||||
: frontmatter.value.bgImage === false
|
||||
? null
|
||||
: defaultHero,
|
||||
imageDark:
|
||||
typeof frontmatter.value.bgImageDark === 'string'
|
||||
? resolveImage(frontmatter.value.bgImageDark)
|
||||
: null,
|
||||
style: frontmatter.value.bgImageStyle ?? null,
|
||||
}));
|
||||
|
||||
const scrollDown = (): void => {
|
||||
window.scrollTo({
|
||||
top: window.innerHeight - (document.querySelector('[vp-navbar]')?.clientHeight ?? 0),
|
||||
behavior: 'smooth',
|
||||
});
|
||||
};
|
||||
|
||||
const text = ref(fallbackText);
|
||||
const display = ref(fallbackText);
|
||||
const author = ref(fallbackAuthor);
|
||||
|
||||
let isMounted = false;
|
||||
let timer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
const clearRenderTimer = (): void => {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const renderText = async (): Promise<void> => {
|
||||
clearRenderTimer();
|
||||
display.value = '';
|
||||
|
||||
let index = 0;
|
||||
|
||||
const renderNextWord = async (): Promise<void> => {
|
||||
display.value += text.value[index] ?? '';
|
||||
index += 1;
|
||||
|
||||
await nextTick();
|
||||
|
||||
if (isMounted && index < text.value.length) {
|
||||
timer = setTimeout(() => {
|
||||
void renderNextWord();
|
||||
}, 120);
|
||||
}
|
||||
};
|
||||
|
||||
await renderNextWord();
|
||||
};
|
||||
|
||||
const getHitokoto = async (): Promise<void> => {
|
||||
try {
|
||||
const response = await fetch('https://v1.hitokoto.cn');
|
||||
const result = (await response.json()) as HitokotoResult;
|
||||
|
||||
if (result.hitokoto) {
|
||||
text.value = result.hitokoto;
|
||||
author.value = result.from ?? fallbackAuthor;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch hitokoto:', error);
|
||||
}
|
||||
};
|
||||
|
||||
watch(text, () => {
|
||||
void renderText();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
isMounted = true;
|
||||
void getHitokoto();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
isMounted = false;
|
||||
clearRenderTimer();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BlogHero>
|
||||
<template #info="info">
|
||||
<HitokotoBlogHero v-bind="info" />
|
||||
</template>
|
||||
</BlogHero>
|
||||
</template>
|
||||
<div
|
||||
v-if="frontmatter.hero !== false"
|
||||
class="vp-blog-hero"
|
||||
:class="{
|
||||
'hero-fullscreen': frontmatter.heroFullScreen,
|
||||
'no-bg': !background.image,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-if="background.image"
|
||||
class="vp-blog-mask"
|
||||
:class="{ light: background.imageDark }"
|
||||
:style="[{ background: `url(${background.image}) center/cover no-repeat` }, background.style]"
|
||||
/>
|
||||
<div
|
||||
v-if="background.imageDark"
|
||||
class="vp-blog-mask dark"
|
||||
:style="[
|
||||
{ background: `url(${background.imageDark}) center/cover no-repeat` },
|
||||
background.style,
|
||||
]"
|
||||
/>
|
||||
<div class="hitokoto">
|
||||
<p class="hitokoto-text">
|
||||
<span>{{ display }}</span>
|
||||
</p>
|
||||
<p class="hitokoto-author">——「{{ author }}」</p>
|
||||
</div>
|
||||
<HeroSlideDownButton v-if="frontmatter.heroFullScreen" @click="scrollDown" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
+24
-25
@@ -1,38 +1,37 @@
|
||||
import {defineUserConfig} from "vuepress";
|
||||
import {viteBundler} from "@vuepress/bundler-vite";
|
||||
import {getDirname, path} from "vuepress/utils";
|
||||
import theme from "./theme.js";
|
||||
|
||||
import { defineUserConfig } from 'vuepress';
|
||||
import { viteBundler } from '@vuepress/bundler-vite';
|
||||
import { getDirname, path } from 'vuepress/utils';
|
||||
import theme from './theme.js';
|
||||
|
||||
const __dirname = getDirname(import.meta.url);
|
||||
|
||||
export default defineUserConfig({
|
||||
base: "/",
|
||||
base: '/',
|
||||
|
||||
lang: "zh-CN",
|
||||
title: "氓氓小栈",
|
||||
description: "氓氓小栈",
|
||||
lang: 'zh-CN',
|
||||
title: '氓氓小栈',
|
||||
description: '氓氓小栈',
|
||||
theme,
|
||||
bundler: viteBundler({
|
||||
viteOptions: {
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
quietDeps: true,
|
||||
silenceDeprecations: ["if-function"],
|
||||
},
|
||||
},
|
||||
},
|
||||
bundler: viteBundler({
|
||||
viteOptions: {
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
quietDeps: true,
|
||||
silenceDeprecations: ['if-function'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
alias: {
|
||||
"@theme-hope/modules/blog/components/BlogHero": path.resolve(
|
||||
__dirname,
|
||||
"./components/BlogHero.vue",
|
||||
'@theme-hope/components/blog/BlogHero': path.resolve(__dirname, './components/BlogHero.vue'),
|
||||
'@theme-hope/modules/blog/components/BlogHero': path.resolve(
|
||||
__dirname,
|
||||
'./components/BlogHero.vue',
|
||||
),
|
||||
},
|
||||
|
||||
|
||||
// 和 PWA 一起启用
|
||||
// shouldPrefetch: false,
|
||||
// VuePress 默认会预取页面资源;如后续启用 PWA,可按需显式调整。
|
||||
});
|
||||
|
||||
+27
-27
@@ -1,30 +1,30 @@
|
||||
import {navbar} from "vuepress-theme-hope";
|
||||
import { navbar } from 'vuepress-theme-hope';
|
||||
|
||||
export default navbar([
|
||||
"/",
|
||||
{
|
||||
text: "编程",
|
||||
icon: "mdi:code-tags",
|
||||
link: "/programming/",
|
||||
},
|
||||
{
|
||||
text: "工作",
|
||||
icon: "mdi:briefcase",
|
||||
link: "/work/",
|
||||
},
|
||||
{
|
||||
text: "应用",
|
||||
icon: "mdi:application",
|
||||
link: "/apps/",
|
||||
},
|
||||
{
|
||||
text: "工具箱",
|
||||
icon: "mdi:toolbox",
|
||||
link: "/tools/",
|
||||
},
|
||||
{
|
||||
text: "AI",
|
||||
icon: "mdi:robot-outline",
|
||||
link: "/ai/",
|
||||
},
|
||||
'/',
|
||||
{
|
||||
text: '编程',
|
||||
icon: 'mdi:code-tags',
|
||||
link: '/programming/',
|
||||
},
|
||||
{
|
||||
text: '工作',
|
||||
icon: 'mdi:briefcase',
|
||||
link: '/work/',
|
||||
},
|
||||
{
|
||||
text: '应用',
|
||||
icon: 'mdi:application',
|
||||
link: '/apps/',
|
||||
},
|
||||
{
|
||||
text: '工具箱',
|
||||
icon: 'mdi:toolbox',
|
||||
link: '/tools/',
|
||||
},
|
||||
{
|
||||
text: 'AI',
|
||||
icon: 'mdi:robot-outline',
|
||||
link: '/ai/',
|
||||
},
|
||||
]);
|
||||
|
||||
+288
-319
@@ -1,347 +1,316 @@
|
||||
import {sidebar} from "vuepress-theme-hope";
|
||||
import { sidebar } from 'vuepress-theme-hope';
|
||||
|
||||
export default sidebar({
|
||||
"/programming/": [
|
||||
'/programming/': [
|
||||
{
|
||||
text: '前端',
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: 'mdi:vuejs',
|
||||
prefix: 'frontend/',
|
||||
children: [
|
||||
{
|
||||
text: "前端",
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: "mdi:vuejs",
|
||||
prefix: "frontend/",
|
||||
children: [
|
||||
{
|
||||
text: "Vue",
|
||||
icon: "mdi:vuejs",
|
||||
collapsible: true,
|
||||
prefix: "vue/",
|
||||
children: "structure",
|
||||
},
|
||||
{
|
||||
text: "CSS",
|
||||
icon: "mdi:language-css3",
|
||||
collapsible: true,
|
||||
prefix: "css/",
|
||||
children: "structure",
|
||||
},
|
||||
{
|
||||
text: "HTML",
|
||||
icon: "mdi:language-html5",
|
||||
collapsible: true,
|
||||
prefix: "html/",
|
||||
children: "structure",
|
||||
},
|
||||
{
|
||||
text: "开发工具",
|
||||
icon: "mdi:tools",
|
||||
collapsible: true,
|
||||
prefix: "tools/",
|
||||
children: "structure",
|
||||
},
|
||||
]
|
||||
text: 'Vue',
|
||||
icon: 'mdi:vuejs',
|
||||
collapsible: true,
|
||||
prefix: 'vue/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: "后端",
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: "mdi:code-tags",
|
||||
prefix: "backend/",
|
||||
children: [
|
||||
{
|
||||
text: "Java",
|
||||
icon: "mdi:language-java",
|
||||
collapsible: true,
|
||||
prefix: "java/",
|
||||
children: [
|
||||
{
|
||||
text: "框架",
|
||||
icon: "mdi:code-braces",
|
||||
collapsible: true,
|
||||
prefix: "框架/",
|
||||
children: "structure",
|
||||
},
|
||||
{
|
||||
text: "功能整理",
|
||||
icon: "mdi:puzzle",
|
||||
collapsible: true,
|
||||
prefix: "功能整理/",
|
||||
children: [
|
||||
"01XJar.md",
|
||||
"02Maven.md",
|
||||
"03WebSocket和HTTP关系.md",
|
||||
"05防止表单和参数重复提交.md",
|
||||
"06Spring Boot JAR 瘦身与加密.md",
|
||||
"SDKMAN-Java-Maven版本管理.md",
|
||||
"Windows-Jabba-Java版本管理.md",
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "试题",
|
||||
icon: "mdi:comment-question",
|
||||
collapsible: true,
|
||||
prefix: "AI试题/",
|
||||
children: "structure",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Go",
|
||||
icon: "mdi:language-go",
|
||||
collapsible: true,
|
||||
prefix: "go/",
|
||||
children: [
|
||||
{
|
||||
text: "Go基础语法",
|
||||
icon: "mdi:book-open-outline",
|
||||
collapsible: true,
|
||||
prefix: "Go基础语法/",
|
||||
children: [
|
||||
"01Hello World.md",
|
||||
"02变量与类型.md",
|
||||
"03slice和map.md",
|
||||
"04Struct、方法与接收者类型详解.md",
|
||||
"05接口.md",
|
||||
"06错误机制.md",
|
||||
"07从零实现 Mini 日志库.md",
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Go并发模型",
|
||||
icon: "mdi:run-fast",
|
||||
collapsible: true,
|
||||
prefix: "Go并发模型/",
|
||||
children: [
|
||||
"08Goroutine与GPM调度模型.md",
|
||||
"09Channel与单向Channel.md",
|
||||
"10select与超时控制.md",
|
||||
"11context取消与超时.md",
|
||||
"12Mutex与WaitGroup.md",
|
||||
"13atomic原子操作.md",
|
||||
"14并发爬虫实战.md",
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Web开发数据库",
|
||||
icon: "mdi:database-outline",
|
||||
collapsible: true,
|
||||
prefix: "Web开发数据库/",
|
||||
children: [
|
||||
"README.md",
|
||||
"15Gin基础入门.md",
|
||||
"16Gin中间件.md",
|
||||
"17GORM数据库.md",
|
||||
"18GORM事务关联.md",
|
||||
"19Viper配置管理.md",
|
||||
"20Zap日志.md",
|
||||
"21综合实战项目.md",
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "C++",
|
||||
icon: "mdi:language-cpp",
|
||||
collapsible: true,
|
||||
prefix: "c++/",
|
||||
children: "structure",
|
||||
},
|
||||
]
|
||||
text: 'CSS',
|
||||
icon: 'mdi:language-css3',
|
||||
collapsible: true,
|
||||
prefix: 'css/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: "Linux",
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: "mdi:linux",
|
||||
prefix: "linux/",
|
||||
children: [
|
||||
{
|
||||
text: "基础",
|
||||
icon: "mdi:console",
|
||||
collapsible: true,
|
||||
prefix: "基础/",
|
||||
children: "structure",
|
||||
},
|
||||
{
|
||||
text: "Linux_Mint",
|
||||
icon: "simple-icons:linuxmint",
|
||||
collapsible: true,
|
||||
prefix: "Linux_Mint/",
|
||||
children: "structure",
|
||||
},
|
||||
{
|
||||
text: "凝思",
|
||||
icon: "mdi:server",
|
||||
collapsible: true,
|
||||
prefix: "凝思/",
|
||||
children: "structure",
|
||||
},
|
||||
]
|
||||
text: 'HTML',
|
||||
icon: 'mdi:language-html5',
|
||||
collapsible: true,
|
||||
prefix: 'html/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: "Docker",
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: "mdi:docker",
|
||||
prefix: "docker/",
|
||||
children: "structure",
|
||||
}
|
||||
],
|
||||
"/work/": [
|
||||
text: '开发工具',
|
||||
icon: 'mdi:tools',
|
||||
collapsible: true,
|
||||
prefix: 'tools/',
|
||||
children: 'structure',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: '后端',
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: 'mdi:code-tags',
|
||||
prefix: 'backend/',
|
||||
children: [
|
||||
{
|
||||
text: "工作日志",
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: "mdi:file-document-outline",
|
||||
prefix: "log/",
|
||||
children: "structure",
|
||||
text: 'Java',
|
||||
icon: 'mdi:language-java',
|
||||
collapsible: true,
|
||||
prefix: 'java/',
|
||||
children: [
|
||||
{
|
||||
text: '框架',
|
||||
icon: 'mdi:code-braces',
|
||||
collapsible: true,
|
||||
prefix: '框架/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: '功能整理',
|
||||
icon: 'mdi:puzzle',
|
||||
collapsible: true,
|
||||
prefix: '功能整理/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: '试题',
|
||||
icon: 'mdi:comment-question',
|
||||
collapsible: true,
|
||||
prefix: 'AI试题/',
|
||||
children: 'structure',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "项目总结",
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: "mdi:book-open-page-variant",
|
||||
prefix: "project-summary/",
|
||||
children: "structure",
|
||||
text: 'Go',
|
||||
icon: 'mdi:language-go',
|
||||
collapsible: true,
|
||||
prefix: 'go/',
|
||||
children: [
|
||||
{
|
||||
text: 'Go基础语法',
|
||||
icon: 'mdi:book-open-outline',
|
||||
collapsible: true,
|
||||
prefix: 'Go基础语法/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: 'Go并发模型',
|
||||
icon: 'mdi:run-fast',
|
||||
collapsible: true,
|
||||
prefix: 'Go并发模型/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: 'Web开发数据库',
|
||||
icon: 'mdi:database-outline',
|
||||
collapsible: true,
|
||||
prefix: 'Web开发数据库/',
|
||||
children: [
|
||||
'README.md',
|
||||
'15Gin基础入门.md',
|
||||
'16Gin中间件.md',
|
||||
'17GORM数据库.md',
|
||||
'18GORM事务关联.md',
|
||||
'19Viper配置管理.md',
|
||||
'20Zap日志.md',
|
||||
'21综合实战项目.md',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "常用记录",
|
||||
icon: "mdi:star",
|
||||
link: "/work/常用.md",
|
||||
text: 'C++',
|
||||
icon: 'mdi:language-cpp',
|
||||
collapsible: true,
|
||||
prefix: 'c++/',
|
||||
children: 'structure',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Linux',
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: 'mdi:linux',
|
||||
prefix: 'linux/',
|
||||
children: [
|
||||
{
|
||||
text: '基础',
|
||||
icon: 'mdi:console',
|
||||
collapsible: true,
|
||||
prefix: '基础/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: "待办事项",
|
||||
icon: "fa6-solid:list-check",
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: "待办首页",
|
||||
icon: "mdi:home-outline",
|
||||
link: "/work/todo/",
|
||||
},
|
||||
{
|
||||
text: "4月待办",
|
||||
icon: "mdi:calendar-month",
|
||||
link: "/work/todo/2026-04.md",
|
||||
},
|
||||
{
|
||||
text: "3月待办",
|
||||
icon: "mdi:calendar-month",
|
||||
link: "/work/todo/2026-03.md",
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
"/apps/": [
|
||||
{
|
||||
text: "自建应用",
|
||||
icon: "mdi:apps",
|
||||
collapsible: true,
|
||||
children: "structure",
|
||||
}
|
||||
],
|
||||
"/tools/": [
|
||||
{
|
||||
text: "工具箱",
|
||||
icon: "mdi:toolbox",
|
||||
collapsible: true,
|
||||
children: [
|
||||
"01gkd.md",
|
||||
"02WSL2.md",
|
||||
"03Scoop.md",
|
||||
"04gitee-ssh.md",
|
||||
"05Google.md",
|
||||
"06MobaXterm.md"
|
||||
],
|
||||
},
|
||||
],
|
||||
"/ai/": [
|
||||
{
|
||||
text: "OpenCode",
|
||||
icon: "fa6-solid:code",
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: "opencode-cli",
|
||||
icon: "fa6-solid:terminal",
|
||||
link: "opencode.md",
|
||||
},
|
||||
{
|
||||
text: "opencode-tui",
|
||||
icon: "fa6-solid:desktop",
|
||||
link: "opencode-tui.md",
|
||||
},
|
||||
],
|
||||
text: 'Linux_Mint',
|
||||
icon: 'simple-icons:linuxmint',
|
||||
collapsible: true,
|
||||
prefix: 'Linux_Mint/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: "Superpowers",
|
||||
icon: "fa6-solid:rocket",
|
||||
collapsible: true,
|
||||
prefix: "superpowers/",
|
||||
children: [
|
||||
{
|
||||
text: "superpowers-总览",
|
||||
icon: "fa6-solid:eye",
|
||||
link: "opencode-superpowers-overview.md",
|
||||
},
|
||||
{
|
||||
text: "superpowers",
|
||||
icon: "fa6-solid:bolt",
|
||||
link: "opencode-superpowers.md",
|
||||
},
|
||||
{
|
||||
text: "skills-使用方案汇总",
|
||||
icon: "fa6-solid:book",
|
||||
link: "opencode-skills-playbook.md",
|
||||
},
|
||||
],
|
||||
text: '凝思',
|
||||
icon: 'mdi:server',
|
||||
collapsible: true,
|
||||
prefix: '凝思/',
|
||||
children: 'structure',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Docker',
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: 'mdi:docker',
|
||||
prefix: 'docker/',
|
||||
children: 'structure',
|
||||
},
|
||||
],
|
||||
'/work/': [
|
||||
{
|
||||
text: '工作日志',
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: 'mdi:file-document-outline',
|
||||
prefix: 'log/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: '项目总结',
|
||||
collapsible: true,
|
||||
expanded: false,
|
||||
icon: 'mdi:book-open-page-variant',
|
||||
prefix: 'project-summary/',
|
||||
children: 'structure',
|
||||
},
|
||||
{
|
||||
text: '常用记录',
|
||||
icon: 'mdi:star',
|
||||
link: '/work/常用.md',
|
||||
},
|
||||
{
|
||||
text: '待办事项',
|
||||
icon: 'fa6-solid:list-check',
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: '待办首页',
|
||||
icon: 'mdi:home-outline',
|
||||
link: '/work/todo/',
|
||||
},
|
||||
{
|
||||
text: "Claude Code",
|
||||
icon: "fa6-solid:code-branch",
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: "多分支工作流实战总结(2026)",
|
||||
icon: "fa6-solid:code-merge",
|
||||
link: "claude-code-branch-workflow-2026.md",
|
||||
},
|
||||
],
|
||||
text: '4月待办',
|
||||
icon: 'mdi:calendar-month',
|
||||
link: '/work/todo/2026-04.md',
|
||||
},
|
||||
{
|
||||
text: "ChatGPT",
|
||||
icon: "fa6-solid:comments",
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: "chatgpt-使用记录与实践",
|
||||
icon: "fa6-solid:message",
|
||||
link: "chatgpt.md",
|
||||
},
|
||||
],
|
||||
text: '3月待办',
|
||||
icon: 'mdi:calendar-month',
|
||||
link: '/work/todo/2026-03.md',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
'/apps/': [
|
||||
{
|
||||
text: '自建应用',
|
||||
icon: 'mdi:apps',
|
||||
collapsible: true,
|
||||
children: 'structure',
|
||||
},
|
||||
],
|
||||
'/tools/': [
|
||||
{
|
||||
text: '工具箱',
|
||||
icon: 'mdi:toolbox',
|
||||
collapsible: true,
|
||||
children: 'structure',
|
||||
},
|
||||
],
|
||||
'/ai/': [
|
||||
{
|
||||
text: 'OpenCode',
|
||||
icon: 'fa6-solid:code',
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: 'opencode-cli',
|
||||
icon: 'fa6-solid:terminal',
|
||||
link: 'opencode.md',
|
||||
},
|
||||
{
|
||||
text: "OpenClaw",
|
||||
icon: "fa6-solid:robot",
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: "openclaw-24h在线部署实战",
|
||||
icon: "fa6-solid:server",
|
||||
link: "openclaw.md",
|
||||
},
|
||||
],
|
||||
text: 'opencode-tui',
|
||||
icon: 'fa6-solid:desktop',
|
||||
link: 'opencode-tui.md',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Superpowers',
|
||||
icon: 'fa6-solid:rocket',
|
||||
collapsible: true,
|
||||
prefix: 'superpowers/',
|
||||
children: [
|
||||
{
|
||||
text: 'superpowers-总览',
|
||||
icon: 'fa6-solid:eye',
|
||||
link: 'opencode-superpowers-overview.md',
|
||||
},
|
||||
{
|
||||
text: "iFlow",
|
||||
icon: "fa6-solid:diagram-project",
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: "iflow-流程编排实践记录",
|
||||
icon: "fa6-solid:flow-chart",
|
||||
link: "iflow.md",
|
||||
},
|
||||
],
|
||||
text: 'superpowers',
|
||||
icon: 'fa6-solid:bolt',
|
||||
link: 'opencode-superpowers.md',
|
||||
},
|
||||
],
|
||||
"/": false,
|
||||
{
|
||||
text: 'skills-使用方案汇总',
|
||||
icon: 'fa6-solid:book',
|
||||
link: 'opencode-skills-playbook.md',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Claude Code',
|
||||
icon: 'fa6-solid:code-branch',
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: '多分支工作流实战总结(2026)',
|
||||
icon: 'fa6-solid:code-merge',
|
||||
link: 'claude-code-branch-workflow-2026.md',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'ChatGPT',
|
||||
icon: 'fa6-solid:comments',
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: 'chatgpt-使用记录与实践',
|
||||
icon: 'fa6-solid:message',
|
||||
link: 'chatgpt.md',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'OpenClaw',
|
||||
icon: 'fa6-solid:robot',
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: 'openclaw-24h在线部署实战',
|
||||
icon: 'fa6-solid:server',
|
||||
link: 'openclaw.md',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'iFlow',
|
||||
icon: 'fa6-solid:diagram-project',
|
||||
collapsible: true,
|
||||
children: [
|
||||
{
|
||||
text: 'iflow-流程编排实践记录',
|
||||
icon: 'fa6-solid:flow-chart',
|
||||
link: 'iflow.md',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
'/': false,
|
||||
});
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// you can change config here
|
||||
$theme-color: #DC143C;
|
||||
$theme-color: #dc143c;
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
/* .vuepress/styles/index.scss */
|
||||
|
||||
.hitokoto-text {
|
||||
color: #DC143C !important; // 替换为你想要的颜色
|
||||
color: #dc143c !important; // 替换为你想要的颜色
|
||||
}
|
||||
|
||||
.hitokoto-author {
|
||||
color: #DC143C!important; // 可选:也可自定义作者名颜色
|
||||
color: #dc143c !important; // 可选:也可自定义作者名颜色
|
||||
}
|
||||
|
||||
.vp-navbar .auto-link {
|
||||
|
||||
+130
-120
@@ -1,126 +1,136 @@
|
||||
import {hopeTheme} from "vuepress-theme-hope";
|
||||
import { hopeTheme } from 'vuepress-theme-hope';
|
||||
|
||||
import navbar from './navbar.js';
|
||||
import sidebar from './sidebar.js';
|
||||
|
||||
const encryptPassword = process.env.ENCRYPT_PASSWORD;
|
||||
|
||||
if (process.env.NODE_ENV === 'production' && !encryptPassword) {
|
||||
throw new Error('Missing ENCRYPT_PASSWORD. Set it before running a production build.');
|
||||
}
|
||||
|
||||
const accountsPassword = encryptPassword ?? 'local-dev-password';
|
||||
|
||||
import navbar from "./navbar.js";
|
||||
import sidebar from "./sidebar.js";
|
||||
//VuePress Theme Hope主题的博客
|
||||
export default hopeTheme(
|
||||
{
|
||||
// 网站域名配置(用于SEO和RSS等功能)
|
||||
hostname: "https://mangmang.fun/",
|
||||
{
|
||||
// 网站域名配置(用于SEO和RSS等功能)
|
||||
hostname: 'https://mangmang.fun/',
|
||||
|
||||
// 加密配置
|
||||
encrypt: {
|
||||
config: {
|
||||
"/accounts/": "362165265", // 账号密码页面访问密码
|
||||
},
|
||||
},
|
||||
|
||||
// 作者信息
|
||||
author: {
|
||||
name: "LiuMangMang",
|
||||
},
|
||||
|
||||
// 网站许可证
|
||||
license: "CC 4.0",
|
||||
|
||||
// 导航栏配置(从 navbar.js 文件导入)
|
||||
navbar,
|
||||
|
||||
// 侧边栏配置(从 sidebar.js 文件导入)
|
||||
sidebar,
|
||||
|
||||
// 网站logo设置
|
||||
logo: "logo/transparentLogo.png", // 亮色模式下的logo
|
||||
logoDark: "logo/transparentLogo.png", // 暗色模式下的logo
|
||||
|
||||
// 支持简写仓库名称,会解析到 GitHub 上,同时也可以是一个完整的 URL
|
||||
// repo: "https://gitea.mangmang.fun/mangmang/blog",
|
||||
// 默认从 `repo` 内容中推断为以下之一:
|
||||
// "GitHub" / "GitLab" / "Gitee" / "Bitbucket" / "Source"
|
||||
repoLabel: "Gitea",
|
||||
repoDisplay: true,
|
||||
|
||||
// 是否显示编辑链接
|
||||
editLink: true,
|
||||
|
||||
// 文档源码目录
|
||||
docsDir: "src",
|
||||
|
||||
// 页脚配置
|
||||
footer: "<a href='https://beian.miit.gov.cn/' target='_blank'>蜀ICP备2025176018号-1</a> | Powered by VuePress | Theme by Hope",
|
||||
displayFooter: true,
|
||||
|
||||
// 是否显示最后更新时间
|
||||
lastUpdated: false,
|
||||
|
||||
// 深色模式配置(toggle表示用户可以切换)
|
||||
darkmode: "toggle",
|
||||
|
||||
// 博客相关配置
|
||||
blog: {
|
||||
description: "一个后端开发者",
|
||||
intro: "/intro.html"
|
||||
},
|
||||
|
||||
// Markdown增强功能配置
|
||||
markdown: {
|
||||
align: true, // 启用文本对齐
|
||||
attrs: true, // 启用属性支持
|
||||
codeTabs: true, // 启用代码选项卡
|
||||
component: true, // 启用组件支持
|
||||
demo: true, // 启用演示支持
|
||||
figure: true, // 启用图片描述
|
||||
gfm: true, // 启用GitHub风格的Markdown
|
||||
imgLazyload: true, // 启用图片懒加载
|
||||
imgSize: true, // 启用图片尺寸设置
|
||||
include: true, // 启用文件包含
|
||||
mark: true, // 启用标记高亮
|
||||
plantuml: true, // 启用PlantUML图表
|
||||
spoiler: true, // 启用剧透标记
|
||||
|
||||
// 文本样式化配置
|
||||
stylize: [
|
||||
{
|
||||
matcher: "Recommended",
|
||||
replacer: ({tag}) => {
|
||||
if (tag === "em")
|
||||
return {
|
||||
tag: "Badge",
|
||||
attrs: {type: "tip"},
|
||||
content: "Recommended",
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
sub: true, // 启用下标
|
||||
sup: true, // 启用上标
|
||||
tabs: true, // 启用选项卡
|
||||
tasklist: true, // 启用任务列表
|
||||
vPre: true, // 启用v-pre支持
|
||||
},
|
||||
|
||||
// 插件配置
|
||||
plugins: {
|
||||
// 启用博客功能
|
||||
blog: true,
|
||||
|
||||
// 启用本地搜索
|
||||
search: true,
|
||||
|
||||
// 组件配置
|
||||
components: {
|
||||
components: ["Badge", "VPCard"],
|
||||
},
|
||||
|
||||
// 图标配置
|
||||
icon: {
|
||||
prefix: "fa6-solid:",
|
||||
},
|
||||
},
|
||||
// 加密配置
|
||||
encrypt: {
|
||||
config: {
|
||||
'/accounts/': accountsPassword, // 账号密码页面访问密码
|
||||
},
|
||||
},
|
||||
{
|
||||
// 自定义主题配置
|
||||
custom: true
|
||||
}
|
||||
|
||||
// 作者信息
|
||||
author: {
|
||||
name: 'LiuMangMang',
|
||||
},
|
||||
|
||||
// 网站许可证
|
||||
license: 'CC 4.0',
|
||||
|
||||
// 导航栏配置(从 navbar.js 文件导入)
|
||||
navbar,
|
||||
|
||||
// 侧边栏配置(从 sidebar.js 文件导入)
|
||||
sidebar,
|
||||
|
||||
// 网站logo设置
|
||||
logo: 'logo/transparentLogo.png', // 亮色模式下的logo
|
||||
logoDark: 'logo/transparentLogo.png', // 暗色模式下的logo
|
||||
|
||||
// 支持简写仓库名称,会解析到 GitHub 上,同时也可以是一个完整的 URL
|
||||
// repo: "https://gitea.mangmang.fun/mangmang/blog",
|
||||
// 默认从 `repo` 内容中推断为以下之一:
|
||||
// "GitHub" / "GitLab" / "Gitee" / "Bitbucket" / "Source"
|
||||
repoLabel: 'Gitea',
|
||||
repoDisplay: true,
|
||||
|
||||
// 是否显示编辑链接
|
||||
editLink: true,
|
||||
|
||||
// 文档源码目录
|
||||
docsDir: 'src',
|
||||
|
||||
// 页脚配置
|
||||
footer:
|
||||
"<a href='https://beian.miit.gov.cn/' target='_blank'>蜀ICP备2025176018号-1</a> | Powered by VuePress | Theme by Hope",
|
||||
displayFooter: true,
|
||||
|
||||
// 是否显示最后更新时间
|
||||
lastUpdated: true,
|
||||
|
||||
// 深色模式配置(toggle表示用户可以切换)
|
||||
darkmode: 'toggle',
|
||||
|
||||
// 博客相关配置
|
||||
blog: {
|
||||
description: '一个后端开发者',
|
||||
intro: '/intro.html',
|
||||
},
|
||||
|
||||
// Markdown增强功能配置
|
||||
markdown: {
|
||||
align: true, // 启用文本对齐
|
||||
attrs: true, // 启用属性支持
|
||||
codeTabs: true, // 启用代码选项卡
|
||||
component: true, // 启用组件支持
|
||||
demo: true, // 启用演示支持
|
||||
figure: true, // 启用图片描述
|
||||
gfm: true, // 启用GitHub风格的Markdown
|
||||
imgLazyload: true, // 启用图片懒加载
|
||||
imgSize: true, // 启用图片尺寸设置
|
||||
include: true, // 启用文件包含
|
||||
mark: true, // 启用标记高亮
|
||||
plantuml: true, // 启用PlantUML图表
|
||||
spoiler: true, // 启用剧透标记
|
||||
|
||||
// 文本样式化配置
|
||||
stylize: [
|
||||
{
|
||||
matcher: 'Recommended',
|
||||
replacer: ({ tag }) => {
|
||||
if (tag === 'em')
|
||||
return {
|
||||
tag: 'Badge',
|
||||
attrs: { type: 'tip' },
|
||||
content: 'Recommended',
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
sub: true, // 启用下标
|
||||
sup: true, // 启用上标
|
||||
tabs: true, // 启用选项卡
|
||||
tasklist: true, // 启用任务列表
|
||||
vPre: true, // 启用v-pre支持
|
||||
},
|
||||
|
||||
// 插件配置
|
||||
plugins: {
|
||||
// 启用博客功能
|
||||
blog: true,
|
||||
|
||||
// 启用本地搜索
|
||||
search: true,
|
||||
|
||||
// 组件配置
|
||||
components: {
|
||||
components: ['Badge', 'VPCard'],
|
||||
},
|
||||
|
||||
// 图标配置
|
||||
icon: {
|
||||
prefix: 'fa6-solid:',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// 自定义主题配置
|
||||
custom: true,
|
||||
},
|
||||
);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
home: true
|
||||
layout: BlogHome
|
||||
layout: Blog
|
||||
hero: true
|
||||
title: 博客主页
|
||||
heroText: ''
|
||||
|
||||
+3
-7
@@ -2,13 +2,9 @@
|
||||
"compilerOptions": {
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"skipLibCheck": true,
|
||||
"target": "ES2022"
|
||||
},
|
||||
"include": [
|
||||
"src/.vuepress/**/*.ts",
|
||||
"src/.vuepress/**/*.vue"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"include": ["src/.vuepress/**/*.ts", "src/.vuepress/**/*.vue"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user