feat: seperate site.config.ts & valaxy.config.ts (#57)

* chore: defineThemePlugin to defineTheme

* chore: ValaxyThemePlugin to ValaxyTheme

* chore: ValaxyPluginOptions to ValaxyOptions

* feat: add ValaxyPlugin interface

* feat: add ValaxyPlugin interface

* chore: defienConfig to defineBlog and blog file change

* chore: defineConfigWithTheme to defineBlogWithTheme

* chore: change config to blog

* chore: modify blog.config details

* chore: change hmr config import id

* chore: change init config to init blog

* chore: blog config to site config

* chore: change config path

* refactor: reset theme valaxy config read #55

* chore: resolveValaxyConfig to resolveSiteConfig

* feat: add valaxy config reload server

* chore: fix type error and template change

* fix: build not theme vite config

* fix: fullMerge vite take over

* fix: user and theme weight problem

* feat: useSite to useSiteConfig

* chore: change site symbol

* chore: change valaxy node

* feat: replace site config use the rest

* fix: variable name adjustment

* chore: fix lint

* chore: solve conflicts

Co-authored-by: YunYouJun <me@yunyoujun.cn>
This commit is contained in:
Mao Mr 2022-07-16 23:09:02 +08:00 committed by GitHub
parent bfd408a420
commit d741bdfeba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 706 additions and 745 deletions

View File

@ -46,7 +46,7 @@ For a example, you can see [demo/yun](./demo/yun/) folder.
- ⚡️ [Vue 3](https://github.com/vuejs/vue-next), [Vite 2](https://github.com/vitejs/vite), [pnpm](https://pnpm.js.org/), [ESBuild](https://github.com/evanw/esbuild) - born with fastness
- 🔥 Hot Reload with Config & Markdown
- 🔧 Type Tooltip for all config by `valaxy.config.ts`
- 🔧 Type Tooltip for all config by `valaxy.config.ts` and `site.config.ts`
- 🗒 Extended Markdown Frontmatter
- 🗂 File based routing via [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages)
- 📦 Components auto importing via [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components)

184
demo/yun/site.config.ts Normal file
View File

@ -0,0 +1,184 @@
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号',
},
},
},
})

View File

@ -1,183 +1,39 @@
import { defineConfig } from 'valaxy'
import type { ThemeConfig } from 'valaxy-theme-yun'
// import { VitePWA } from 'vite-plugin-pwa'
import Inspect from 'vite-plugin-inspect'
/**
* User Config
* do not use export const config to avoid defu conflict
*/
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: '云游君',
const safelist = [
'i-ri-home-line',
]
export default defineConfig({
vite: {
// https://github.com/antfu/vite-plugin-inspect
// Visit http://localhost:3333/__inspect/ to see the inspector
plugins: [Inspect()],
},
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',
},
unocss: {
safelist,
},
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',
markdown: {
blocks: {
tip: {
icon: 'i-carbon-thumbs-up',
text: 'ヒント',
langs: {
'zh-CN': '提示',
},
},
{
name: 'QQ 支付',
url: 'https://cdn.yunyoujun.cn/img/donate/qqpay-qrcode.png',
color: '#12B7F5',
icon: 'i-ri-qq-line',
warning: {
icon: 'i-carbon-warning-alt',
text: '注意',
},
{
name: '微信支付',
url: 'https://cdn.yunyoujun.cn/img/donate/wechatpay-qrcode.jpg',
color: '#2DC100',
icon: 'i-ri-wechat-pay-line',
danger: {
icon: 'i-carbon-warning',
text: '警告',
},
],
},
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号',
info: {
text: 'información',
},
},
},

View File

@ -1,72 +0,0 @@
import { defineConfig } from 'vite'
// import { VitePWA } from 'vite-plugin-pwa'
import Inspect from 'vite-plugin-inspect'
const safelist = [
'i-ri-home-line',
]
export default defineConfig({
plugins: [
// https://github.com/antfu/vite-plugin-inspect
// Visit http://localhost:3333/__inspect/ to see the inspector
Inspect(),
// VitePWA({
// registerType: 'autoUpdate',
// includeAssets: ['favicon.svg', 'safari-pinned-tab.svg'],
// manifest: {
// name: 'Theme Yun',
// short_name: 'Yun',
// theme_color: '#ffffff',
// icons: [
// {
// src: '/pwa-192x192.png',
// sizes: '192x192',
// type: 'image/png',
// },
// {
// src: '/pwa-512x512.png',
// sizes: '512x512',
// type: 'image/png',
// },
// {
// src: '/pwa-512x512.png',
// sizes: '512x512',
// type: 'image/png',
// purpose: 'any maskable',
// },
// ],
// },
// }),
],
valaxy: {
unocss: {
safelist,
},
markdown: {
blocks: {
tip: {
icon: 'i-carbon-thumbs-up',
text: 'ヒント',
langs: {
'zh-CN': '提示',
},
},
warning: {
icon: 'i-carbon-warning-alt',
text: '注意',
},
danger: {
icon: 'i-carbon-warning',
text: '警告',
},
info: {
text: 'información',
},
},
},
},
})

View File

@ -11,9 +11,9 @@ end: false
> 在每篇文章末尾,展示赞助(打赏)信息。
```ts
// valaxy.config.ts
import { defineConfig } from 'valaxy'
export default defineConfig({
// site.config.ts
import { defineSite } from 'valaxy'
export default defineSite({
sponsor: {
enable: true,
methods: [

View File

@ -75,7 +75,7 @@ const b = a
> `valaxy-theme-yun` 支持
```ts
// valaxy.config.ts
// site.config.ts
export default {
themeConfig: {
colors: {
@ -139,9 +139,9 @@ Katex is enabled by default.
:::
```ts
// valaxy.config.ts
import { defineConfig } from 'valaxy'
export default defineConfig({
// site.config.ts
import { defineSite } from 'valaxy'
export default defineSite({
features: {
// disable katex
katex: false

View File

@ -80,7 +80,7 @@ See `http://localhost:4859/`, have fun!
### Config
Modify `valaxy.config.ts` to custom your blog.
Modify `site.config.ts` to custom your blog.
English & Chinese Docs is coming!

View File

@ -18,10 +18,10 @@ Valaxy 决定中心化地提供各类封装好的评论钩子函数。
```vue {2}
<script lang="ts" setup>
import { useConfig, useWaline } from 'valaxy'
import { useSite, useWaline } from 'valaxy'
// 读取用户配置
const config = useConfig()
const config = useSite()
// 挂载 Waline
useWaline(config.value.comment.waline)
</script>

View File

@ -40,7 +40,7 @@ export default defineConfig({
```ts
// provided by valaxy, just as a tip
export interface ValaxyPluginOptions {
export interface ValaxyConfig {
vue?: Parameters<typeof Vue>[0]
components?: Parameters<typeof Components>[0]
unocss?: UnoCSSConfig

9
docs/site.config.ts Normal file
View File

@ -0,0 +1,9 @@
import { defineSite } from 'valaxy'
export default defineSite({
title: 'Valaxy',
url: 'https://valaxy.site',
theme: 'press',
themeConfig: {},
})

View File

@ -1,9 +1,29 @@
import { defineConfig } from 'valaxy'
const safelist = [
'i-ri-home-line',
]
export default defineConfig({
title: 'Valaxy',
url: 'https://valaxy.site',
vite: {
base: '/',
},
unocss: {
safelist,
},
theme: 'press',
themeConfig: {},
markdown: {
blocks: {
tip: {
icon: 'i-carbon-thumbs-up',
},
warning: {
icon: 'i-carbon-warning-alt',
},
danger: {
icon: 'i-carbon-warning',
},
info: {
text: 'i-carbon-information',
},
},
},
})

View File

@ -1,32 +0,0 @@
import { defineConfig } from 'vite'
const safelist = [
'i-ri-home-line',
]
export default defineConfig({
base: '/',
plugins: [],
valaxy: {
unocss: {
safelist,
},
markdown: {
blocks: {
tip: {
icon: 'i-carbon-thumbs-up',
},
warning: {
icon: 'i-carbon-warning-alt',
},
danger: {
icon: 'i-carbon-warning',
},
info: {
text: 'i-carbon-information',
},
},
},
},
})

View File

@ -36,8 +36,8 @@ async function init() {
console.log(` ${bold('Check it')}:`)
console.log()
console.log(`- Change ${bold('author')} name in ${yellow('LICENSE')} & ${green('package.json')} & ${blue('.github')}`)
console.log(`- Change ${blue('valaxy.config.ts')} theme: ${yellow('starter')} to ${cyan(`${themeName}`)}`)
console.log(`- Rename ${yellow('valaxy-theme-starter')} to ${cyan(`valaxy-theme-${themeName}`)}`)
console.log(`- Change ${blue('site.config.ts')} theme: ${yellow('starter')} to ${cyan(`${themeName}`)}`)
console.log(`- Rename ${yellow(`valaxy-theme-${themeName}`)} to ${cyan(`valaxy-theme-${themeName}`)}`)
console.log()
console.log(` ${cyan('✨')}`)
console.log()

View File

@ -18,7 +18,7 @@ See `http://localhost:4859/`, have fun!
### Config
Modify `valaxy.config.ts` to custom your blog.
Modify `site.config.ts` to custom your blog.
English & Chinese Docs is coming!

View File

@ -17,4 +17,4 @@ Write your first post!
## Usage
Modify `valaxy.config.ts` to custom your blog.
Modify `site.config.ts` to custom your blog.

View File

@ -0,0 +1,155 @@
import { defineSite } from 'valaxy'
import type { ThemeConfig } from 'valaxy-theme-yun'
/**
* User Config
*/
export default defineSite<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号',
},
},
},
})

View File

@ -1,155 +1,13 @@
import { defineConfig } from 'valaxy'
import type { ThemeConfig } from 'valaxy-theme-yun'
// add icons what you will need
const safelist = [
'i-ri-home-line',
]
/**
* User Config
*/
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号',
},
},
},
export default defineConfig({
unocss: { safelist },
})

View File

@ -1,14 +1,5 @@
import { defineConfig } from 'vite'
// add icons what you will need
const safelist = [
'i-ri-home-line',
]
export default defineConfig({
valaxy: {
unocss: {
safelist,
},
},
})

View File

@ -1,12 +1,13 @@
<script lang="ts" setup>
import type { PageData, Post } from 'valaxy'
import { useConfig, useFrontmatter, useLayout, useSidebar } from 'valaxy'
import { useFrontmatter, useLayout, useSidebar, useSite } from 'valaxy'
defineProps<{
frontmatter: Post
data?: PageData
}>()
const config = useConfig()
const config = useSite()
const frontmatter = useFrontmatter()
const { hasSidebar } = useSidebar()

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { useConfig, useSidebar } from 'valaxy'
import { useSidebar, useSite } from 'valaxy'
import { useThemeConfig } from '../../composables'
import PressSwitchAppearance from './PressSwitchAppearance.vue'
@ -13,7 +13,7 @@ defineEmits<{
const { hasSidebar } = useSidebar()
const config = useConfig()
const config = useSite()
const themeConfig = useThemeConfig()
</script>

View File

@ -1,5 +1,5 @@
import { computed } from 'vue'
import { useConfig } from 'valaxy'
import { useSite } from 'valaxy'
import type { ThemeConfig } from '../types'
/**
@ -7,6 +7,6 @@ import type { ThemeConfig } from '../types'
* @returns
*/
export function useThemeConfig<T = ThemeConfig>() {
const config = useConfig<T>()
const config = useSite<T>()
return computed(() => config!.value.themeConfig)
}

View File

@ -1,7 +1,3 @@
import { defineThemePlugin } from 'valaxy'
import type { ResolvedValaxyOptions } from 'valaxy'
import type { Plugin } from 'vite'
export * from '../config'
export * from '../types'
@ -10,34 +6,3 @@ export interface UserOptions {
primary: string
}
}
function ThemeYunVitePlugin(options: ResolvedValaxyOptions): Plugin {
const themeConfig = options.config.themeConfig
return {
name: 'valaxy-theme-yun',
enforce: 'pre',
config() {
return {
css: {
preprocessorOptions: {
scss: {
additionalData: `$c-primary: ${themeConfig.colors?.primary || '#0078E7'} !default;`,
},
},
},
optimizeDeps: {
exclude: ['@docsearch/js'],
},
}
},
}
}
export default defineThemePlugin((options) => {
return {
vite: {
plugins: [ThemeYunVitePlugin(options)],
},
}
})

View File

@ -0,0 +1,36 @@
import type { ResolvedValaxyOptions } from 'valaxy'
import { defineConfig } from 'valaxy/node'
import type { Plugin } from 'vite'
function ThemeYunVitePlugin(options: ResolvedValaxyOptions): Plugin {
const themeConfig = options.config.themeConfig
return {
name: 'valaxy-theme-yun',
enforce: 'pre',
config() {
return {
css: {
preprocessorOptions: {
scss: {
additionalData: `$c-primary: ${themeConfig.colors?.primary || '#0078E7'} !default;`,
},
},
},
optimizeDeps: {
exclude: ['@docsearch/js'],
},
}
},
}
}
const config = defineConfig((options) => {
return {
vite: {
plugins: [ThemeYunVitePlugin(options)],
},
}
})
export default config

View File

@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { PageData, Post } from 'valaxy'
import { useConfig, usePostTitle } from 'valaxy'
import { usePostTitle, useSite } from 'valaxy'
import { computed, defineAsyncComponent } from 'vue'
import { usePostProperty } from '../composables'
@ -8,7 +8,7 @@ const props = defineProps<{
frontmatter: Post
data?: PageData
}>()
const config = useConfig()
const config = useSite()
const { styles, icon, color } = usePostProperty(props.frontmatter.type)
const title = usePostTitle(computed(() => props.frontmatter))

View File

@ -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 { useConfig } from 'valaxy'
import { useSite } from 'valaxy'
import { useRoute, useRouter } from 'vue-router'
const router = useRouter()
const route = useRoute()
const config = useConfig()
const config = useSite()
onMounted(() => {
initialize(config.value.search.algolia)

View File

@ -1,6 +1,6 @@
<script lang="ts" setup>
import { capitalize, computed } from 'vue'
import { useConfig } from 'valaxy'
import { useSite } 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 = useConfig()
const config = useSite()
const themeConfig = useThemeConfig()
const year = new Date().getFullYear()

View File

@ -1,8 +1,8 @@
<script lang="ts" setup>
import { useConfig } from 'valaxy'
import { useSite } from 'valaxy'
import { useRouter } from 'vue-router'
const config = useConfig()
const config = useSite()
const router = useRouter()
</script>

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { useConfig } from 'valaxy'
import { useSite } from 'valaxy'
const config = useConfig()
const config = useSite()
</script>
<template>

View File

@ -1,10 +1,10 @@
<script lang="ts" setup>
import { useConfig } from 'valaxy'
import { useSite } from 'valaxy'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const config = useConfig()
const config = useSite()
const showQr = ref(false)
</script>

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { useConfig, useTwikoo } from 'valaxy'
import { useSite, useTwikoo } from 'valaxy'
const config = useConfig()
const config = useSite()
useTwikoo(config.value.comment.twikoo)
</script>

View File

@ -1,9 +1,9 @@
<script lang="ts" setup>
import { useConfig } from 'valaxy'
import { useSite } from 'valaxy'
// we need import on demand
import { useWaline } from 'valaxy/client/composables/comments/waline'
const config = useConfig()
const config = useSite()
useWaline(config.value.comment.waline, config.value.cdn.prefix)
</script>

View File

@ -1,5 +1,5 @@
import { computed } from 'vue'
import { useConfig } from 'valaxy'
import { useSite } 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 = useConfig<ThemeConfig>()
const config = useSite<ThemeConfig>()
return computed(() => config!.value.themeConfig)
}

View File

@ -1,8 +1,8 @@
<script lang="ts" setup>
import { useAppStore, useConfig, useLayout } from 'valaxy'
import { useAppStore, useLayout, useSite } from 'valaxy'
const app = useAppStore()
const config = useConfig()
const config = useSite()
const isHome = useLayout('home')
</script>

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { useConfig } from 'valaxy'
import { useSite } from 'valaxy'
const config = useConfig()
const config = useSite()
</script>
<template>

View File

@ -1,8 +1,8 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { useConfig, useFrontmatter, useFullUrl } from 'valaxy'
import { useFrontmatter, useFullUrl, useSite } from 'valaxy'
const config = useConfig()
const config = useSite()
const frontmatter = useFrontmatter()
const url = useFullUrl()

View File

@ -1,7 +1,3 @@
import { defineThemePlugin } from 'valaxy'
import type { ResolvedValaxyOptions } from 'valaxy'
import type { Plugin } from 'vite'
export * from '../config'
export * from '../types'
@ -11,33 +7,3 @@ export interface UserOptions {
}
}
function ThemeYunVitePlugin(options: ResolvedValaxyOptions): Plugin {
const themeConfig = options.config.themeConfig
return {
name: 'valaxy-theme-yun',
enforce: 'pre',
config() {
return {
css: {
preprocessorOptions: {
scss: {
additionalData: `$c-primary: ${themeConfig.colors?.primary || '#0078E7'} !default;`,
},
},
},
optimizeDeps: {
exclude: ['@docsearch/js'],
},
}
},
}
}
export default defineThemePlugin((options) => {
return {
vite: {
plugins: [ThemeYunVitePlugin(options)],
},
}
})

View File

@ -0,0 +1,36 @@
import type { ResolvedValaxyOptions } from 'valaxy'
import { defineConfig } from 'valaxy/node'
import type { Plugin } from 'vite'
function ThemeYunVitePlugin(options: ResolvedValaxyOptions): Plugin {
const themeConfig = options.config.themeConfig
return {
name: 'valaxy-theme-yun',
enforce: 'pre',
config() {
return {
css: {
preprocessorOptions: {
scss: {
additionalData: `$c-primary: ${themeConfig.colors?.primary || '#0078E7'} !default;`,
},
},
},
optimizeDeps: {
exclude: ['@docsearch/js'],
},
}
},
}
}
const config = defineConfig((options) => {
return {
vite: {
plugins: [ThemeYunVitePlugin(options)],
},
}
})
export default config

View File

@ -6,13 +6,13 @@ 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 { useConfig } from './config'
import { useSite } 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 = useConfig()
const config = useSite()
useHead({
title: config.value.title,
link: [

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useConfig } from '../config'
import { useSite } from '../config'
withDefaults(defineProps<{
url?: string
@ -11,7 +11,7 @@ withDefaults(defineProps<{
const { t, locale } = useI18n()
const config = useConfig()
const config = useSite()
const ccVersion = (config.value.license.type === 'zero') ? '1.0' : '4.0'
const ccPrefix = (config.value.license.type === 'zero') ? 'publicdomain' : 'licenses'

View File

@ -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 { useConfig } from '../..'
import { useSite } from '../..'
declare global {
interface Window {
@ -24,7 +24,7 @@ declare global {
* @param options
*/
export function useTwikoo(options: {} = {}) {
const config = useConfig()
const config = useSite()
const cdnPrefix = computed(() => config.value.cdn.prefix)
const route = useRoute()

View File

@ -3,7 +3,7 @@ import { computed, inject } from 'vue'
import { isClient } from '@vueuse/core'
import type { PageData, Post } from '../../types'
import { useConfig } from '../config'
import { useSite } from '../config'
export function useFrontmatter() {
const route = useRoute()
@ -25,7 +25,7 @@ export function useData(): PageData {
* get full url
*/
export function useFullUrl() {
const config = useConfig()
const config = useSite()
const route = useRoute()
const url = computed(() => {
const siteUrl = config.value.url.endsWith('/') ? config.value.url.slice(0, -1) : config.value.url

View File

@ -1,7 +1,7 @@
import { useScriptTag } from '@vueuse/core'
import { useHead } from '@vueuse/head'
import { computed } from 'vue'
import { useConfig } from '../..'
import { useSite } from '../..'
/**
* use MetingJS and Aplayer
@ -9,7 +9,7 @@ import { useConfig } from '../..'
* @see https://github.com/metowolf/MetingJS
*/
export function useAplayer() {
const config = useConfig()
const config = useSite()
const cdnPrefix = computed(() => config.value.cdn.prefix)
useHead({

View File

@ -1,5 +1,5 @@
// @ts-expect-error virtual module @valaxyjs/config
import valaxyConfig from '/@valaxyjs/config'
import valaxySiteConfig from '/@valaxyjs/site'
// @ts-expect-error virtual module @valaxyjs/context
import valaxyContext from '/@valaxyjs/context'
import type { ComputedRef, InjectionKey } from 'vue'
@ -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 { ValaxyConfig } from 'valaxy/types'
import type { ValaxySiteConfig } from 'valaxy/types'
/**
* parse valaxy config
@ -24,16 +24,16 @@ interface ValaxyContext {
userRoot: string
}
export const valaxyConfigSymbol: InjectionKey<ComputedRef<ValaxyConfig>> = Symbol('valaxy:config')
export const valaxyConfigRef = shallowRef<ValaxyConfig>(parse<ValaxyConfig>(valaxyConfig))
export const valaxySiteConfigSymbol: InjectionKey<ComputedRef<ValaxySiteConfig>> = Symbol('valaxy:site')
export const valaxySiteConfigRef = shallowRef<ValaxySiteConfig>(parse<ValaxySiteConfig>(valaxySiteConfig))
export const valaxyContextRef = shallowRef<ValaxyContext>(parse<ValaxyContext>(valaxyContext))
// hmr
if (import.meta.hot) {
// /@valaxyjs/config must be static string
import.meta.hot.accept('/@valaxyjs/config', (m) => {
valaxyConfigRef.value = parse<ValaxyConfig>(m.default)
// /@valaxyjs/site must be static string
import.meta.hot.accept('/@valaxyjs/site', (m) => {
valaxySiteConfigRef.value = parse<ValaxySiteConfig>(m.default)
})
// context
@ -42,8 +42,8 @@ if (import.meta.hot) {
})
}
export function initConfig() {
return computed(() => valaxyConfigRef.value)
export function initSite() {
return computed(() => valaxySiteConfigRef.value)
}
export function initContext() {
@ -55,8 +55,8 @@ export function initContext() {
* @public
* @returns
*/
export function useConfig<ThemeConfig = any>() {
const config = inject<ComputedRef<ValaxyConfig<ThemeConfig>>>(valaxyConfigSymbol)
export function useSite<ThemeConfig = any>() {
const config = inject<ComputedRef<ValaxySiteConfig<ThemeConfig>>>(valaxySiteConfigSymbol)
if (!config)
throw new Error('[Valaxy] config not properly injected in app')
return config!
@ -69,6 +69,6 @@ export function useConfig<ThemeConfig = any>() {
* @returns
*/
export function useThemeConfig<T = Record<string, any>>() {
const config = useConfig<T>()
const config = useSite<T>()
return computed(() => config!.value.themeConfig)
}

View File

@ -12,7 +12,7 @@ import { useStorage } from '@vueuse/core'
import type { Router } from 'vue-router'
import type { PageDataPayload } from '../../types'
import { initConfig, valaxyConfigSymbol } from '../config'
import { initSite, valaxySiteConfigSymbol } from '../config'
import { ensureSuffix } from '@antfu/utils'
import type { UserModule } from 'valaxy/client/types'
@ -45,8 +45,8 @@ function shouldHotReload(payload: PageDataPayload): boolean {
export const install: UserModule = ({ app, router }) => {
// inject valaxy config before modules
const config = initConfig()
app.provide(valaxyConfigSymbol, config)
const config = initSite()
app.provide(valaxySiteConfigSymbol, config)
const locale = useStorage('valaxy-locale', config.value.lang || 'en')

View File

@ -11,11 +11,10 @@ export async function build(
options: ResolvedValaxyOptions,
viteConfig: InlineConfig = {},
) {
const valaxyConfig = await resolveValaxyConfig(options, viteConfig)
const inlineConfig = mergeConfig({
plugins: await ViteValaxyPlugins(options, valaxyConfig),
}, viteConfig)
const config = await resolveValaxyConfig(options, viteConfig)
const inlineConfig = mergeConfig(config.vite!, {
plugins: await ViteValaxyPlugins(options, config),
})
await viteBuild(inlineConfig)
}
@ -24,10 +23,10 @@ export async function ssgBuild(
options: ResolvedValaxyOptions,
viteConfig: InlineConfig = {},
) {
const valaxyConfig = await resolveValaxyConfig(options, viteConfig)
const config = await resolveValaxyConfig(options, viteConfig)
const defaultConfig: InlineConfig = {
plugins: await ViteValaxyPlugins(options, valaxyConfig),
plugins: await ViteValaxyPlugins(options, config),
}
defaultConfig.ssgOptions = {
@ -42,7 +41,7 @@ export async function ssgBuild(
},
dirStyle: 'nested',
}
const inlineConfig: InlineConfig = mergeConfig(defaultConfig, viteConfig)
const inlineConfig: InlineConfig = mergeConfig(config.vite!, defaultConfig)
await viteSsgBuild({}, inlineConfig)
}

View File

@ -3,9 +3,10 @@ import { join } from 'path'
import type { ConfigEnv, InlineConfig } from 'vite'
import { uniq } from '@antfu/utils'
import { loadConfigFromFile, mergeConfig } from 'vite'
import type { ResolvedValaxyOptions } from './options'
import { toAtFS } from './utils'
import { loadConfig } from 'unconfig'
import type { ResolvedValaxyOptions, ValaxyConfig } from './options'
import { mergeFullConfig, toAtFS } from './utils'
import type { ValaxyConfigExport } from './config'
export async function mergeViteConfigs({ userRoot, themeRoot }: ResolvedValaxyOptions, command: 'serve' | 'build') {
const configEnv: ConfigEnv = {
mode: 'development',
@ -15,10 +16,7 @@ export async function mergeViteConfigs({ userRoot, themeRoot }: ResolvedValaxyOp
let resolvedConfig: InlineConfig = {}
// let vite default config file be clientRoot/vite.config.ts
const files = uniq([
userRoot,
themeRoot,
]).map(i => join(i, 'vite.config.ts'))
const files = uniq([themeRoot, userRoot]).map(i => join(i, 'vite.config.ts'))
for await (const file of files) {
if (!existsSync(file))
@ -32,12 +30,35 @@ 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 = ''
let body = ''
const roots = [themeRoot, userRoot]
const roots = [userRoot, themeRoot]
if (config.mode === 'auto') {
head += `

View File

@ -6,26 +6,35 @@ import { normalizePath } from 'vite'
import { loadConfig } from 'unconfig'
import type { VitePluginConfig as UnoCssConfig } from 'unocss/vite'
import type { Awaitable } from '@antfu/utils'
import type { UserConfig, ValaxyConfig } from '../types'
import type { ResolvedValaxyOptions, ValaxyEntryOptions, ValaxyThemePlugin } from './options'
import type { UserConfig, ValaxySiteConfig } from '../types'
import type { ResolvedValaxyOptions, ValaxyConfig, ValaxyEntryOptions } from './options'
/**
* Type config helper
* Type site helper
*/
export function defineConfig<ThemeConfig>(config: UserConfig<ThemeConfig>) {
export function defineSite<ThemeConfig>(config: UserConfig<ThemeConfig>) {
return config
}
/**
* Type config helper for custom theme config
* Type site helper for custom theme site
*/
export function defineConfigWithTheme<ThemeConfig>(
export function defineSiteWithTheme<ThemeConfig>(
config: UserConfig<ThemeConfig>,
) {
return config
}
const defaultValaxyConfig: ValaxyConfig = {
export type ValaxyConfigExport = ValaxyConfig | Promise<ValaxyConfig> | ValaxyConfigFn
export type ValaxyConfigFn = (options: ResolvedValaxyOptions) => ValaxyConfig | Promise<ValaxyConfig>
/**
* Type valaxy config helper
*/
export function defineConfig(config: ValaxyConfigExport) {
return config
}
const defaultSiteConfig: ValaxySiteConfig = {
mode: 'auto',
url: '/',
lang: 'en',
@ -110,17 +119,17 @@ const defaultValaxyConfig: ValaxyConfig = {
}
// for user config
export async function resolveConfig(options: ValaxyEntryOptions = {}) {
export async function resolveSiteConfig(options: ValaxyEntryOptions = {}) {
// c12 merge array twice, so i deprecated it
// const { config, configFile } = await loadConfig<ValaxyConfig>({
// const { config, configFile } = await loadConfig<ValaxySiteConfig>({
// name: 'valaxy',
// defaults: defaultValaxyConfig,
// defaults: defaultSiteConfig,
// })
const { config: userConfig, sources } = await loadConfig<ValaxyConfig>({
const { config: userConfig, sources } = await loadConfig<ValaxySiteConfig>({
sources: [
{
files: 'valaxy.config',
files: 'site.config',
extensions: ['ts', 'js', 'mjs', 'cjs', 'json'],
},
],
@ -129,7 +138,7 @@ export async function resolveConfig(options: ValaxyEntryOptions = {}) {
const configFile = normalizePath(sources[0] || '')
const config = defu(userConfig, defaultValaxyConfig)
const config = defu(userConfig, defaultSiteConfig)
// ensure suffix for cdn prefix
config.cdn.prefix = ensureSuffix('/', config.cdn.prefix)
@ -160,13 +169,6 @@ export async function resolveConfig(options: ValaxyEntryOptions = {}) {
}
}
export type ThemeConfigExport = ValaxyThemePlugin | Promise<ValaxyThemePlugin> | ThemeConfigFn
export type ThemeConfigFn = (options: ResolvedValaxyOptions) => ValaxyThemePlugin | Promise<ValaxyThemePlugin>
export function defineThemePlugin(config: ThemeConfigExport) {
return config
}
export type UnoSetup = () => Awaitable<Partial<UnoCssConfig> | undefined>
export function defineUnoSetup(fn: UnoSetup) {

View File

@ -1,16 +1,8 @@
import type { ViteSSGOptions } from 'vite-ssg'
import type { ValaxyPluginOptions } from './options'
// extend vite.config.ts
declare module 'vite' {
interface UserConfig {
/**
* Custom internal plugin options for Valaxy (advanced)
*
* @see ./options.ts'
*/
valaxy?: ValaxyPluginOptions
ssgOptions?: ViteSSGOptions
}
}

View File

@ -6,15 +6,13 @@ 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 } from 'vite'
import type { UserConfig as ViteUserConfig } from 'vite'
import type { presetAttributify, presetIcons, presetTypography, presetUno } from 'unocss'
import type { ValaxyConfig } from '../types'
import { resolveConfig } from './config'
import type { ValaxySiteConfig } from '../types'
import { resolveSiteConfig } from './config'
import { resolveImportPath } from './utils'
import type { MarkdownOptions } from './markdown'
const debug = _debug('valaxy:options')
// for cli entry
export interface ValaxyEntryOptions {
/**
@ -24,7 +22,8 @@ export interface ValaxyEntryOptions {
userRoot?: string
}
export interface ValaxyPluginOptions {
export interface ValaxyConfig {
vite?: ViteUserConfig
vue?: Parameters<typeof Vue>[0]
components?: Parameters<typeof Components>[0]
unocss?: UnoCSSConfig
@ -48,11 +47,10 @@ export interface ValaxyPluginOptions {
excerpt?: string
path: string
}) => void
plugins?: ValaxyPluginOption[]
}
export interface ValaxyThemePlugin extends ValaxyPluginOptions {
vite?: Omit<UserConfig, 'valaxy'>
}
export type ValaxyPluginLike = ValaxyConfig | ValaxyConfig[] | false | null | undefined
export type ValaxyPluginOption = ValaxyPluginLike | string | [string, any]
export interface ResolvedValaxyOptions {
mode: 'dev' | 'build'
@ -82,7 +80,7 @@ export interface ResolvedValaxyOptions {
/**
* Valaxy Config
*/
config: ValaxyConfig
config: ValaxySiteConfig
/**
* config file path
*/
@ -91,9 +89,11 @@ export interface ResolvedValaxyOptions {
}
export interface ValaxyServerOptions {
onConfigReload?: (newConfig: ValaxyConfig, config: ValaxyConfig, force?: boolean) => void
onConfigReload?: (newConfig: ValaxySiteConfig, config: ValaxySiteConfig, force?: boolean) => void
}
const debug = _debug('valaxy:options')
export function isPath(name: string) {
return name.startsWith('/') || /^\.\.?[\/\\]/.test(name)
}
@ -120,7 +120,7 @@ export async function resolveOptions(options: ValaxyEntryOptions, mode: Resolved
const clientRoot = resolve(pkgRoot, 'client')
const userRoot = resolve(options.userRoot || process.cwd())
const { config: valaxyConfig, configFile, theme } = await resolveConfig(options)
const { config: siteConfig, configFile, theme } = await resolveSiteConfig(options)
const themeRoot = getThemeRoot(theme, userRoot)
const roots = uniq([clientRoot, themeRoot, userRoot])
@ -146,7 +146,7 @@ export async function resolveOptions(options: ValaxyEntryOptions, mode: Resolved
themeRoot,
roots,
theme,
config: valaxyConfig,
config: siteConfig,
configFile: configFile || '',
pages,
}

View File

@ -8,7 +8,7 @@ import { getIndexHtml } from '../common'
export function createConfigPlugin(options: ResolvedValaxyOptions): Plugin {
return {
name: 'valaxy:config',
name: 'valaxy:site',
config(config) {
const injection: InlineConfig = {

View File

@ -1,10 +1,10 @@
import fs from 'fs'
import { join, relative } from 'path'
import { basename, join, relative } from 'path'
import type { Plugin, ResolvedConfig } from 'vite'
// import consola from 'consola'
import { resolveConfig } from '../config'
import type { ResolvedValaxyOptions, ValaxyPluginOptions, ValaxyServerOptions } from '../options'
import { resolveSiteConfig } from '../config'
import type { ResolvedValaxyOptions, ValaxyConfig, ValaxyServerOptions } from '../options'
import { resolveImportPath, slash, toAtFS } from '../utils'
import { createMarkdownToVueRenderFn } from '../markdown/markdownToVue'
import type { PageDataPayload } from '../../types'
@ -63,26 +63,26 @@ function generateLocales(roots: string[]) {
return imports.join('\n')
}
export function createValaxyPlugin(options: ResolvedValaxyOptions, pluginOptions: ValaxyPluginOptions, serverOptions: ValaxyServerOptions = {}): Plugin {
export function createValaxyPlugin(options: ResolvedValaxyOptions, valaxyConfig: ValaxyConfig, serverOptions: ValaxyServerOptions = {}): Plugin {
const valaxyPrefix = '/@valaxy'
let valaxyConfig = options.config
let siteConfig = options.config
const roots = options.roots
let markdownToVue: Awaited<ReturnType<typeof createMarkdownToVueRenderFn>>
let hasDeadLinks = false
let config: ResolvedConfig
let viteConfig: ResolvedConfig
return {
name: 'valaxy:loader',
enforce: 'pre',
async configResolved(resolvedConfig) {
config = resolvedConfig
viteConfig = resolvedConfig
markdownToVue = await createMarkdownToVueRenderFn(
options.userRoot,
pluginOptions.markdown || {
valaxyConfig.markdown || {
toc: {
includeLevel: [1, 2, 3, 4],
listType: 'ol',
@ -90,8 +90,8 @@ export function createValaxyPlugin(options: ResolvedValaxyOptions, pluginOptions
katex: {},
},
options.pages,
config.define,
config.command === 'build',
viteConfig.define,
viteConfig.command === 'build',
options.config.lastUpdated,
)
},
@ -111,9 +111,9 @@ export function createValaxyPlugin(options: ResolvedValaxyOptions, pluginOptions
},
load(id) {
if (id === '/@valaxyjs/config')
if (id === '/@valaxyjs/site')
// stringify twice for \"
return `export default ${JSON.stringify(JSON.stringify(valaxyConfig))}`
return `export default ${JSON.stringify(JSON.stringify(siteConfig))}`
if (id === '/@valaxyjs/context') {
return `export default ${JSON.stringify(JSON.stringify({
@ -160,7 +160,7 @@ export function createValaxyPlugin(options: ResolvedValaxyOptions, pluginOptions
const { vueSrc, deadLinks, includes } = await markdownToVue(
code,
id,
config.publicDir,
viteConfig.publicDir,
)
if (deadLinks.length)
hasDeadLinks = true
@ -181,18 +181,22 @@ export function createValaxyPlugin(options: ResolvedValaxyOptions, pluginOptions
},
async handleHotUpdate(ctx) {
// handle valaxy.config.ts hmr
// handle site.config.ts hmr
const { file, server, read } = ctx
if (file === options.configFile) {
const { config } = await resolveConfig()
const fileName = basename(file)
const isSiteConfig = fileName.startsWith('site.config')
const isValaxyConfig = fileName.startsWith('valaxy.config')
serverOptions.onConfigReload?.(config, options.config)
if (isSiteConfig || isValaxyConfig) {
const { config } = await resolveSiteConfig()
serverOptions.onConfigReload?.(config, options.config, isValaxyConfig)
Object.assign(options.config, config)
valaxyConfig = config
siteConfig = config
const moduleIds = ['/@valaxyjs/config', '/@valaxyjs/context']
const moduleIds = ['/@valaxyjs/site', '/@valaxyjs/context']
const moduleEntries = [
...Array.from(moduleIds).map(id => server.moduleGraph.getModuleById(id)),
].filter(<T>(item: T): item is NonNullable<T> => !!item)

View File

@ -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, ValaxyPluginOptions, ValaxyServerOptions } from '../options'
import type { ResolvedValaxyOptions, ValaxyConfig, ValaxyServerOptions } from '../options'
import { setupMarkdownPlugins } from '../markdown'
// import { createMarkdownPlugin, excerpt_separator } from './markdown'
// import { formatMdDate } from '../utils/date'
@ -23,20 +23,20 @@ import { createValaxyPlugin } from '.'
export async function ViteValaxyPlugins(
options: ResolvedValaxyOptions,
pluginOptions: ValaxyPluginOptions = {},
valaxyConfig: ValaxyConfig = {},
serverOptions: ValaxyServerOptions = {},
): Promise<(PluginOption | PluginOption[])[] | undefined> {
const { roots } = options
// const MarkdownPlugin = createMarkdownPlugin(options)
const UnocssPlugin = await createUnocssPlugin(options, pluginOptions)
const UnocssPlugin = await createUnocssPlugin(options, valaxyConfig)
const ValaxyPlugin = createValaxyPlugin(options, pluginOptions, serverOptions)
const ValaxyPlugin = createValaxyPlugin(options, valaxyConfig, serverOptions)
// for render markdown excerpt
const mdIt = new MarkdownIt({ html: true })
await setupMarkdownPlugins(mdIt, pluginOptions.markdown, true)
await setupMarkdownPlugins(mdIt, valaxyConfig.markdown, true)
const customElements = new Set([
// katex
@ -81,9 +81,9 @@ export async function ViteValaxyPlugins(
return customElements.has(tag)
},
},
...pluginOptions.vue?.template,
...valaxyConfig.vue?.template,
},
...pluginOptions.vue,
...valaxyConfig.vue,
}),
createConfigPlugin(options),
@ -95,7 +95,7 @@ export async function ViteValaxyPlugins(
extensions: ['vue', 'md'],
dirs: roots.map(root => `${root}/pages`),
...pluginOptions.pages,
...valaxyConfig.pages,
/**
* we need get frontmatter before route, so write it in Pages.extendRoute
@ -167,7 +167,7 @@ export async function ViteValaxyPlugins(
if (route.meta.frontmatter.updated)
route.meta.frontmatter.updated = route.meta.frontmatter.date
pluginOptions.extendMd?.({
valaxyConfig.extendMd?.({
route,
data,
excerpt,
@ -175,7 +175,7 @@ export async function ViteValaxyPlugins(
})
}
pluginOptions.pages?.extendRoute?.(route, parent)
valaxyConfig.pages?.extendRoute?.(route, parent)
return route
},
@ -200,7 +200,7 @@ export async function ViteValaxyPlugins(
dirs: roots.map(root => `${root}/components`).concat(roots.map(root => `${root}/layouts`)).concat(['src/components', 'components']),
dts: `${options.userRoot}/components.d.ts`,
...pluginOptions.components,
...valaxyConfig.components,
}),
// https://github.com/antfu/unocss

View File

@ -13,11 +13,11 @@ import {
transformerDirectives,
transformerVariantGroup,
} from 'unocss'
import type { ValaxyConfig } from 'valaxy'
import type { ResolvedValaxyOptions, ValaxyPluginOptions } from '../options'
import type { ValaxySiteConfig } from 'valaxy'
import type { ResolvedValaxyOptions, ValaxyConfig } from '../options'
import { loadSetups } from './setupNode'
export const createSafelist = async (config: ValaxyConfig, pluginOptions: ValaxyPluginOptions = {}) => {
export const createSafelist = async (config: ValaxySiteConfig, pluginOptions: ValaxyConfig = {}) => {
const { generateSafelist } = await import(`valaxy-theme-${config.theme}`)
const safeIcons: string[] = [
@ -49,7 +49,7 @@ export const createSafelist = async (config: ValaxyConfig, pluginOptions: Valaxy
return safelist
}
export const createUnocssConfig = async (options: ResolvedValaxyOptions, pluginOptions: ValaxyPluginOptions) => {
export const createUnocssConfig = async (options: ResolvedValaxyOptions, pluginOptions: ValaxyConfig) => {
const unocssConfig: VitePluginConfig = {
shortcuts: [
['btn', 'px-4 py-1 rounded inline-block bg-sky-600 text-white cursor-pointer hover:bg-sky-700 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
@ -99,7 +99,7 @@ export const createUnocssConfig = async (options: ResolvedValaxyOptions, pluginO
return unocssConfig
}
export const createUnocssPlugin = async (options: ResolvedValaxyOptions, pluginOptions: ValaxyPluginOptions) => {
export const createUnocssPlugin = async (options: ResolvedValaxyOptions, pluginOptions: ValaxyConfig) => {
const { unocss: unoOptions } = pluginOptions
const defaultConfig = await createUnocssConfig(options, pluginOptions)

View File

@ -13,13 +13,13 @@ export async function createServer(
// default editor vscode
process.env.EDITOR = process.env.EDITOR || 'code'
const valaxyConfig = await resolveValaxyConfig(options, viteConfig)
const config = await resolveValaxyConfig(options, viteConfig)
const server = await createViteServer(
mergeViteConfig(
viteConfig,
config.vite!,
{
plugins: await ViteValaxyPlugins(options, valaxyConfig, serverOptions),
plugins: await ViteValaxyPlugins(options, config, serverOptions),
},
),
)

View File

@ -2,14 +2,13 @@ import * as readline from 'readline'
import path from 'path'
import os from 'os'
import { blue, bold, cyan, dim, gray, green, underline, yellow } from 'kolorist'
import { blue, bold, cyan, dim, gray, green, underline } from 'kolorist'
import consola from 'consola'
import type { InlineConfig, ViteDevServer } from 'vite'
import { mergeConfig } from 'vite'
import { createServer } from '../server'
import type { ResolvedValaxyOptions } from '../options'
import { version } from '../../package.json'
import { createSafelist } from '../plugins/unocss'
import { mergeViteConfigs } from '../common'
let server: ViteDevServer | undefined
@ -49,31 +48,20 @@ export async function initServer(options: ResolvedValaxyOptions, viteConfig: Inl
)
try {
let safelist = (await createSafelist(options.config, viteConfigs.valaxy || {})).concat([])
let oldSafelist = safelist
server = await createServer(options, viteConfigs, {
async onConfigReload(newConfig, config, force = false) {
async onConfigReload(newSiteConfig, siteConfig, force = false) {
consola.log('force: ', force)
if (force)
initServer(options, viteConfig)
let reload = false
let iconChanged = false
safelist = (await createSafelist(newConfig, viteConfigs.valaxy || {})).concat([])
iconChanged = safelist.some(name => !oldSafelist.includes(name))
oldSafelist = safelist
if (newConfig.theme !== config.theme) {
if (newSiteConfig.theme !== siteConfig.theme)
reload = true
}
else if (iconChanged) {
consola.info('Find new icon, reload server...')
consola.info(`If you do not want to reload, write icon name in ${yellow('vite.config.ts')} ${green('valaxy.unocss.safelist')}.`)
console.log()
reload = true
}
// consola.info('Find new icon, reload server...')
// consola.info(`If you do not want to reload, write icon name in ${yellow('vite.config.ts')} ${green('valaxy.unocss.safelist')}.`)
// console.log()
// reload = true
if (reload)
initServer(options, viteConfig)

View File

@ -1,48 +1,15 @@
import type { ResolvedValaxyOptions } from 'valaxy'
import type { ValaxyPluginOptions } from 'valaxy/node'
import type { InlineConfig } from 'vite'
import { mergeConfig as mergeViteConfig } from 'vite'
import type { ResolvedValaxyOptions } from '../options'
import { mergeValaxyConfigs } from '../common'
export async function resolveValaxyConfig(options: ResolvedValaxyOptions, viteConfig: InlineConfig = {}) {
const { default: config } = (await import(`valaxy-theme-${options.theme}`))
let resolved = typeof config === 'function' ? (await config?.(options)) : config
const resolved = await mergeValaxyConfigs(options)
if (!resolved)
return {}
if (!resolved.vite)
resolved.vite = {}
// if theme exists vite config
// inherited configuration
if (resolved.vite)
Object.assign(viteConfig, mergeViteConfig(viteConfig, resolved.vite))
resolved.vite = mergeViteConfig(resolved.vite, viteConfig)
if (viteConfig.valaxy)
resolved = mergeConfig(resolved, viteConfig.valaxy)
return resolved as ValaxyPluginOptions
}
export function mergeConfig(merged: any, b: any) {
for (const key in b) {
const value = b[key]
if (value == null)
continue
const existing = merged[key]
if (Array.isArray(existing) && Array.isArray(value)) {
merged[key] = [...existing, ...value]
continue
}
if (typeof existing === 'object' && typeof value === 'object') {
merged[key] = mergeConfig(existing, value)
continue
}
if (typeof existing === 'function' && typeof value === 'function') {
merged[key] = function (...args: any[]) {
existing.call(merged[key], ...args)
value.call(merged[key], ...args)
}
continue
}
merged[key] = value
}
return merged
return resolved
}

View File

@ -3,11 +3,27 @@ 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
@ -59,3 +75,4 @@ export function resolveImportPath(importName: string, ensure = false) {
consola.error(`Failed to resolve package ${importName}`)
return undefined
}

View File

@ -23,8 +23,7 @@ declare module '*.vue' {
}
// vite hmr data
declare module '/@valaxyjs/config' {
// import type { ValaxyConfig } from 'valaxy'
declare module '/@valaxyjs/site' {
const config: string
export default config
}

View File

@ -16,9 +16,8 @@ export default defineConfig((options) => {
format: ['cjs', 'esm'],
minify: !options.watch,
external: [
'/@valaxyjs/config',
'/@valaxyjs/site',
'/@valaxyjs/context',
'@waline/client',
],
}

View File

@ -26,7 +26,7 @@ export interface AlgoliaSearchOptions {
}
// packages/valaxy/node/config.ts
export interface ValaxyConfig<T = ValaxyThemeConfig> {
export interface ValaxySiteConfig<T = ValaxyThemeConfig> {
/**
* enable auto (light/dark mode)
* @default 'auto'
@ -226,5 +226,5 @@ export type PartialDeep<T> = {
* Valaxy User Config
* @description Valaxy
*/
export type UserConfig<ThemeConfig = ValaxyThemeConfig> = PartialDeep<ValaxyConfig<ThemeConfig>>
export type UserConfig<ThemeConfig = ValaxyThemeConfig> = PartialDeep<ValaxySiteConfig<ThemeConfig>>