mirror of https://github.com/YunYouJun/valaxy
refactor: resolve by one valaxy.config.ts
This commit is contained in:
parent
f3ab87f7a9
commit
f27e23d38a
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"cSpell.words": ["algoliasearch", "instantsearch", "valaxy", "valaxyjs", "beian", "jiti", "defu"],
|
||||
"cSpell.words": ["algoliasearch", "instantsearch", "valaxy", "valaxyjs", "beian", "jiti", "defu", "twikoo"],
|
||||
"i18n-ally.sourceLanguage": "en",
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.localesPaths": ["packages/valaxy/src/client/locales"],
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
{
|
||||
"name": "yun-demo",
|
||||
"slidev": {
|
||||
"theme": "yun"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build:ssg && npm run rss",
|
||||
"build:spa": "valaxy build",
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
import { defineSite } from 'valaxy'
|
||||
import type { ThemeConfig } from 'valaxy-theme-yun'
|
||||
|
||||
/**
|
||||
* Blog Config
|
||||
* do not use export const config to avoid defu conflict
|
||||
*/
|
||||
export default defineSite<ThemeConfig>({
|
||||
lang: 'zh-CN',
|
||||
title: 'Valaxy Theme Yun',
|
||||
url: 'https://valaxy.yyj.moe/',
|
||||
author: {
|
||||
avatar: 'https://www.yunyoujun.cn/images/avatar.jpg',
|
||||
name: '云游君',
|
||||
},
|
||||
description: 'Valaxy Theme Yun Preview.',
|
||||
social: [
|
||||
{
|
||||
name: 'RSS',
|
||||
link: '/atom.xml',
|
||||
icon: 'i-ri-rss-line',
|
||||
color: 'orange',
|
||||
},
|
||||
{
|
||||
name: 'QQ 群 1050458482',
|
||||
link: 'https://qm.qq.com/cgi-bin/qm/qr?k=kZJzggTTCf4SpvEQ8lXWoi5ZjhAx0ILZ&jump_from=webapi',
|
||||
icon: 'i-ri-qq-line',
|
||||
color: '#12B7F5',
|
||||
},
|
||||
{
|
||||
name: 'GitHub',
|
||||
link: 'https://github.com/YunYouJun',
|
||||
icon: 'i-ri-github-line',
|
||||
color: '#6e5494',
|
||||
},
|
||||
{
|
||||
name: '微博',
|
||||
link: 'https://weibo.com/jizhideyunyoujun',
|
||||
icon: 'i-ri-weibo-line',
|
||||
color: '#E6162D',
|
||||
},
|
||||
{
|
||||
name: '豆瓣',
|
||||
link: 'https://www.douban.com/people/yunyoujun/',
|
||||
icon: 'i-ri-douban-line',
|
||||
color: '#007722',
|
||||
},
|
||||
{
|
||||
name: '网易云音乐',
|
||||
link: 'https://music.163.com/#/user/home?id=247102977',
|
||||
icon: 'i-ri-netease-cloud-music-line',
|
||||
color: '#C20C0C',
|
||||
},
|
||||
{
|
||||
name: '知乎',
|
||||
link: 'https://www.zhihu.com/people/yunyoujun/',
|
||||
icon: 'i-ri-zhihu-line',
|
||||
color: '#0084FF',
|
||||
},
|
||||
{
|
||||
name: '哔哩哔哩',
|
||||
link: 'https://space.bilibili.com/1579790',
|
||||
icon: 'i-ri-bilibili-line',
|
||||
color: '#FF8EB3',
|
||||
},
|
||||
{
|
||||
name: '微信公众号',
|
||||
link: 'https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg',
|
||||
icon: 'i-ri-wechat-2-line',
|
||||
color: '#1AAD19',
|
||||
},
|
||||
{
|
||||
name: 'Twitter',
|
||||
link: 'https://twitter.com/YunYouJun',
|
||||
icon: 'i-ri-twitter-line',
|
||||
color: '#1da1f2',
|
||||
},
|
||||
{
|
||||
name: 'Telegram Channel',
|
||||
link: 'https://t.me/elpsycn',
|
||||
icon: 'i-ri-telegram-line',
|
||||
color: '#0088CC',
|
||||
},
|
||||
{
|
||||
name: 'E-Mail',
|
||||
link: 'mailto:me@yunyoujun.cn',
|
||||
icon: 'i-ri-mail-line',
|
||||
color: '#8E71C1',
|
||||
},
|
||||
{
|
||||
name: 'Travelling',
|
||||
link: 'https://travellings.link',
|
||||
icon: 'i-ri-train-line',
|
||||
color: 'var(--va-c-text)',
|
||||
},
|
||||
],
|
||||
|
||||
search: {
|
||||
enable: true,
|
||||
algolia: {
|
||||
enable: true,
|
||||
appId: 'UVMHTMG1T5',
|
||||
apiKey: '805f2584a8866388aa1631ff0348ddae',
|
||||
indexName: 'valaxy',
|
||||
|
||||
// test
|
||||
// appId: 'BH4D9OD16A',
|
||||
// apiKey: '978ef82b43148b59dc771ea53b7a56af',
|
||||
// indexName: 'elpsy',
|
||||
},
|
||||
},
|
||||
|
||||
comment: {
|
||||
enable: true,
|
||||
waline: {
|
||||
enable: true,
|
||||
serverURL: 'https://waline.yunyoujun.cn',
|
||||
},
|
||||
twikoo: {
|
||||
// enable: true,
|
||||
envId: 'https://twikoo.vercel.app',
|
||||
},
|
||||
},
|
||||
|
||||
sponsor: {
|
||||
enable: true,
|
||||
methods: [
|
||||
{
|
||||
name: '支付宝',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/alipay-qrcode.jpg',
|
||||
color: '#00A3EE',
|
||||
icon: 'i-ri-alipay-line',
|
||||
},
|
||||
{
|
||||
name: 'QQ 支付',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/qqpay-qrcode.png',
|
||||
color: '#12B7F5',
|
||||
icon: 'i-ri-qq-line',
|
||||
},
|
||||
{
|
||||
name: '微信支付',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/wechatpay-qrcode.jpg',
|
||||
color: '#2DC100',
|
||||
icon: 'i-ri-wechat-pay-line',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
theme: 'yun',
|
||||
|
||||
themeConfig: {
|
||||
// colors: {
|
||||
// primary: 'red',
|
||||
// },
|
||||
|
||||
banner: {
|
||||
enable: true,
|
||||
title: '云游君的小站',
|
||||
},
|
||||
|
||||
pages: [
|
||||
{
|
||||
name: '我的小伙伴们',
|
||||
url: '/links/',
|
||||
icon: 'i-ri-genderless-line',
|
||||
color: 'dodgerblue',
|
||||
},
|
||||
{
|
||||
name: '喜欢的女孩子',
|
||||
url: '/girls/',
|
||||
icon: 'i-ri-women-line',
|
||||
color: 'hotpink',
|
||||
},
|
||||
],
|
||||
|
||||
footer: {
|
||||
since: 2016,
|
||||
beian: {
|
||||
enable: true,
|
||||
icp: '苏ICP备17038157号',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
|
@ -1,20 +1,200 @@
|
|||
import { defineConfig } from 'valaxy'
|
||||
import type { ThemeConfig } from 'valaxy-theme-yun'
|
||||
// import { VitePWA } from 'vite-plugin-pwa'
|
||||
import Inspect from 'vite-plugin-inspect'
|
||||
// import site from './site.config'
|
||||
|
||||
const safelist = [
|
||||
'i-ri-home-line',
|
||||
]
|
||||
|
||||
export default defineConfig({
|
||||
export default defineConfig<ThemeConfig>({
|
||||
lang: 'zh-CN',
|
||||
title: 'Valaxy Theme Yun',
|
||||
url: 'https://valaxy.yyj.moe/',
|
||||
author: {
|
||||
avatar: 'https://www.yunyoujun.cn/images/avatar.jpg',
|
||||
name: '云游君',
|
||||
},
|
||||
description: 'Valaxy Theme Yun Preview.',
|
||||
social: [
|
||||
{
|
||||
name: 'RSS',
|
||||
link: '/atom.xml',
|
||||
icon: 'i-ri-rss-line',
|
||||
color: 'orange',
|
||||
},
|
||||
{
|
||||
name: 'QQ 群 1050458482',
|
||||
link: 'https://qm.qq.com/cgi-bin/qm/qr?k=kZJzggTTCf4SpvEQ8lXWoi5ZjhAx0ILZ&jump_from=webapi',
|
||||
icon: 'i-ri-qq-line',
|
||||
color: '#12B7F5',
|
||||
},
|
||||
{
|
||||
name: 'GitHub',
|
||||
link: 'https://github.com/YunYouJun',
|
||||
icon: 'i-ri-github-line',
|
||||
color: '#6e5494',
|
||||
},
|
||||
{
|
||||
name: '微博',
|
||||
link: 'https://weibo.com/jizhideyunyoujun',
|
||||
icon: 'i-ri-weibo-line',
|
||||
color: '#E6162D',
|
||||
},
|
||||
{
|
||||
name: '豆瓣',
|
||||
link: 'https://www.douban.com/people/yunyoujun/',
|
||||
icon: 'i-ri-douban-line',
|
||||
color: '#007722',
|
||||
},
|
||||
{
|
||||
name: '网易云音乐',
|
||||
link: 'https://music.163.com/#/user/home?id=247102977',
|
||||
icon: 'i-ri-netease-cloud-music-line',
|
||||
color: '#C20C0C',
|
||||
},
|
||||
{
|
||||
name: '知乎',
|
||||
link: 'https://www.zhihu.com/people/yunyoujun/',
|
||||
icon: 'i-ri-zhihu-line',
|
||||
color: '#0084FF',
|
||||
},
|
||||
{
|
||||
name: '哔哩哔哩',
|
||||
link: 'https://space.bilibili.com/1579790',
|
||||
icon: 'i-ri-bilibili-line',
|
||||
color: '#FF8EB3',
|
||||
},
|
||||
{
|
||||
name: '微信公众号',
|
||||
link: 'https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg',
|
||||
icon: 'i-ri-wechat-2-line',
|
||||
color: '#1AAD19',
|
||||
},
|
||||
{
|
||||
name: 'Twitter',
|
||||
link: 'https://twitter.com/YunYouJun',
|
||||
icon: 'i-ri-twitter-line',
|
||||
color: '#1da1f2',
|
||||
},
|
||||
{
|
||||
name: 'Telegram Channel',
|
||||
link: 'https://t.me/elpsycn',
|
||||
icon: 'i-ri-telegram-line',
|
||||
color: '#0088CC',
|
||||
},
|
||||
{
|
||||
name: 'E-Mail',
|
||||
link: 'mailto:me@yunyoujun.cn',
|
||||
icon: 'i-ri-mail-line',
|
||||
color: '#8E71C1',
|
||||
},
|
||||
{
|
||||
name: 'Travelling',
|
||||
link: 'https://travellings.link',
|
||||
icon: 'i-ri-train-line',
|
||||
color: 'var(--va-c-text)',
|
||||
},
|
||||
],
|
||||
|
||||
search: {
|
||||
enable: true,
|
||||
algolia: {
|
||||
enable: true,
|
||||
appId: 'UVMHTMG1T5',
|
||||
apiKey: '805f2584a8866388aa1631ff0348ddae',
|
||||
indexName: 'valaxy',
|
||||
|
||||
// test
|
||||
// appId: 'BH4D9OD16A',
|
||||
// apiKey: '978ef82b43148b59dc771ea53b7a56af',
|
||||
// indexName: 'elpsy',
|
||||
},
|
||||
},
|
||||
|
||||
comment: {
|
||||
enable: true,
|
||||
waline: {
|
||||
enable: true,
|
||||
serverURL: 'https://waline.yunyoujun.cn',
|
||||
},
|
||||
twikoo: {
|
||||
// enable: true,
|
||||
envId: 'https://twikoo.vercel.app',
|
||||
},
|
||||
},
|
||||
|
||||
sponsor: {
|
||||
enable: true,
|
||||
methods: [
|
||||
{
|
||||
name: '支付宝',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/alipay-qrcode.jpg',
|
||||
color: '#00A3EE',
|
||||
icon: 'i-ri-alipay-line',
|
||||
},
|
||||
{
|
||||
name: 'QQ 支付',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/qqpay-qrcode.png',
|
||||
color: '#12B7F5',
|
||||
icon: 'i-ri-qq-line',
|
||||
},
|
||||
{
|
||||
name: '微信支付',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/wechatpay-qrcode.jpg',
|
||||
color: '#2DC100',
|
||||
icon: 'i-ri-wechat-pay-line',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
theme: 'yun',
|
||||
|
||||
themeConfig: {
|
||||
// colors: {
|
||||
// primary: 'red',
|
||||
// },
|
||||
|
||||
banner: {
|
||||
enable: true,
|
||||
title: '云游君的小站',
|
||||
},
|
||||
|
||||
pages: [
|
||||
{
|
||||
name: '我的小伙伴们',
|
||||
url: '/links/',
|
||||
icon: 'i-ri-genderless-line',
|
||||
color: 'dodgerblue',
|
||||
},
|
||||
{
|
||||
name: '喜欢的女孩子',
|
||||
url: '/girls/',
|
||||
icon: 'i-ri-women-line',
|
||||
color: 'hotpink',
|
||||
},
|
||||
],
|
||||
|
||||
footer: {
|
||||
since: 2016,
|
||||
beian: {
|
||||
enable: true,
|
||||
icp: '苏ICP备17038157号',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
vite: {
|
||||
// https://github.com/antfu/vite-plugin-inspect
|
||||
// Visit http://localhost:3333/__inspect/ to see the inspector
|
||||
plugins: [Inspect()],
|
||||
},
|
||||
|
||||
unocss: {
|
||||
safelist,
|
||||
},
|
||||
|
||||
markdown: {
|
||||
blocks: {
|
||||
tip: {
|
||||
|
|
|
@ -27,4 +27,4 @@ features:
|
|||
details: Go wild with true SSG + SPA architecture. Static on page load, but engage users with 100% interactivity from there.
|
||||
---
|
||||
|
||||
<div m="t-8" class="text-center" text="4xl">WORK IN PROGRESS</div>
|
||||
<div m="y-8" text="center 4xl" font="black">🧪 <br /><br />WORK IN PROGRESS</div>
|
||||
|
|
|
@ -74,10 +74,10 @@ Valaxy 决定中心化地提供各类封装好的评论钩子函数。
|
|||
|
||||
```vue {2}
|
||||
<script lang="ts" setup>
|
||||
import { useSite, useWaline } from 'valaxy'
|
||||
import { useConfig, useWaline } from 'valaxy'
|
||||
|
||||
// 读取用户配置
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
// 挂载 Waline
|
||||
useWaline(config.value.comment.waline)
|
||||
</script>
|
||||
|
|
|
@ -3,6 +3,7 @@ import { defineSite } from 'valaxy'
|
|||
export default defineSite({
|
||||
title: 'Valaxy',
|
||||
url: 'https://valaxy.site',
|
||||
description: 'Valaxy Site Docs',
|
||||
|
||||
theme: 'press',
|
||||
themeConfig: {},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { defineConfig } from 'valaxy'
|
||||
import type { ThemeConfig } from 'valaxy-theme-yun'
|
||||
|
||||
// add icons what you will need
|
||||
const safelist = [
|
||||
|
@ -8,6 +9,154 @@ const safelist = [
|
|||
/**
|
||||
* User Config
|
||||
*/
|
||||
export default defineConfig({
|
||||
export default defineConfig<ThemeConfig>({
|
||||
lang: 'zh-CN',
|
||||
title: 'Valaxy Theme Yun',
|
||||
author: {
|
||||
name: '云游君',
|
||||
},
|
||||
description: 'Valaxy Theme Yun Preview.',
|
||||
social: [
|
||||
{
|
||||
name: 'RSS',
|
||||
link: '/atom.xml',
|
||||
icon: 'i-ri-rss-line',
|
||||
color: 'orange',
|
||||
},
|
||||
{
|
||||
name: 'QQ 群 1050458482',
|
||||
link: 'https://qm.qq.com/cgi-bin/qm/qr?k=kZJzggTTCf4SpvEQ8lXWoi5ZjhAx0ILZ&jump_from=webapi',
|
||||
icon: 'i-ri-qq-line',
|
||||
color: '#12B7F5',
|
||||
},
|
||||
{
|
||||
name: 'GitHub',
|
||||
link: 'https://github.com/YunYouJun',
|
||||
icon: 'i-ri-github-line',
|
||||
color: '#6e5494',
|
||||
},
|
||||
{
|
||||
name: '微博',
|
||||
link: 'https://weibo.com/jizhideyunyoujun',
|
||||
icon: 'i-ri-weibo-line',
|
||||
color: '#E6162D',
|
||||
},
|
||||
{
|
||||
name: '豆瓣',
|
||||
link: 'https://www.douban.com/people/yunyoujun/',
|
||||
icon: 'i-ri-douban-line',
|
||||
color: '#007722',
|
||||
},
|
||||
{
|
||||
name: '网易云音乐',
|
||||
link: 'https://music.163.com/#/user/home?id=247102977',
|
||||
icon: 'i-ri-netease-cloud-music-line',
|
||||
color: '#C20C0C',
|
||||
},
|
||||
{
|
||||
name: '知乎',
|
||||
link: 'https://www.zhihu.com/people/yunyoujun/',
|
||||
icon: 'i-ri-zhihu-line',
|
||||
color: '#0084FF',
|
||||
},
|
||||
{
|
||||
name: '哔哩哔哩',
|
||||
link: 'https://space.bilibili.com/1579790',
|
||||
icon: 'i-ri-bilibili-line',
|
||||
color: '#FF8EB3',
|
||||
},
|
||||
{
|
||||
name: '微信公众号',
|
||||
link: 'https://cdn.yunyoujun.cn/img/about/white-qrcode-and-search.jpg',
|
||||
icon: 'i-ri-wechat-2-line',
|
||||
color: '#1AAD19',
|
||||
},
|
||||
{
|
||||
name: 'Twitter',
|
||||
link: 'https://twitter.com/YunYouJun',
|
||||
icon: 'i-ri-twitter-line',
|
||||
color: '#1da1f2',
|
||||
},
|
||||
{
|
||||
name: 'Telegram Channel',
|
||||
link: 'https://t.me/elpsycn',
|
||||
icon: 'i-ri-telegram-line',
|
||||
color: '#0088CC',
|
||||
},
|
||||
{
|
||||
name: 'E-Mail',
|
||||
link: 'mailto:me@yunyoujun.cn',
|
||||
icon: 'i-ri-mail-line',
|
||||
color: '#8E71C1',
|
||||
},
|
||||
{
|
||||
name: 'Travelling',
|
||||
link: 'https://travellings.link',
|
||||
icon: 'i-ri-train-line',
|
||||
color: 'var(--va-c-text)',
|
||||
},
|
||||
],
|
||||
|
||||
search: {
|
||||
enable: false,
|
||||
},
|
||||
|
||||
sponsor: {
|
||||
enable: true,
|
||||
title: '我很可爱,请给我钱!',
|
||||
methods: [
|
||||
{
|
||||
name: '支付宝',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/alipay-qrcode.jpg',
|
||||
color: '#00A3EE',
|
||||
icon: 'i-ri-alipay-line',
|
||||
},
|
||||
{
|
||||
name: 'QQ 支付',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/qqpay-qrcode.png',
|
||||
color: '#12B7F5',
|
||||
icon: 'i-ri-qq-line',
|
||||
},
|
||||
{
|
||||
name: '微信支付',
|
||||
url: 'https://cdn.yunyoujun.cn/img/donate/wechatpay-qrcode.jpg',
|
||||
color: '#2DC100',
|
||||
icon: 'i-ri-wechat-pay-line',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
theme: 'yun',
|
||||
|
||||
themeConfig: {
|
||||
banner: {
|
||||
enable: true,
|
||||
title: '云游君的小站',
|
||||
},
|
||||
|
||||
pages: [
|
||||
{
|
||||
name: '我的小伙伴们',
|
||||
url: '/links/',
|
||||
icon: 'i-ri-genderless-line',
|
||||
color: 'dodgerblue',
|
||||
},
|
||||
{
|
||||
name: '喜欢的女孩子',
|
||||
url: '/girls/',
|
||||
icon: 'i-ri-women-line',
|
||||
color: 'hotpink',
|
||||
},
|
||||
],
|
||||
|
||||
footer: {
|
||||
since: 2016,
|
||||
beian: {
|
||||
enable: true,
|
||||
icp: '苏ICP备17038157号',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
unocss: { safelist },
|
||||
})
|
||||
|
|
|
@ -27,7 +27,7 @@ const app = useAppStore()
|
|||
z="10"
|
||||
:class="app.isRightSidebarOpen && 'open'"
|
||||
>
|
||||
<div class="aside-container" flex="~ col">
|
||||
<div class="aside-container lt-xl:fixed" flex="~ col">
|
||||
<PressToc v-if="frontmatter.toc !== false" :headers="data.headers || []" />
|
||||
<div class="flex-grow" />
|
||||
<div v-if="$slots.default" class="custom-container">
|
||||
|
@ -65,13 +65,17 @@ const app = useAppStore()
|
|||
|
||||
.aside-container {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
top: calc(var(--pr-nav-height) + 32px);
|
||||
margin-top: calc(var(--pr-nav-height) * -1 - 32px);
|
||||
padding-top: calc(var(--pr-nav-height) + 32px);
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
@include media('xl') {
|
||||
.aside-container {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.press-aside {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ const getTitle = (post: Post | any) => {
|
|||
|
||||
<template>
|
||||
<li v-if="category.total" class="category-list-item inline-flex items-center">
|
||||
<span class="folder-action inline-flex" @click="collapsable = !collapsable">
|
||||
<span class="folder-action inline-flex cursor-pointer" @click="collapsable = !collapsable">
|
||||
<div v-if="collapsable" i-ri-folder-add-line />
|
||||
<div v-else style="color:var(--va-c-primary)" i-ri-folder-reduce-line /></span>
|
||||
<span class="category-name" m="l-1" @click="displayCategory ? displayCategory(name) : null">
|
||||
|
@ -42,7 +42,6 @@ const getTitle = (post: Post | any) => {
|
|||
<ul v-if="!isParentCategory(category)">
|
||||
<li v-for="post, i in category.posts" :key="i" class="post-list-item" m="l-4">
|
||||
<router-link v-if="post.title" :to="post.path || ''" class="inline-flex items-center">
|
||||
<div i-ri-file-text-line />
|
||||
<span m="l-1">{{ getTitle(post) }}</span>
|
||||
</router-link>
|
||||
</li>
|
||||
|
|
|
@ -35,14 +35,14 @@ defineProps<{
|
|||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 6px;
|
||||
background-color: var(--vp-c-gray-light-4);
|
||||
background-color: var(--va-c-gray-light-4);
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.dark .icon {
|
||||
background-color: var(--vp-c-bg);
|
||||
background-color: var(--va-c-bg);
|
||||
}
|
||||
|
||||
.title {
|
||||
|
@ -56,6 +56,6 @@ defineProps<{
|
|||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
color: var(--va-c-text-light);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -64,12 +64,12 @@ function scrollToTop() {
|
|||
line-height: 24px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
color: var(--va-c-text-light);
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.menu:hover {
|
||||
color: var(--vp-c-text-1);
|
||||
color: var(--va-c-text);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<script lang="ts" setup>
|
||||
import type { PageData, Post } from 'valaxy'
|
||||
import { useFrontmatter, useLayout, useSidebar, useSite } from 'valaxy'
|
||||
import { useConfig, useFrontmatter, useLayout, useSidebar } from 'valaxy'
|
||||
|
||||
defineProps<{
|
||||
frontmatter: Post
|
||||
data?: PageData
|
||||
}>()
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const frontmatter = useFrontmatter()
|
||||
|
||||
const { hasSidebar } = useSidebar()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import { useSidebar, useSite } from 'valaxy'
|
||||
import { useConfig, useSidebar } from 'valaxy'
|
||||
import { useThemeConfig } from '../../composables'
|
||||
import PressSwitchAppearance from './PressSwitchAppearance.vue'
|
||||
|
||||
|
@ -13,7 +13,7 @@ defineEmits<{
|
|||
|
||||
const { hasSidebar } = useSidebar()
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const themeConfig = useThemeConfig()
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { computed } from 'vue'
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
import type { ThemeConfig } from '../types'
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,6 @@ import type { ThemeConfig } from '../types'
|
|||
* @returns
|
||||
*/
|
||||
export function useThemeConfig<T = ThemeConfig>() {
|
||||
const config = useSite<T>()
|
||||
const config = useConfig<T>()
|
||||
return computed(() => config!.value.themeConfig)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import type { PageData, Post } from 'valaxy'
|
||||
import { usePostTitle, useSite } from 'valaxy'
|
||||
import { useConfig, usePostTitle } from 'valaxy'
|
||||
import { computed, defineAsyncComponent } from 'vue'
|
||||
import { usePostProperty } from '../composables'
|
||||
|
||||
|
@ -8,7 +8,7 @@ const props = defineProps<{
|
|||
frontmatter: Post
|
||||
data?: PageData
|
||||
}>()
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
|
||||
const { styles, icon, color } = usePostProperty(props.frontmatter.type)
|
||||
const title = usePostTitle(computed(() => props.frontmatter))
|
||||
|
|
|
@ -4,12 +4,12 @@ import docsearch from '@docsearch/js'
|
|||
import type { DocSearchHit } from '@docsearch/react/dist/esm/types'
|
||||
import { onMounted } from 'vue'
|
||||
import type { AlgoliaSearchOptions } from 'valaxy'
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
|
||||
onMounted(() => {
|
||||
initialize(config.value.search.algolia)
|
||||
|
@ -142,9 +142,9 @@ function getRelativePath(absoluteUrl: string) {
|
|||
.dark .DocSearch {
|
||||
--docsearch-modal-shadow: none;
|
||||
--docsearch-footer-shadow: none;
|
||||
--docsearch-logo-color: var(--va-c-text-2);
|
||||
--docsearch-logo-color: var(--va-c-text-light);
|
||||
--docsearch-hit-background: var(--va-c-bg-mute);
|
||||
--docsearch-hit-color: var(--va-c-text-2);
|
||||
--docsearch-hit-color: var(--va-c-text-light);
|
||||
--docsearch-hit-shadow: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import { capitalize, computed } from 'vue'
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import pkg from 'valaxy/package.json'
|
||||
|
@ -8,7 +8,7 @@ import { useThemeConfig } from '../composables'
|
|||
|
||||
const { t } = useI18n()
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const themeConfig = useThemeConfig()
|
||||
|
||||
const year = new Date().getFullYear()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts" setup>
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const router = useRouter()
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script lang="ts" setup>
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { t } = useI18n()
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
|
||||
const showQr = ref(false)
|
||||
</script>
|
||||
|
|
|
@ -110,7 +110,7 @@ function handleClick({ target: el }: Event) {
|
|||
.outline-link {
|
||||
display: block;
|
||||
line-height: 28px;
|
||||
color: var(--va-c-text-2);
|
||||
color: var(--va-c-text-light);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { useSite, useTwikoo } from 'valaxy'
|
||||
import { useConfig, useTwikoo } from 'valaxy'
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
useTwikoo(config.value.comment.twikoo)
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts" setup>
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
// we need import on demand
|
||||
import { useWaline } from 'valaxy/client/composables/comments/waline'
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
useWaline(config.value.comment.waline, config.value.cdn.prefix)
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { computed } from 'vue'
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
import type { YunTheme } from '../types'
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,6 @@ import type { YunTheme } from '../types'
|
|||
* @returns
|
||||
*/
|
||||
export function useThemeConfig<ThemeConfig = YunTheme.Config>() {
|
||||
const config = useSite<ThemeConfig>()
|
||||
const config = useConfig<ThemeConfig>()
|
||||
return computed(() => config!.value.themeConfig)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts" setup>
|
||||
import { useAppStore, useLayout, useSite } from 'valaxy'
|
||||
import { useAppStore, useConfig, useLayout } from 'valaxy'
|
||||
import { useThemeConfig } from '../composables'
|
||||
|
||||
const app = useAppStore()
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const themeConfig = useThemeConfig()
|
||||
const isHome = useLayout('home')
|
||||
</script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { useSite } from 'valaxy'
|
||||
import { useConfig } from 'valaxy'
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { useFrontmatter, useFullUrl, useSite } from 'valaxy'
|
||||
import { useConfig, useFrontmatter, useFullUrl } from 'valaxy'
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const frontmatter = useFrontmatter()
|
||||
const url = useFullUrl()
|
||||
|
||||
|
|
|
@ -104,5 +104,3 @@ export const defaultThemeConfig: ThemeConfig = {
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default defaultThemeConfig
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import type { ResolvedValaxyOptions } from 'valaxy/node'
|
||||
import type { ThemeUserConfig } from '../types'
|
||||
|
||||
/**
|
||||
|
@ -5,7 +6,8 @@ import type { ThemeUserConfig } from '../types'
|
|||
* @param themeConfig
|
||||
* @returns
|
||||
*/
|
||||
export function generateSafelist(themeConfig: ThemeUserConfig) {
|
||||
export function generateSafelist(options: ResolvedValaxyOptions<ThemeUserConfig>) {
|
||||
const themeConfig = options.config.themeConfig || {}
|
||||
const safelist = []
|
||||
|
||||
const types = themeConfig.types
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type { ResolvedValaxyOptions } from 'valaxy'
|
||||
import { defineConfig } from 'valaxy/node'
|
||||
import { defineTheme } from 'valaxy/node'
|
||||
import type { Plugin } from 'vite'
|
||||
import type { ThemeConfig } from './types'
|
||||
import { generateSafelist } from './node'
|
||||
import { defaultThemeConfig, generateSafelist } from './node'
|
||||
|
||||
function ThemeVitePlugin(options: ResolvedValaxyOptions<ThemeConfig>): Plugin {
|
||||
const themeConfig = options.config.themeConfig
|
||||
const themeConfig = options.config.themeConfig || {}
|
||||
return {
|
||||
name: 'valaxy-theme-yun',
|
||||
enforce: 'pre',
|
||||
|
@ -27,15 +27,14 @@ function ThemeVitePlugin(options: ResolvedValaxyOptions<ThemeConfig>): Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
const config = defineConfig<ThemeConfig>((options) => {
|
||||
export default defineTheme<ThemeConfig>((options) => {
|
||||
return {
|
||||
themeConfig: defaultThemeConfig,
|
||||
vite: {
|
||||
plugins: [ThemeVitePlugin(options)],
|
||||
},
|
||||
unocss: {
|
||||
safelist: generateSafelist(options.config.themeConfig),
|
||||
safelist: generateSafelist(options),
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
export default config
|
||||
|
|
|
@ -6,20 +6,20 @@ import { isDark } from './composables'
|
|||
// https://github.com/vueuse/head
|
||||
// you can use this to manipulate the document head in any components,
|
||||
// they will be rendered correctly in the html results with vite-ssg
|
||||
import { useSite } from './config'
|
||||
import { useConfig } from './config'
|
||||
|
||||
// <link rel="apple-touch-icon" href="/pwa-192x192.png">
|
||||
// <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#00aba9">
|
||||
// <meta name="msapplication-TileColor" content = "#00aba9" >
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
useHead({
|
||||
title: config.value.title,
|
||||
link: [
|
||||
{
|
||||
rel: 'icon',
|
||||
href: config.value.favicon,
|
||||
type: config.value.favicon.endsWith('svg') ? 'image/svg+xml' : 'image/png',
|
||||
type: config.value.favicon?.endsWith('svg') ? 'image/svg+xml' : 'image/png',
|
||||
},
|
||||
],
|
||||
meta: [
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useSite } from '../config'
|
||||
import { useConfig } from '../config'
|
||||
|
||||
withDefaults(defineProps<{
|
||||
url?: string
|
||||
|
@ -11,7 +11,7 @@ withDefaults(defineProps<{
|
|||
|
||||
const { t, locale } = useI18n()
|
||||
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
|
||||
const ccVersion = (config.value.license.type === 'zero') ? '1.0' : '4.0'
|
||||
const ccPrefix = (config.value.license.type === 'zero') ? 'publicdomain' : 'licenses'
|
||||
|
|
|
@ -2,7 +2,7 @@ import { isClient, useScriptTag } from '@vueuse/core'
|
|||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useSite } from '../..'
|
||||
import { useConfig } from '../..'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
@ -24,7 +24,7 @@ declare global {
|
|||
* @param options
|
||||
*/
|
||||
export function useTwikoo(options: {} = {}) {
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const cdnPrefix = computed(() => config.value.cdn.prefix)
|
||||
|
||||
const route = useRoute()
|
||||
|
|
|
@ -3,7 +3,7 @@ import { computed, inject } from 'vue'
|
|||
import { isClient } from '@vueuse/core'
|
||||
|
||||
import type { PageData, Post } from '../../types'
|
||||
import { useSite } from '../config'
|
||||
import { useConfig } from '../config'
|
||||
|
||||
export function useFrontmatter() {
|
||||
const route = useRoute()
|
||||
|
@ -25,7 +25,7 @@ export function useData(): PageData {
|
|||
* get full url
|
||||
*/
|
||||
export function useFullUrl() {
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const route = useRoute()
|
||||
const url = computed(() => {
|
||||
const siteUrl = config.value.url.endsWith('/') ? config.value.url.slice(0, -1) : config.value.url
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useScriptTag } from '@vueuse/core'
|
||||
import { useHead } from '@vueuse/head'
|
||||
import { computed } from 'vue'
|
||||
import { useSite } from '../..'
|
||||
import { useConfig } from '../..'
|
||||
|
||||
/**
|
||||
* use MetingJS and Aplayer
|
||||
|
@ -9,7 +9,7 @@ import { useSite } from '../..'
|
|||
* @see https://github.com/metowolf/MetingJS
|
||||
*/
|
||||
export function useAplayer() {
|
||||
const config = useSite()
|
||||
const config = useConfig()
|
||||
const cdnPrefix = computed(() => config.value.cdn.prefix)
|
||||
|
||||
useHead({
|
||||
|
|
|
@ -8,7 +8,7 @@ import { computed, inject, readonly, shallowRef } from 'vue'
|
|||
// fix build caused by pnpm
|
||||
// This is likely not portable. A type annotation is necessary.
|
||||
// https://github.com/microsoft/TypeScript/issues/42873
|
||||
import type { ValaxySiteConfig } from 'valaxy/types'
|
||||
import type { ValaxySiteConfig, ValaxyThemeConfig } from 'valaxy/types'
|
||||
|
||||
/**
|
||||
* parse valaxy config
|
||||
|
@ -50,25 +50,35 @@ export function initContext() {
|
|||
return computed(() => valaxyContextRef.value)
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* get valaxy config
|
||||
* @public
|
||||
* @returns
|
||||
*/
|
||||
export function useSite<ThemeConfig = any>() {
|
||||
export function useSite<ThemeConfig = ValaxyThemeConfig>() {
|
||||
const config = inject<ComputedRef<ValaxySiteConfig<ThemeConfig>>>(valaxySiteConfigSymbol)
|
||||
if (!config)
|
||||
throw new Error('[Valaxy] config not properly injected in app')
|
||||
throw new Error('[Valaxy] site config not properly injected in app')
|
||||
return config!
|
||||
}
|
||||
|
||||
/**
|
||||
* alias for useSite
|
||||
* @public
|
||||
* @returns
|
||||
*/
|
||||
export function useConfig<ThemeConfig = ValaxyThemeConfig>() {
|
||||
return useSite<ThemeConfig>()
|
||||
}
|
||||
|
||||
/**
|
||||
* You can use like this: import { useThemeConfig } from 'valaxy-theme-xxx'
|
||||
* if you want to: import { useThemeConfig } from 'valaxy'
|
||||
* you need pass themeConfig by yourself
|
||||
* @internal
|
||||
* @returns
|
||||
*/
|
||||
export function useThemeConfig<T = Record<string, any>>() {
|
||||
const config = useSite<T>()
|
||||
export function useThemeConfig<ThemeConfig = ValaxyThemeConfig>() {
|
||||
const config = useSite<ThemeConfig>()
|
||||
return computed(() => config!.value.themeConfig)
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ $light: map.merge(
|
|||
"c-bg-light": white,
|
||||
"c-bg-dark": #fafafa,
|
||||
|
||||
"c-bg-soft": white,
|
||||
"c-bg-soft": #f9f9f9,
|
||||
"c-bg-alt": #f9f9f9,
|
||||
"c-bg-mute": #f1f1f1,
|
||||
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
import type { InlineConfig } from 'vite'
|
||||
import { mergeConfig, build as viteBuild } from 'vite'
|
||||
import { mergeConfig as mergeViteConfig, build as viteBuild } from 'vite'
|
||||
import { build as viteSsgBuild } from 'vite-ssg/node'
|
||||
import generateSitemap from 'vite-ssg-sitemap'
|
||||
|
||||
import type { ResolvedValaxyOptions } from './options'
|
||||
import { ViteValaxyPlugins } from './plugins/preset'
|
||||
import { resolveValaxyConfig } from './utils/config'
|
||||
|
||||
export async function build(
|
||||
options: ResolvedValaxyOptions,
|
||||
viteConfig: InlineConfig = {},
|
||||
) {
|
||||
const config = await resolveValaxyConfig(options, viteConfig)
|
||||
const inlineConfig = mergeConfig(config.vite!, {
|
||||
plugins: await ViteValaxyPlugins(options, config),
|
||||
const inlineConfig = mergeViteConfig(viteConfig, {
|
||||
plugins: await ViteValaxyPlugins(options),
|
||||
})
|
||||
|
||||
await viteBuild(inlineConfig)
|
||||
|
@ -23,10 +21,8 @@ export async function ssgBuild(
|
|||
options: ResolvedValaxyOptions,
|
||||
viteConfig: InlineConfig = {},
|
||||
) {
|
||||
const config = await resolveValaxyConfig(options, viteConfig)
|
||||
|
||||
const defaultConfig: InlineConfig = {
|
||||
plugins: await ViteValaxyPlugins(options, config),
|
||||
plugins: await ViteValaxyPlugins(options),
|
||||
}
|
||||
|
||||
defaultConfig.ssgOptions = {
|
||||
|
@ -41,7 +37,7 @@ export async function ssgBuild(
|
|||
},
|
||||
dirStyle: 'nested',
|
||||
}
|
||||
const inlineConfig: InlineConfig = mergeConfig(config.vite!, defaultConfig)
|
||||
const inlineConfig: InlineConfig = mergeViteConfig(defaultConfig, viteConfig)
|
||||
|
||||
await viteSsgBuild({}, inlineConfig)
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ cli.command(
|
|||
const port = userPort || await findFreePort(4859)
|
||||
const options = await resolveOptions({ userRoot: root })
|
||||
|
||||
const viteConfig: InlineConfig = {
|
||||
const viteConfig: InlineConfig = mergeConfig({
|
||||
// avoid load userRoot/vite.config.ts repeatedly
|
||||
configFile: path.resolve(options.clientRoot, 'vite.config.ts'),
|
||||
server: {
|
||||
|
@ -81,7 +81,8 @@ cli.command(
|
|||
host: remote ? '0.0.0.0' : 'localhost',
|
||||
},
|
||||
logLevel: log as LogLevel,
|
||||
}
|
||||
}, options.config.vite || {})
|
||||
|
||||
await initServer(options, viteConfig)
|
||||
printInfo(options, port, remote)
|
||||
|
||||
|
@ -135,8 +136,9 @@ cli.command(
|
|||
const options = await resolveOptions({ userRoot: root }, 'build')
|
||||
printInfo(options)
|
||||
|
||||
const viteConfig = mergeConfig(
|
||||
await mergeViteConfigs(options, 'build'),
|
||||
const valaxyViteConfig: InlineConfig = mergeConfig(await mergeViteConfigs(options, 'build'), options.config.vite || {})
|
||||
const viteConfig: InlineConfig = mergeConfig(
|
||||
valaxyViteConfig,
|
||||
{
|
||||
// avoid load userRoot/vite.config.ts repeatedly
|
||||
configFile: path.resolve(options.clientRoot, 'vite.config.ts'),
|
||||
|
|
|
@ -3,10 +3,9 @@ import { join } from 'path'
|
|||
import type { ConfigEnv, InlineConfig } from 'vite'
|
||||
import { uniq } from '@antfu/utils'
|
||||
import { loadConfigFromFile, mergeConfig } from 'vite'
|
||||
import { loadConfig } from 'unconfig'
|
||||
import type { ResolvedValaxyOptions, ValaxyConfig } from './options'
|
||||
import { mergeFullConfig, toAtFS } from './utils'
|
||||
import type { ValaxyConfigExport } from './config'
|
||||
import type { ResolvedValaxyOptions } from './options'
|
||||
import { toAtFS } from './utils'
|
||||
|
||||
export async function mergeViteConfigs({ userRoot, themeRoot }: ResolvedValaxyOptions, command: 'serve' | 'build') {
|
||||
const configEnv: ConfigEnv = {
|
||||
mode: 'development',
|
||||
|
@ -30,29 +29,6 @@ export async function mergeViteConfigs({ userRoot, themeRoot }: ResolvedValaxyOp
|
|||
return resolvedConfig
|
||||
}
|
||||
|
||||
export async function mergeValaxyConfigs(options: ResolvedValaxyOptions) {
|
||||
const { userRoot, themeRoot } = options
|
||||
let valaxyConfig: ValaxyConfig = { vite: {} }
|
||||
for await (const root of uniq([themeRoot, userRoot])) {
|
||||
// no need to judge empty, unconfig will do it for us
|
||||
const { config } = await loadConfig<ValaxyConfig>({
|
||||
sources: {
|
||||
files: 'valaxy.config',
|
||||
async rewrite(c: ValaxyConfigExport) {
|
||||
return await (typeof c === 'function' ? c(options) : c)
|
||||
},
|
||||
},
|
||||
cwd: root,
|
||||
merge: false,
|
||||
|
||||
})
|
||||
if (!config)
|
||||
continue
|
||||
valaxyConfig = mergeFullConfig(valaxyConfig, config)
|
||||
}
|
||||
return valaxyConfig
|
||||
}
|
||||
|
||||
export async function getIndexHtml({ clientRoot, themeRoot, userRoot, config }: ResolvedValaxyOptions): Promise<string> {
|
||||
let main = await fs.readFile(join(clientRoot, 'index.html'), 'utf-8')
|
||||
let head = ''
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
// import { loadConfig } from 'c12'
|
||||
import path from 'path'
|
||||
import fs from 'fs-extra'
|
||||
import defu from 'defu'
|
||||
import { ensureSuffix } from '@antfu/utils'
|
||||
import { normalizePath } from 'vite'
|
||||
import { loadConfig } from 'unconfig'
|
||||
import type { VitePluginConfig as UnoCssConfig } from 'unocss/vite'
|
||||
import type { Awaitable } from '@antfu/utils'
|
||||
import jiti from 'jiti'
|
||||
import type { UserConfig, ValaxySiteConfig } from '../types'
|
||||
import type { ResolvedValaxyOptions, ThemeSetup, ValaxyConfig, ValaxyEntryOptions } from './options'
|
||||
import { getThemeRoot } from './utils/theme'
|
||||
import type { DefaultThemeConfig, SiteConfig, UserSiteConfig } from '../types'
|
||||
import type { ResolvedValaxyOptions } from './options'
|
||||
import type { UserConfig, ValaxyConfig } from './types'
|
||||
|
||||
/**
|
||||
* Type site helper
|
||||
*/
|
||||
export function defineSite<ThemeConfig>(config: UserConfig<ThemeConfig>) {
|
||||
export function defineSite<ThemeConfig>(config: UserSiteConfig<ThemeConfig>) {
|
||||
return config
|
||||
}
|
||||
|
||||
|
@ -22,21 +15,27 @@ export function defineSite<ThemeConfig>(config: UserConfig<ThemeConfig>) {
|
|||
* Type site helper for custom theme site
|
||||
*/
|
||||
export function defineSiteWithTheme<ThemeConfig>(
|
||||
config: UserConfig<ThemeConfig>,
|
||||
config: UserSiteConfig<ThemeConfig>,
|
||||
) {
|
||||
return config
|
||||
}
|
||||
|
||||
export type ValaxyConfigExport<T = Record<string, any>> = ValaxyConfig | Promise<ValaxyConfig> | ValaxyConfigFn<T>
|
||||
export type ValaxyConfigFn<T> = (options: ResolvedValaxyOptions<T>) => ValaxyConfig | Promise<ValaxyConfig>
|
||||
/**
|
||||
* Type valaxy config helper
|
||||
*/
|
||||
export function defineConfig<ThemeConfig>(config: ValaxyConfigExport<ThemeConfig>) {
|
||||
export function defineConfig<ThemeConfig>(config: UserConfig<ThemeConfig>) {
|
||||
return config
|
||||
}
|
||||
|
||||
const defaultSiteConfig: ValaxySiteConfig = {
|
||||
export type ValaxyConfigExtendKey = 'vite' | 'vue' | 'unocss' | 'unocssPresets' | 'markdown' | 'extendMd'
|
||||
export type ValaxyTheme<ThemeConfig = DefaultThemeConfig> = Pick<ValaxyConfig, ValaxyConfigExtendKey> & { themeConfig?: ThemeConfig }
|
||||
export function defineTheme<ThemeConfig = DefaultThemeConfig>(
|
||||
theme: ValaxyTheme<ThemeConfig> | ((options: ResolvedValaxyOptions<ThemeConfig>) => ValaxyTheme<ThemeConfig>),
|
||||
) {
|
||||
return theme
|
||||
}
|
||||
|
||||
export const defaultSiteConfig: SiteConfig = {
|
||||
mode: 'auto',
|
||||
url: '/',
|
||||
lang: 'en',
|
||||
|
@ -44,13 +43,14 @@ const defaultSiteConfig: ValaxySiteConfig = {
|
|||
description: 'A blog generated by Valaxy.',
|
||||
subtitle: 'Next Generation Static Blog Framework.',
|
||||
author: {
|
||||
// todo valaxy logo
|
||||
avatar: 'https://www.yunyoujun.cn/images/avatar.jpg',
|
||||
email: 'me@yunyoujun.cn',
|
||||
link: 'https://www.yunyoujun.cn',
|
||||
name: 'YunYouJun',
|
||||
email: 'i@valaxy.site',
|
||||
link: 'https://valaxy.site',
|
||||
name: 'VALAXY Developer',
|
||||
status: {
|
||||
emoji: '😊',
|
||||
message: 'All at sea.',
|
||||
emoji: '🌌',
|
||||
message: 'The moonlight is beautiful.',
|
||||
},
|
||||
},
|
||||
favicon: '/favicon.svg',
|
||||
|
@ -73,7 +73,7 @@ const defaultSiteConfig: ValaxySiteConfig = {
|
|||
|
||||
sponsor: {
|
||||
enable: true,
|
||||
title: '我很可爱,请给我钱',
|
||||
title: '赞助',
|
||||
methods: [],
|
||||
},
|
||||
|
||||
|
@ -120,64 +120,6 @@ const defaultSiteConfig: ValaxySiteConfig = {
|
|||
// },
|
||||
}
|
||||
|
||||
// for user config
|
||||
export async function resolveSiteConfig(options: ValaxyEntryOptions = {}) {
|
||||
// c12 merge array twice, so i deprecated it
|
||||
// const { config, configFile } = await loadConfig<ValaxySiteConfig>({
|
||||
// name: 'valaxy',
|
||||
// defaults: defaultSiteConfig,
|
||||
// })
|
||||
|
||||
const { config: userConfig, sources } = await loadConfig<ValaxySiteConfig>({
|
||||
sources: [
|
||||
{
|
||||
files: 'site.config',
|
||||
extensions: ['ts', 'js', 'mjs', 'cjs', 'json'],
|
||||
},
|
||||
],
|
||||
merge: false,
|
||||
})
|
||||
|
||||
const configFile = normalizePath(sources[0] || '')
|
||||
|
||||
const config = defu(userConfig, defaultSiteConfig)
|
||||
// ensure suffix for cdn prefix
|
||||
config.cdn.prefix = ensureSuffix('/', config.cdn.prefix)
|
||||
|
||||
const theme = options.theme || config.theme || 'yun'
|
||||
let themeSetup: ThemeSetup = {}
|
||||
|
||||
try {
|
||||
const themeEntry = path.resolve(getThemeRoot(theme), 'node/index.ts')
|
||||
if (!(await fs.pathExists(themeEntry)))
|
||||
throw new Error('theme entry not found')
|
||||
|
||||
themeSetup = jiti(__filename)(themeEntry)
|
||||
config.themeConfig = defu(config.themeConfig, themeSetup.defaultThemeConfig || {})
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e)
|
||||
console.error(`valaxy-theme-${theme} doesn't have default config`)
|
||||
}
|
||||
|
||||
try {
|
||||
const pkg = fs.readFileSync(require.resolve(`valaxy-theme-${theme}/package.json`), 'utf-8')
|
||||
config.themeConfig.pkg = JSON.parse(pkg)
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`valaxy-theme-${theme} doesn't have package.json`)
|
||||
}
|
||||
|
||||
config.url = ensureSuffix('/', config.url)
|
||||
|
||||
return {
|
||||
config,
|
||||
configFile,
|
||||
theme,
|
||||
themeSetup,
|
||||
}
|
||||
}
|
||||
|
||||
export type UnoSetup = () => Awaitable<Partial<UnoCssConfig> | undefined>
|
||||
|
||||
export function defineUnoSetup(fn: UnoSetup) {
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
import { dirname, resolve } from 'path'
|
||||
import fs from 'fs'
|
||||
import _debug from 'debug'
|
||||
import fg from 'fast-glob'
|
||||
import type Vue from '@vitejs/plugin-vue'
|
||||
import type Components from 'unplugin-vue-components/vite'
|
||||
import type { VitePluginConfig as UnoCSSConfig } from 'unocss/vite'
|
||||
import { uniq } from '@antfu/utils'
|
||||
import type Pages from 'vite-plugin-pages'
|
||||
import type { UserConfig as ViteUserConfig } from 'vite'
|
||||
import type { presetAttributify, presetIcons, presetTypography, presetUno } from 'unocss'
|
||||
import type { ValaxySiteConfig } from '../types'
|
||||
import { resolveSiteConfig } from './config'
|
||||
import { ensureSuffix, uniq } from '@antfu/utils'
|
||||
import defu from 'defu'
|
||||
import type { DefaultThemeConfig } from '../types'
|
||||
import { resolveImportPath } from './utils'
|
||||
import type { MarkdownOptions } from './markdown'
|
||||
import { getThemeRoot } from './utils/theme'
|
||||
import { mergeValaxyConfig, resolveValaxyConfig, resolveValaxyConfigFromRoot } from './utils/config'
|
||||
import type { ValaxyConfig } from './types'
|
||||
import { defaultSiteConfig } from './config'
|
||||
|
||||
// for cli entry
|
||||
export interface ValaxyEntryOptions {
|
||||
|
@ -23,41 +20,7 @@ export interface ValaxyEntryOptions {
|
|||
userRoot?: string
|
||||
}
|
||||
|
||||
export interface ValaxyConfig {
|
||||
vite?: ViteUserConfig
|
||||
vue?: Parameters<typeof Vue>[0]
|
||||
components?: Parameters<typeof Components>[0]
|
||||
unocss?: UnoCSSConfig
|
||||
/**
|
||||
* unocss presets
|
||||
*/
|
||||
unocssPresets?: {
|
||||
uno?: Parameters<typeof presetUno>[0]
|
||||
attributify?: Parameters<typeof presetAttributify>[0]
|
||||
icons?: Parameters<typeof presetIcons>[0]
|
||||
typography?: Parameters<typeof presetTypography>[0]
|
||||
}
|
||||
pages?: Parameters<typeof Pages>[0]
|
||||
/**
|
||||
* for markdown
|
||||
*/
|
||||
markdown?: MarkdownOptions
|
||||
extendMd?: (ctx: {
|
||||
route: any
|
||||
data: Record<string, any>
|
||||
excerpt?: string
|
||||
path: string
|
||||
}) => void
|
||||
plugins?: ValaxyPluginOption[]
|
||||
}
|
||||
export type ValaxyPluginLike = ValaxyConfig | ValaxyConfig[] | false | null | undefined
|
||||
export type ValaxyPluginOption = ValaxyPluginLike | string | [string, any]
|
||||
|
||||
export interface ThemeSetup {
|
||||
defaultThemeConfig?: Record<string, any>
|
||||
}
|
||||
|
||||
export interface ResolvedValaxyOptions<T = Record<string, any>> {
|
||||
export interface ResolvedValaxyOptions<ThemeConfig = DefaultThemeConfig> {
|
||||
mode: 'dev' | 'build'
|
||||
/**
|
||||
* package.json root
|
||||
|
@ -82,11 +45,10 @@ export interface ResolvedValaxyOptions<T = Record<string, any>> {
|
|||
*/
|
||||
roots: string[]
|
||||
theme: string
|
||||
themeSetup: ThemeSetup
|
||||
/**
|
||||
* Valaxy Config
|
||||
*/
|
||||
config: ValaxySiteConfig<T>
|
||||
config: ValaxyConfig<ThemeConfig>
|
||||
/**
|
||||
* config file path
|
||||
*/
|
||||
|
@ -95,7 +57,7 @@ export interface ResolvedValaxyOptions<T = Record<string, any>> {
|
|||
}
|
||||
|
||||
export interface ValaxyServerOptions {
|
||||
onConfigReload?: (newConfig: ValaxySiteConfig, config: ValaxySiteConfig, force?: boolean) => void
|
||||
onConfigReload?: (newConfig: ValaxyConfig, config: ValaxyConfig, force?: boolean) => void
|
||||
}
|
||||
|
||||
const debug = _debug('valaxy:options')
|
||||
|
@ -106,8 +68,9 @@ export async function resolveOptions(options: ValaxyEntryOptions, mode: Resolved
|
|||
const clientRoot = resolve(pkgRoot, 'client')
|
||||
const userRoot = resolve(options.userRoot || process.cwd())
|
||||
|
||||
const { config: siteConfig, configFile, theme, themeSetup } = await resolveSiteConfig(options)
|
||||
const themeRoot = getThemeRoot(theme, userRoot)
|
||||
const { config: userValaxyConfig, configFile, theme } = await resolveValaxyConfig(options)
|
||||
|
||||
const themeRoot = getThemeRoot(theme, options.userRoot)
|
||||
|
||||
const roots = uniq([clientRoot, themeRoot, userRoot])
|
||||
|
||||
|
@ -132,12 +95,31 @@ export async function resolveOptions(options: ValaxyEntryOptions, mode: Resolved
|
|||
themeRoot,
|
||||
roots,
|
||||
theme,
|
||||
themeSetup,
|
||||
config: siteConfig,
|
||||
config: userValaxyConfig,
|
||||
configFile: configFile || '',
|
||||
pages,
|
||||
}
|
||||
debug(valaxyOptions)
|
||||
|
||||
// resolve theme valaxy.config.ts and merge theme
|
||||
const { config: themeValaxyConfig } = await resolveValaxyConfigFromRoot(themeRoot, valaxyOptions)
|
||||
const valaxyConfig = mergeValaxyConfig(userValaxyConfig, themeValaxyConfig)
|
||||
const config = defu(valaxyConfig, defaultSiteConfig)
|
||||
valaxyOptions.config = config
|
||||
|
||||
// optimize config
|
||||
config.url = ensureSuffix('/', config.url)
|
||||
// ensure suffix for cdn prefix
|
||||
config.cdn.prefix = ensureSuffix('/', config.cdn.prefix)
|
||||
|
||||
// mount pkg info
|
||||
try {
|
||||
const pkg = fs.readFileSync(require.resolve(`valaxy-theme-${theme}/package.json`), 'utf-8')
|
||||
config.themeConfig.pkg = JSON.parse(pkg)
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`valaxy-theme-${theme} doesn't have package.json`)
|
||||
}
|
||||
|
||||
return valaxyOptions
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { dirname, join, resolve } from 'path'
|
|||
import type { InlineConfig, Plugin } from 'vite'
|
||||
import { mergeConfig } from 'vite'
|
||||
import isInstalledGlobally from 'is-installed-globally'
|
||||
import fs from 'fs-extra'
|
||||
import type { ResolvedValaxyOptions } from '../options'
|
||||
import { resolveImportPath, toAtFS } from '../utils'
|
||||
import { getIndexHtml } from '../common'
|
||||
|
@ -81,6 +82,13 @@ export function createConfigPlugin(options: ResolvedValaxyOptions): Plugin {
|
|||
res.end(await getIndexHtml(options))
|
||||
return
|
||||
}
|
||||
// patch rss
|
||||
if (req.url! === '/atom.xml') {
|
||||
res.setHeader('Content-Type', 'application/xml')
|
||||
res.statusCode = 200
|
||||
res.end(await fs.readFile(resolve(options.userRoot, 'dist/atom.xml'), 'utf-8'))
|
||||
return
|
||||
}
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import fs from 'fs'
|
||||
|
||||
import { basename, join, relative } from 'path'
|
||||
import { join, relative } from 'path'
|
||||
import type { Plugin, ResolvedConfig } from 'vite'
|
||||
// import consola from 'consola'
|
||||
import { resolveSiteConfig } from '../config'
|
||||
import type { ResolvedValaxyOptions, ValaxyConfig, ValaxyServerOptions } from '../options'
|
||||
import type { ResolvedValaxyOptions, ValaxyServerOptions } from '../options'
|
||||
import { resolveOptions } from '../options'
|
||||
import { resolveImportPath, slash, toAtFS } from '../utils'
|
||||
import { createMarkdownToVueRenderFn } from '../markdown/markdownToVue'
|
||||
import type { PageDataPayload } from '../../types'
|
||||
|
@ -19,7 +19,7 @@ function generateStyles(roots: string[], options: ResolvedValaxyOptions) {
|
|||
const imports: string[] = []
|
||||
|
||||
// katex
|
||||
if (options.config.features.katex) {
|
||||
if (options.config.features?.katex) {
|
||||
imports.push(`import "${toAtFS(resolveImportPath('katex/dist/katex.min.css', true))}"`)
|
||||
imports.push(`import "${toAtFS(join(options.clientRoot, 'styles/third/katex.scss'))}"`)
|
||||
}
|
||||
|
@ -63,7 +63,9 @@ function generateLocales(roots: string[]) {
|
|||
return imports.join('\n')
|
||||
}
|
||||
|
||||
export function createValaxyPlugin(options: ResolvedValaxyOptions, valaxyConfig: ValaxyConfig, serverOptions: ValaxyServerOptions = {}): Plugin {
|
||||
export function createValaxyPlugin(options: ResolvedValaxyOptions, serverOptions: ValaxyServerOptions = {}): Plugin {
|
||||
const { config: valaxyConfig } = options
|
||||
|
||||
const valaxyPrefix = '/@valaxy'
|
||||
|
||||
let siteConfig = options.config
|
||||
|
@ -184,14 +186,10 @@ export function createValaxyPlugin(options: ResolvedValaxyOptions, valaxyConfig:
|
|||
// handle site.config.ts hmr
|
||||
const { file, server, read } = ctx
|
||||
|
||||
const fileName = basename(file)
|
||||
const isSiteConfig = fileName.startsWith('site.config')
|
||||
const isValaxyConfig = fileName.startsWith('valaxy.config')
|
||||
if (file === options.configFile) {
|
||||
const { config } = await resolveOptions({ userRoot: options.userRoot })
|
||||
|
||||
if (isSiteConfig || isValaxyConfig) {
|
||||
const { config } = await resolveSiteConfig()
|
||||
|
||||
serverOptions.onConfigReload?.(config, options.config, isValaxyConfig)
|
||||
serverOptions.onConfigReload?.(config, options.config)
|
||||
Object.assign(options.config, config)
|
||||
|
||||
siteConfig = config
|
||||
|
|
|
@ -12,7 +12,7 @@ import Components from 'unplugin-vue-components/vite'
|
|||
import { vueI18n } from '@intlify/vite-plugin-vue-i18n'
|
||||
|
||||
import dayjs from 'dayjs'
|
||||
import type { ResolvedValaxyOptions, ValaxyConfig, ValaxyServerOptions } from '../options'
|
||||
import type { ResolvedValaxyOptions, ValaxyServerOptions } from '../options'
|
||||
import { setupMarkdownPlugins } from '../markdown'
|
||||
// import { createMarkdownPlugin, excerpt_separator } from './markdown'
|
||||
// import { formatMdDate } from '../utils/date'
|
||||
|
@ -23,15 +23,14 @@ import { createValaxyPlugin } from '.'
|
|||
|
||||
export async function ViteValaxyPlugins(
|
||||
options: ResolvedValaxyOptions,
|
||||
valaxyConfig: ValaxyConfig = {},
|
||||
serverOptions: ValaxyServerOptions = {},
|
||||
): Promise<(PluginOption | PluginOption[])[] | undefined> {
|
||||
const { roots } = options
|
||||
const { roots, config: valaxyConfig } = options
|
||||
|
||||
// const MarkdownPlugin = createMarkdownPlugin(options)
|
||||
const UnocssPlugin = await createUnocssPlugin(options, valaxyConfig)
|
||||
|
||||
const ValaxyPlugin = createValaxyPlugin(options, valaxyConfig, serverOptions)
|
||||
const ValaxyPlugin = createValaxyPlugin(options, serverOptions)
|
||||
|
||||
// for render markdown excerpt
|
||||
const mdIt = new MarkdownIt({ html: true })
|
||||
|
@ -139,7 +138,7 @@ export async function ViteValaxyPlugins(
|
|||
// options.config.lastUpdated,
|
||||
// )
|
||||
const lastUpdated = options.config.lastUpdated
|
||||
const format = options.config.date.format
|
||||
const format = options.config.date?.format
|
||||
if (!data.date)
|
||||
data.date = fs.statSync(path).mtime
|
||||
|
||||
|
|
|
@ -35,20 +35,20 @@ export async function build(options: ResolvedValaxyOptions) {
|
|||
const DOMAIN = config.url.slice(0, -1)
|
||||
|
||||
const author: Author = {
|
||||
name: options.config.author.name,
|
||||
email: options.config.author.email,
|
||||
link: options.config.author.link,
|
||||
name: config?.author?.name,
|
||||
email: config?.author?.email,
|
||||
link: config?.author?.link,
|
||||
}
|
||||
|
||||
consola.info(`RSS Site Url: ${cyan(siteUrl)}`)
|
||||
|
||||
const ccVersion = (config.license.type === 'zero') ? '1.0' : '4.0'
|
||||
const ccVersion = (config.license?.type === 'zero') ? '1.0' : '4.0'
|
||||
const feedOptions: FeedOptions = {
|
||||
title: config.title,
|
||||
title: config.title || 'Valaxy Blog',
|
||||
description: config.description,
|
||||
id: siteUrl || 'valaxy',
|
||||
link: siteUrl,
|
||||
copyright: `CC ${config.license.type.toUpperCase()} ${ccVersion} ${new Date().getFullYear()} © ${config.author.name}`,
|
||||
copyright: `CC ${config.license?.type?.toUpperCase()} ${ccVersion} ${new Date().getFullYear()} © ${config.author?.name}`,
|
||||
feedLinks: {
|
||||
json: `${siteUrl}feed.json`,
|
||||
atom: `${siteUrl}feed.atom`,
|
||||
|
@ -70,7 +70,7 @@ export async function build(options: ResolvedValaxyOptions) {
|
|||
continue
|
||||
}
|
||||
|
||||
await formatMdDate(data, i, config.date.format, config.lastUpdated)
|
||||
await formatMdDate(data, i, config.date?.format, config.lastUpdated)
|
||||
|
||||
// todo i18n
|
||||
|
||||
|
@ -99,23 +99,23 @@ export async function build(options: ResolvedValaxyOptions) {
|
|||
|
||||
// write
|
||||
feedOptions.author = author
|
||||
feedOptions.image = config.author.avatar.startsWith('http') ? config.author.avatar : `${DOMAIN}${config.author.avatar}`
|
||||
feedOptions.favicon = `${DOMAIN}${config.feed.favicon || config.favicon}`
|
||||
feedOptions.image = config.author?.avatar?.startsWith('http') ? config.author.avatar : `${DOMAIN}${config.author?.avatar}`
|
||||
feedOptions.favicon = `${DOMAIN}${config.feed?.favicon || config.favicon}`
|
||||
|
||||
const feed = new Feed(feedOptions)
|
||||
posts.forEach(item => feed.addItem(item))
|
||||
// items.forEach(i=> console.log(i.title, i.date))
|
||||
|
||||
await fs.ensureDir(dirname(`./dist/${config.feed.name}`))
|
||||
await fs.ensureDir(dirname(`./dist/${config.feed?.name}`))
|
||||
const path = './dist'
|
||||
|
||||
const types = ['xml', 'atom', 'json']
|
||||
types.forEach((type) => {
|
||||
let data = ''
|
||||
let name = `${path}/${config.feed.name || 'feed'}.${type}`
|
||||
let name = `${path}/${config.feed?.name || 'feed'}.${type}`
|
||||
if (type === 'xml') { data = feed.rss2() }
|
||||
else if (type === 'atom') {
|
||||
if (!config.feed.name)
|
||||
if (!config.feed?.name)
|
||||
name = `${path}/atom.xml`
|
||||
data = feed.atom1()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import { createServer as createViteServer, mergeConfig as mergeViteConfig } from
|
|||
|
||||
import type { ResolvedValaxyOptions, ValaxyServerOptions } from './options'
|
||||
import { ViteValaxyPlugins } from './plugins/preset'
|
||||
import { resolveValaxyConfig } from './utils/config'
|
||||
|
||||
export async function createServer(
|
||||
options: ResolvedValaxyOptions,
|
||||
|
@ -13,13 +12,11 @@ export async function createServer(
|
|||
// default editor vscode
|
||||
process.env.EDITOR = process.env.EDITOR || 'code'
|
||||
|
||||
const config = await resolveValaxyConfig(options, viteConfig)
|
||||
|
||||
const server = await createViteServer(
|
||||
mergeViteConfig(
|
||||
config.vite!,
|
||||
viteConfig,
|
||||
{
|
||||
plugins: await ViteValaxyPlugins(options, config, serverOptions),
|
||||
plugins: await ViteValaxyPlugins(options, serverOptions),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import type Vue from '@vitejs/plugin-vue'
|
||||
import type Components from 'unplugin-vue-components/vite'
|
||||
import type { VitePluginConfig as UnoCSSConfig } from 'unocss/vite'
|
||||
import type Pages from 'vite-plugin-pages'
|
||||
import type { UserConfig as ViteUserConfig } from 'vite'
|
||||
import type { presetAttributify, presetIcons, presetTypography, presetUno } from 'unocss'
|
||||
import type { DefaultThemeConfig, UserSiteConfig } from '../types'
|
||||
import type { ResolvedValaxyOptions } from './options'
|
||||
import type { MarkdownOptions } from './markdown'
|
||||
|
||||
export type ValaxyConfig<ThemeConfig = DefaultThemeConfig> = UserSiteConfig<ThemeConfig> & ValaxyExtendConfig
|
||||
export type UserConfig<ThemeConfig = DefaultThemeConfig> = ValaxyConfig<ThemeConfig>
|
||||
/**
|
||||
* fn with options for theme config
|
||||
*/
|
||||
export type ValaxyConfigFn<ThemeConfig = DefaultThemeConfig> = (options: ResolvedValaxyOptions<ThemeConfig>) => ValaxyConfig | Promise<ValaxyConfig>
|
||||
export type ValaxyConfigExport<ThemeConfig = DefaultThemeConfig> = ValaxyConfig<ThemeConfig> | ValaxyConfigFn<ThemeConfig>
|
||||
|
||||
export interface ValaxyExtendConfig {
|
||||
vite?: ViteUserConfig
|
||||
vue?: Parameters<typeof Vue>[0]
|
||||
components?: Parameters<typeof Components>[0]
|
||||
unocss?: UnoCSSConfig
|
||||
/**
|
||||
* unocss presets
|
||||
*/
|
||||
unocssPresets?: {
|
||||
uno?: Parameters<typeof presetUno>[0]
|
||||
attributify?: Parameters<typeof presetAttributify>[0]
|
||||
icons?: Parameters<typeof presetIcons>[0]
|
||||
typography?: Parameters<typeof presetTypography>[0]
|
||||
}
|
||||
pages?: Parameters<typeof Pages>[0]
|
||||
/**
|
||||
* for markdown
|
||||
*/
|
||||
markdown?: MarkdownOptions
|
||||
extendMd?: (ctx: {
|
||||
route: any
|
||||
data: Record<string, any>
|
||||
excerpt?: string
|
||||
path: string
|
||||
}) => void
|
||||
}
|
|
@ -10,6 +10,8 @@ import { createServer } from '../server'
|
|||
import type { ResolvedValaxyOptions } from '../options'
|
||||
import { version } from '../../package.json'
|
||||
import { mergeViteConfigs } from '../common'
|
||||
import type { ValaxyConfigExtendKey } from '../config'
|
||||
|
||||
let server: ViteDevServer | undefined
|
||||
|
||||
export function printInfo(options: ResolvedValaxyOptions, port?: number, remote?: string | boolean) {
|
||||
|
@ -38,6 +40,16 @@ export function printInfo(options: ResolvedValaxyOptions, port?: number, remote?
|
|||
console.log()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const CONFIG_RESTART_FIELDS: ValaxyConfigExtendKey[] = [
|
||||
'vite',
|
||||
'vue',
|
||||
'unocss',
|
||||
'unocssPresets',
|
||||
'markdown',
|
||||
'extendMd',
|
||||
]
|
||||
|
||||
export async function initServer(options: ResolvedValaxyOptions, viteConfig: InlineConfig) {
|
||||
if (server)
|
||||
await server.close()
|
||||
|
@ -49,7 +61,7 @@ export async function initServer(options: ResolvedValaxyOptions, viteConfig: Inl
|
|||
|
||||
try {
|
||||
server = await createServer(options, viteConfigs, {
|
||||
async onConfigReload(newSiteConfig, siteConfig, force = false) {
|
||||
async onConfigReload(newConfig, config, force = false) {
|
||||
if (force) {
|
||||
consola.info('[valaxy]', `${yellow('force')} reload the server`)
|
||||
initServer(options, viteConfig)
|
||||
|
@ -57,7 +69,7 @@ export async function initServer(options: ResolvedValaxyOptions, viteConfig: Inl
|
|||
|
||||
let reload = false
|
||||
|
||||
if (newSiteConfig.theme !== siteConfig.theme)
|
||||
if (newConfig.theme !== config.theme)
|
||||
reload = true
|
||||
|
||||
// consola.info('Find new icon, reload server...')
|
||||
|
@ -65,6 +77,11 @@ export async function initServer(options: ResolvedValaxyOptions, viteConfig: Inl
|
|||
// console.log()
|
||||
// reload = true
|
||||
|
||||
// if (CONFIG_RESTART_FIELDS.some(i => !equal(newConfig[i], config[i]))) {
|
||||
// reload = true
|
||||
// console.log(yellow('\n restarting on config change\n'))
|
||||
// }
|
||||
|
||||
if (reload)
|
||||
initServer(options, viteConfig)
|
||||
},
|
||||
|
|
|
@ -1,15 +1,73 @@
|
|||
import type { InlineConfig } from 'vite'
|
||||
import { mergeConfig as mergeViteConfig } from 'vite'
|
||||
import type { ResolvedValaxyOptions } from '../options'
|
||||
import { mergeValaxyConfigs } from '../common'
|
||||
import { mergeConfig as mergeViteConfig, normalizePath } from 'vite'
|
||||
import { loadConfig } from 'unconfig'
|
||||
import { createDefu } from 'defu'
|
||||
import { isFunction } from '@antfu/utils'
|
||||
import type { ResolvedValaxyOptions, ValaxyEntryOptions } from '../options'
|
||||
import type { ValaxyConfig, ValaxyConfigFn } from '../types'
|
||||
|
||||
export async function resolveValaxyConfig(options: ResolvedValaxyOptions, viteConfig: InlineConfig = {}) {
|
||||
const resolved = await mergeValaxyConfigs(options)
|
||||
/**
|
||||
* merge valaxy.config
|
||||
* (source, default)
|
||||
*/
|
||||
export const mergeValaxyConfig = createDefu((obj: any, key, value) => {
|
||||
if (isFunction(obj[key]) && isFunction(value)) {
|
||||
obj[key] = function (...args: any[]) {
|
||||
obj[key].call(this, ...args)
|
||||
value.call(this, ...args)
|
||||
}
|
||||
}
|
||||
if (key === 'vite') {
|
||||
// a deep copy and needs to be taken over
|
||||
obj[key] = mergeViteConfig(obj[key], value)
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
if (!resolved.vite)
|
||||
resolved.vite = {}
|
||||
/**
|
||||
* resolve valaxy config from special root
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
export async function resolveValaxyConfigFromRoot(root: string, options?: ResolvedValaxyOptions) {
|
||||
// c12 merge array twice, so i deprecated it
|
||||
const { config, sources } = await loadConfig<ValaxyConfig>({
|
||||
sources: {
|
||||
files: 'valaxy.config',
|
||||
async rewrite(c: ValaxyConfig | ValaxyConfigFn) {
|
||||
const config = await (typeof c === 'function' ? c(options || {} as ResolvedValaxyOptions) : c)
|
||||
return config
|
||||
},
|
||||
},
|
||||
cwd: root,
|
||||
})
|
||||
|
||||
resolved.vite = mergeViteConfig(resolved.vite, viteConfig)
|
||||
if (!config.vite)
|
||||
config.vite = {}
|
||||
|
||||
return resolved
|
||||
return {
|
||||
config,
|
||||
sources,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* resolve user valaxy config
|
||||
* options only have userRoot
|
||||
* @param options
|
||||
* @param viteConfig
|
||||
* @returns
|
||||
*/
|
||||
export async function resolveValaxyConfig(options: ValaxyEntryOptions) {
|
||||
// const resolved = await mergeValaxyConfig(options)
|
||||
// valaxyConfig = mergeValaxyConfig(valaxyConfig, config)
|
||||
const { config: userValaxyConfig, sources } = await resolveValaxyConfigFromRoot(options.userRoot || process.cwd())
|
||||
const configFile = normalizePath(sources[0] || '')
|
||||
|
||||
const theme = options.theme || userValaxyConfig.theme || 'yun'
|
||||
|
||||
return {
|
||||
config: userValaxyConfig,
|
||||
configFile,
|
||||
theme,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,27 +3,11 @@ import isInstalledGlobally from 'is-installed-globally'
|
|||
import globalDirs from 'global-dirs'
|
||||
import { sync as resolve } from 'resolve'
|
||||
import consola from 'consola'
|
||||
import { createDefu } from 'defu'
|
||||
import { isFunction } from '@antfu/utils'
|
||||
import { mergeConfig as mergeViteConfig } from 'vite'
|
||||
|
||||
export * from './getGitTimestamp'
|
||||
|
||||
export const EXTERNAL_URL_RE = /^https?:/i
|
||||
|
||||
export const mergeFullConfig = createDefu((obj: any, key, value) => {
|
||||
if (isFunction(obj[key]) && isFunction(value)) {
|
||||
obj[key] = function (...args: any[]) {
|
||||
obj[key].call(this, ...args)
|
||||
value.call(this, ...args)
|
||||
}
|
||||
}
|
||||
if (key === 'vite') {
|
||||
// a deep copy and needs to be taken over
|
||||
obj[key] = mergeViteConfig(obj[key], value)
|
||||
return true
|
||||
}
|
||||
})
|
||||
/**
|
||||
* transform obj for vite code
|
||||
* @param obj
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export type ValaxyThemeConfig = Record<string, any>
|
||||
export type DefaultThemeConfig = Record<string, any>
|
||||
|
||||
export interface SocialLink {
|
||||
/**
|
||||
|
@ -25,8 +25,8 @@ export interface AlgoliaSearchOptions {
|
|||
initialQuery?: string
|
||||
}
|
||||
|
||||
// packages/valaxy/node/config.ts
|
||||
export interface ValaxySiteConfig<T = ValaxyThemeConfig> {
|
||||
// shared with valaxy node and client
|
||||
export interface SiteConfig<T = DefaultThemeConfig> {
|
||||
/**
|
||||
* enable auto (light/dark mode)
|
||||
* @default 'auto'
|
||||
|
@ -226,5 +226,4 @@ export type PartialDeep<T> = {
|
|||
* Valaxy User Config
|
||||
* @description Valaxy 用户配置
|
||||
*/
|
||||
export type UserConfig<ThemeConfig = ValaxyThemeConfig> = PartialDeep<ValaxySiteConfig<ThemeConfig>>
|
||||
|
||||
export type UserSiteConfig<ThemeConfig = DefaultThemeConfig> = PartialDeep<SiteConfig<ThemeConfig>>
|
||||
|
|
Loading…
Reference in New Issue