mirror of https://github.com/YunYouJun/valaxy
refactor: migrate vite-plugin-pages to unplugin-vue-router
This commit is contained in:
parent
f7324b4157
commit
9a00a55dc8
|
@ -49,7 +49,7 @@ For a example, you can see [demo/yun](./demo/yun/) folder.
|
|||
- 🔥 Hot Reload with Config & Markdown
|
||||
- 🔧 Type Tooltip for all config by `valaxy.config.ts`
|
||||
- 🗒 Extended Markdown Frontmatter
|
||||
- 🗂 File based routing via [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages)
|
||||
- 🗂 File based routing via [unplugin-vue-router](https://github.com/posva/unplugin-vue-router)
|
||||
- 📦 Components auto importing via [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components)
|
||||
- 🖨 Static-site generation (SSG) via [vite-ssg](https://github.com/antfu/vite-ssg) (SPA is OK!)
|
||||
- 🕸 RSS & Sitemap
|
||||
|
|
|
@ -49,7 +49,7 @@ pnpm create valaxy
|
|||
- 🔥 配置 & Markdown 文件热更新
|
||||
- 🔧 `valaxy.config.ts` 的所有配置项皆有类型提示
|
||||
- 🗒 扩展 Markdown Frontmatter
|
||||
- 🗂 实现基于文件路由 by [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages)
|
||||
- 🗂 实现基于文件路由 by [unplugin-vue-router](https://github.com/posva/unplugin-vue-router)
|
||||
- 📦 自动引入组件 by [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components)
|
||||
- 🖨 静态站点生成 (SSG) by [vite-ssg](https://github.com/antfu/vite-ssg) (支持单页面应用!)
|
||||
- 🕸 RSS & Sitemap
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# _Drafts
|
||||
|
||||
Temp, this folder contains all the drafts of the pages.
|
|
@ -2,13 +2,11 @@ import { defineConfig } from 'vite'
|
|||
|
||||
// vite plugins
|
||||
// import { VitePWA } from 'vite-plugin-pwa'
|
||||
// import VueDevTools from 'vite-plugin-vue-devtools'
|
||||
|
||||
// import Inspect from 'vite-plugin-inspect'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
// not works, to be fixed
|
||||
// VueDevTools(),
|
||||
// VitePWA(),
|
||||
// https://github.com/antfu/vite-plugin-inspect
|
||||
// Visit http://localhost:3333/__inspect/ to see the inspector
|
||||
|
|
|
@ -225,12 +225,12 @@ to build their own.
|
|||
## 基于文件的自动路由 {lang="zh-CN"}
|
||||
|
||||
::: zh-CN
|
||||
路由会自动遵循相同目录结构从当前路径中的 Vue 文件生成。更多请参考 [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages)。
|
||||
路由会自动遵循相同目录结构从当前路径中的 Vue/Markdown 文件生成。更多请参考 [unplugin-vue-router](https://github.com/posva/unplugin-vue-router)。
|
||||
:::
|
||||
|
||||
::: en
|
||||
Routes will be auto-generated for Vue files in this dir with the same file structure.
|
||||
Check out [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) for more details.
|
||||
Routes will be auto-generated for Vue/Markdown files in this dir with the same file structure.
|
||||
Check out [`unplugin-vue-router`](https://github.com/posva/unplugin-vue-router) for more details.
|
||||
:::
|
||||
|
||||
## 构建 {lang="zh-CN"}
|
||||
|
|
|
@ -103,15 +103,21 @@ pnpm create valaxy
|
|||
|
||||
我们提供了一个扩展函数,以供你快速扩展页面信息。
|
||||
|
||||
你也可以直接扩展 [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages) 插件中的 `extendRoute`。
|
||||
<!-- TODO -->
|
||||
|
||||
你也可以直接扩展 [unplugin-vue-router](https://github.com/posva/unplugin-vue-router) 插件中的 `extendRoute`。
|
||||
|
||||
> <https://github.com/posva/unplugin-vue-router/issues/43#issuecomment-1433140464>
|
||||
|
||||
```ts
|
||||
// valaxy.config.ts
|
||||
import { defineTheme } from 'valaxy'
|
||||
|
||||
export default defineTheme({
|
||||
pages: {
|
||||
extendRoute(route, parent) {
|
||||
vueRouter: {
|
||||
extendRoutes(route) {
|
||||
// want to get component absolute paths?
|
||||
// const path = route.components.get('default')
|
||||
console.log(route)
|
||||
},
|
||||
},
|
||||
|
@ -122,6 +128,8 @@ export default defineTheme({
|
|||
```
|
||||
|
||||
```ts
|
||||
import type { EditableTreeNode } from 'unplugin-vue-router'
|
||||
|
||||
// provided by valaxy, just as a tip
|
||||
export interface ValaxyConfig {
|
||||
vue?: Parameters<typeof Vue>[0]
|
||||
|
@ -129,11 +137,7 @@ export interface ValaxyConfig {
|
|||
unocss?: UnoCSSConfig
|
||||
pages?: Parameters<typeof Pages>[0]
|
||||
extendMd?: (ctx: {
|
||||
route: {
|
||||
meta: { frontmatter?: Record<string, any>, layout?: string }
|
||||
path: string
|
||||
component: string
|
||||
}
|
||||
route: EditableTreeNode
|
||||
data: Readonly<Record<string, any>>
|
||||
excerpt?: string
|
||||
path: string
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
"resolveJsonModule": true,
|
||||
"types": [
|
||||
"vite/client",
|
||||
"vite-plugin-pages/client",
|
||||
"vite-plugin-vue-layouts/client"
|
||||
],
|
||||
"allowJs": true,
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
defineProps<{ page: string }>()
|
||||
import { useRoute } from 'vue-router'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const route = useRoute()
|
||||
const pageIndex = computed(() => Number.parseInt((route.params as { page: string }).page))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<YunPostList :cur-page="parseInt(page)" />
|
||||
<YunPostList :cur-page="pageIndex" />
|
||||
</template>
|
||||
|
||||
<route lang="yaml">
|
||||
meta:
|
||||
layout: home
|
||||
</route>
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
"resolveJsonModule": true,
|
||||
"types": [
|
||||
"vite/client",
|
||||
"vite-plugin-pages/client",
|
||||
"vite-plugin-vue-layouts/client"
|
||||
"vite-plugin-vue-layouts/client",
|
||||
"valaxy/client"
|
||||
],
|
||||
"allowJs": true,
|
||||
"strict": true,
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
# ignore it
|
||||
components.d.ts
|
||||
index.html
|
||||
|
||||
# unplugin-vue-components
|
||||
components.d.ts
|
||||
|
||||
# unplugin-vue-router
|
||||
typed-router.d.ts
|
||||
|
|
|
@ -19,7 +19,7 @@ export function usePostTitle(post: ComputedRef<Post>) {
|
|||
*/
|
||||
export function usePageList() {
|
||||
return computed<Post[]>(() => {
|
||||
const excludePages = ['/:..all', '/:all(.*)*', '/']
|
||||
const excludePages = ['/:..all', '/:all(.*)*', '/', '/:path(.*)']
|
||||
const router = useRouter()
|
||||
const routes = router.getRoutes()
|
||||
.filter(i => i.name)
|
||||
|
@ -27,7 +27,7 @@ export function usePageList() {
|
|||
.filter(i => i.meta!.frontmatter)
|
||||
.filter(i => i.path && !excludePages.includes(i.path))
|
||||
.map((i) => {
|
||||
return Object.assign({ path: i.path, excerpt: i.meta!.excerpt }, i.meta!.frontmatter) as Post
|
||||
return Object.assign({ path: i.path, excerpt: i.meta!.excerpt }, i.meta!.frontmatter || {}) as Post
|
||||
})
|
||||
return routes
|
||||
})
|
||||
|
|
|
@ -4,7 +4,7 @@ Vue components in this dir are used as layouts.
|
|||
|
||||
By default, `default.vue` will be used unless an alternative is specified in the route meta.
|
||||
|
||||
With [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) and [`vite-plugin-vue-layouts`](https://github.com/JohnCampionJr/vite-plugin-vue-layouts), you can specify the layout in the page's SFCs like this:
|
||||
With [unplugin-vue-router](https://github.com/posva/unplugin-vue-router) and [`vite-plugin-vue-layouts`](https://github.com/JohnCampionJr/vite-plugin-vue-layouts), you can specify the layout in the page's SFCs like this:
|
||||
|
||||
```html
|
||||
<route lang="yaml">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import type { ViteSSGContext } from 'vite-ssg'
|
||||
import { ViteSSG } from 'vite-ssg'
|
||||
import generatedRoutes from 'virtual:generated-pages'
|
||||
|
||||
import { routes } from 'vue-router/auto/routes'
|
||||
import { setupLayouts } from 'virtual:generated-layouts'
|
||||
|
||||
import { initValaxyConfig, valaxyConfigSymbol } from 'valaxy'
|
||||
|
@ -20,12 +21,6 @@ import 'uno.css'
|
|||
|
||||
import setupMain from './setup/main'
|
||||
|
||||
const routes = setupLayouts(import.meta.env.DEV
|
||||
? generatedRoutes
|
||||
: generatedRoutes.filter(i =>
|
||||
i.meta && i.meta.frontmatter && !i.meta.frontmatter.draft,
|
||||
))
|
||||
|
||||
/**
|
||||
* register global components
|
||||
* @param ctx
|
||||
|
@ -35,12 +30,17 @@ export function registerComponents(ctx: ViteSSGContext) {
|
|||
}
|
||||
|
||||
// not filter hide for ssg
|
||||
const routesWithLayout = setupLayouts(import.meta.env.DEV
|
||||
? routes
|
||||
: routes.filter(i =>
|
||||
i.meta && i.meta.frontmatter && !i.meta.frontmatter.draft,
|
||||
))
|
||||
|
||||
// https://github.com/antfu/vite-ssg
|
||||
export const createApp = ViteSSG(
|
||||
App,
|
||||
{
|
||||
routes,
|
||||
routes: routesWithLayout,
|
||||
base: import.meta.env.BASE_URL,
|
||||
scrollBehavior(to, from) {
|
||||
if (to.path !== from.path)
|
||||
|
|
|
@ -63,7 +63,6 @@ $light: map.merge(
|
|||
"c-primary-rgb": #{color.red($c-primary), color.green($c-primary), color.blue($c-primary)},
|
||||
|
||||
"c-link": get-css-var("c-primary-dark"),
|
||||
"c-divider": rgba(60, 60, 60, 0.2),
|
||||
),
|
||||
$light
|
||||
);
|
||||
|
|
|
@ -376,6 +376,7 @@ function injectPageDataCode(
|
|||
|
||||
const isUsingTS = tags.findIndex(tag => scriptLangTsRE.test(tag)) > -1
|
||||
|
||||
// merge lastUpdated
|
||||
const exportScript = `
|
||||
import { provide } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
|
|
@ -7,6 +7,7 @@ import Vue from '@vitejs/plugin-vue'
|
|||
import Layouts from 'vite-plugin-vue-layouts'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import VueI18n from '@intlify/unplugin-vue-i18n/vite'
|
||||
import VueDevTools from 'vite-plugin-vue-devtools'
|
||||
|
||||
import UnheadVite from '@unhead/addons/vite'
|
||||
|
||||
|
@ -17,7 +18,7 @@ import { createUnocssPlugin } from './unocss'
|
|||
import { createConfigPlugin } from './extendConfig'
|
||||
import { createClientSetupPlugin } from './setupClient'
|
||||
import { createFixPlugins } from './patchTransform'
|
||||
import { createPagesPlugin } from './pages'
|
||||
import { createRouterPlugin } from './vueRouter'
|
||||
import { createValaxyPlugin } from './valaxy'
|
||||
|
||||
// for render markdown excerpt
|
||||
|
@ -86,12 +87,13 @@ export async function ViteValaxyPlugins(
|
|||
createClientSetupPlugin(options),
|
||||
createValaxyPlugin(options, serverOptions),
|
||||
|
||||
// https://github.com/hannoeru/vite-plugin-pages
|
||||
createPagesPlugin(options),
|
||||
// https://github.com/posva/unplugin-vue-router
|
||||
createRouterPlugin(options),
|
||||
|
||||
// https://github.com/JohnCampionJr/vite-plugin-vue-layouts
|
||||
Layouts({
|
||||
layoutsDirs: roots.map(root => `${root}/layouts`),
|
||||
pagesDirs: roots.map(root => `${root}/pages`),
|
||||
}),
|
||||
|
||||
// https://github.com/antfu/unplugin-vue-components
|
||||
|
@ -130,5 +132,7 @@ export async function ViteValaxyPlugins(
|
|||
|
||||
splitVendorChunkPlugin(),
|
||||
createFixPlugins(options),
|
||||
|
||||
VueDevTools(),
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import Pages from 'vite-plugin-pages'
|
||||
import VueRouter from 'unplugin-vue-router/vite'
|
||||
import fs from 'fs-extra'
|
||||
import matter from 'gray-matter'
|
||||
import { isDate } from '@antfu/utils'
|
||||
import { convert } from 'html-to-text'
|
||||
import type { ExcerptType, Page } from 'valaxy/types'
|
||||
import type { ResolvedValaxyOptions } from '../options'
|
||||
import type { ValaxyExtendConfig } from '../types'
|
||||
import { EXCERPT_SEPARATOR } from '../constants'
|
||||
|
||||
import { mdIt } from './preset'
|
||||
|
@ -31,55 +30,51 @@ function getExcerptByType(excerpt = '', type: ExcerptType = 'html') {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/hannoeru/vite-plugin-pages
|
||||
* @see https://github.com/posva/unplugin-vue-router
|
||||
* @param options
|
||||
*/
|
||||
export function createPagesPlugin(options: ResolvedValaxyOptions) {
|
||||
export function createRouterPlugin(options: ResolvedValaxyOptions) {
|
||||
const { roots, config: valaxyConfig } = options
|
||||
|
||||
return Pages({
|
||||
extensions: ['vue', 'md'],
|
||||
dirs: roots.map(root => `${root}/pages`),
|
||||
return VueRouter({
|
||||
extensions: ['.vue', '.md'],
|
||||
routesFolder: roots.map(root => `${root}/pages`),
|
||||
dts: `${options.clientRoot}/typed-router.d.ts`,
|
||||
|
||||
...valaxyConfig.pages,
|
||||
...valaxyConfig.vueRouter,
|
||||
|
||||
/**
|
||||
* we need get frontmatter before route, so write it in Pages.extendRoute
|
||||
* @experimental See https://github.com/posva/unplugin-vue-router/issues/43
|
||||
* we need get frontmatter before route, so write it in extendRoute
|
||||
*/
|
||||
async extendRoute(
|
||||
route: Parameters<Required<ValaxyExtendConfig>['extendMd']>[0]['route'],
|
||||
parent,
|
||||
) {
|
||||
let path: string = route.component
|
||||
|
||||
async extendRoute(route) {
|
||||
const defaultFrontmatter = JSON.parse(JSON.stringify(valaxyConfig.siteConfig.frontmatter)) || {}
|
||||
if (!route.meta) {
|
||||
route.meta = {
|
||||
frontmatter: defaultFrontmatter,
|
||||
}
|
||||
}
|
||||
else if (!route.meta.frontmatter) {
|
||||
// set default frontmatter
|
||||
route.meta.frontmatter = defaultFrontmatter
|
||||
}
|
||||
|
||||
// encode for chinese filename dev and build same
|
||||
route.path = encodeURI(route.path)
|
||||
|
||||
// add default layout for home, can be overrode
|
||||
if (route.path === '/')
|
||||
route.meta.layout = 'home'
|
||||
|
||||
// find page path
|
||||
roots.forEach((root) => {
|
||||
const pagePath = root + route.component
|
||||
if (fs.existsSync(pagePath))
|
||||
path = pagePath
|
||||
// merge deeply
|
||||
route.addToMeta({
|
||||
frontmatter: defaultFrontmatter,
|
||||
})
|
||||
|
||||
// encode for chinese filename dev and build same
|
||||
// const encodedPath = encodeURI(route.path)
|
||||
// if (encodedPath !== route.path)
|
||||
// route.path = encodedPath
|
||||
|
||||
// add default layout for home, can be overrode
|
||||
if (route.fullPath === '/' || route.fullPath === '/page') {
|
||||
route.addToMeta({
|
||||
layout: 'home',
|
||||
})
|
||||
}
|
||||
|
||||
// find page path
|
||||
const path = route.components.get('default') || ''
|
||||
|
||||
// page is post
|
||||
if (route.path.startsWith('/posts/'))
|
||||
route.meta.layout = 'post'
|
||||
if (route.fullPath.startsWith('/posts/')) {
|
||||
route.addToMeta({
|
||||
layout: 'post',
|
||||
})
|
||||
}
|
||||
|
||||
if (path.endsWith('.md')) {
|
||||
const md = fs.readFileSync(path, 'utf-8')
|
||||
|
@ -89,7 +84,6 @@ export function createPagesPlugin(options: ResolvedValaxyOptions) {
|
|||
const mdFm = data as Page
|
||||
|
||||
// todo, optimize it to cache or on demand
|
||||
// https://github.com/hannoeru/vite-plugin-pages/issues/257
|
||||
const lastUpdated = options.config.siteConfig.lastUpdated
|
||||
|
||||
// do not export password
|
||||
|
@ -120,8 +114,11 @@ export function createPagesPlugin(options: ResolvedValaxyOptions) {
|
|||
})
|
||||
|
||||
// set layout
|
||||
if (data.layout)
|
||||
route.meta.layout = data.layout
|
||||
if (data.layout) {
|
||||
route.addToMeta({
|
||||
layout: data.layout,
|
||||
})
|
||||
}
|
||||
|
||||
// set default updated
|
||||
if (!route.meta.frontmatter?.updated)
|
||||
|
@ -152,9 +149,7 @@ export function createPagesPlugin(options: ResolvedValaxyOptions) {
|
|||
valaxyConfig.extendMd?.(ctx)
|
||||
}
|
||||
|
||||
valaxyConfig.pages?.extendRoute?.(route, parent)
|
||||
|
||||
return route
|
||||
return valaxyConfig.vueRouter?.extendRoute?.(route)
|
||||
},
|
||||
})
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
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 VueRouter from 'unplugin-vue-router/vite'
|
||||
import type { EditableTreeNode } from 'unplugin-vue-router'
|
||||
import type { UserConfig as ViteUserConfig } from 'vite'
|
||||
import type { presetAttributify, presetIcons, presetTypography, presetUno } from 'unocss'
|
||||
import type { Hookable } from 'hookable'
|
||||
|
@ -71,17 +72,13 @@ export interface ValaxyExtendConfig {
|
|||
icons?: Parameters<typeof presetIcons>[0]
|
||||
typography?: Parameters<typeof presetTypography>[0]
|
||||
}
|
||||
pages?: Parameters<typeof Pages>[0]
|
||||
vueRouter?: Parameters<typeof VueRouter>[0]
|
||||
/**
|
||||
* for markdown
|
||||
*/
|
||||
markdown?: MarkdownOptions
|
||||
extendMd?: (ctx: {
|
||||
route: {
|
||||
meta: { frontmatter: Record<string, any>, layout?: string } & object
|
||||
path: string
|
||||
component: string
|
||||
}
|
||||
route: EditableTreeNode
|
||||
data: Readonly<Record<string, any>>
|
||||
content: string
|
||||
excerpt?: string
|
||||
|
|
|
@ -72,8 +72,8 @@
|
|||
"@unhead/schema-org": "^1.8.9",
|
||||
"@unhead/vue": "^1.8.9",
|
||||
"@vitejs/plugin-vue": "^5.0.3",
|
||||
"@vueuse/core": "^10.7.1",
|
||||
"@vueuse/integrations": "^10.7.1",
|
||||
"@vueuse/core": "^10.7.2",
|
||||
"@vueuse/integrations": "^10.7.2",
|
||||
"body-scroll-lock": "4.0.0-beta.0",
|
||||
"consola": "^3.2.3",
|
||||
"critters": "^0.0.20",
|
||||
|
@ -114,9 +114,10 @@
|
|||
"unconfig": "^0.3.11",
|
||||
"unocss": "^0.58.3",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"unplugin-vue-router": "^0.7.0",
|
||||
"vanilla-lazyload": "^17.8.5",
|
||||
"vite": "^5.0.11",
|
||||
"vite-plugin-pages": "^0.32.0",
|
||||
"vite-plugin-vue-devtools": "^7.0.10",
|
||||
"vite-plugin-vue-layouts": "0.11.0",
|
||||
"vite-ssg": "0.23.6",
|
||||
"vite-ssg-sitemap": "0.6.1",
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import 'vue-router'
|
||||
|
||||
import './client/typed-router'
|
||||
|
||||
import type { Post } from './types'
|
||||
import type { Header } from './node/markdown'
|
||||
|
||||
|
|
590
pnpm-lock.yaml
590
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -19,7 +19,6 @@
|
|||
"types": [
|
||||
"vitest",
|
||||
"vite/client",
|
||||
"vite-plugin-pages/client",
|
||||
"vite-plugin-vue-layouts/client",
|
||||
"@intlify/unplugin-vue-i18n/messages"
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue