@movk/nuxt-docs 1.3.7 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
- 🎨 **采用 Nuxt UI** - 集成全面的 UI 组件库,开箱即用
|
|
20
20
|
- 📝 **MDC 语法增强** - 支持 Markdown 与 Vue 组件的无缝集成,实现动态内容
|
|
21
21
|
- 🧩 **组件文档自动生成** - 自动生成 Props、Slots、Emits 文档及交互式示例
|
|
22
|
+
- 📦 **Git 提交历史集成** - 通过 CommitChangelog 组件自动展示文件的提交历史记录
|
|
22
23
|
- 📚 **智能侧边栏导航** - 根据内容结构自动生成导航
|
|
23
24
|
- 🔍 **全文搜索** - 内置强大的全文搜索功能
|
|
24
25
|
- 🌙 **暗黑模式** - 支持亮色/暗色主题切换
|
|
@@ -31,14 +32,30 @@
|
|
|
31
32
|
|
|
32
33
|
### 使用模板创建项目
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
根据您的需求选择合适的模板:
|
|
36
|
+
|
|
37
|
+
#### 📚 完整文档站点(推荐)
|
|
38
|
+
|
|
39
|
+
适合构建完整的文档网站,包含 ESLint、TypeScript 检查等开发工具。
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# 使用完整模板创建新项目
|
|
36
43
|
npx nuxi init -t gh:mhaibaraai/movk-nuxt-docs/templates/default my-docs
|
|
37
|
-
# 进入项目目录
|
|
38
44
|
cd my-docs
|
|
39
|
-
# 启动开发服务器
|
|
40
45
|
pnpm dev
|
|
41
46
|
```
|
|
47
|
+
|
|
48
|
+
#### 📦 模块文档站点(精简)
|
|
49
|
+
|
|
50
|
+
适合为 npm 包或库快速创建文档,内置 Release 页面展示版本发布历史,无额外开发工具。
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# 使用模块模板创建新项目
|
|
54
|
+
npx nuxi init -t gh:mhaibaraai/movk-nuxt-docs/templates/module my-module-docs
|
|
55
|
+
cd my-module-docs
|
|
56
|
+
pnpm dev
|
|
57
|
+
```
|
|
58
|
+
|
|
42
59
|
访问 `http://localhost:3000` 查看你的文档网站。
|
|
43
60
|
|
|
44
61
|
### 作为 Layer 使用
|
|
@@ -73,9 +90,9 @@ export default defineNuxtConfig({
|
|
|
73
90
|
|
|
74
91
|
## 📁 项目结构
|
|
75
92
|
|
|
76
|
-
###
|
|
93
|
+
### 模板项目结构
|
|
77
94
|
|
|
78
|
-
|
|
95
|
+
使用模板创建的项目结构(以 `default` 模板为例):
|
|
79
96
|
|
|
80
97
|
```bash
|
|
81
98
|
my-docs/
|
|
@@ -86,22 +103,27 @@ my-docs/
|
|
|
86
103
|
│ ├── index.md # 首页
|
|
87
104
|
│ └── docs/ # 文档页面
|
|
88
105
|
├── public/ # 静态资源
|
|
89
|
-
├── scripts/ # 脚本
|
|
90
106
|
├── nuxt.config.ts # Nuxt 配置
|
|
107
|
+
├── app.config.ts # 应用配置
|
|
108
|
+
├── content.config.ts # 内容配置
|
|
91
109
|
├── tsconfig.json # TypeScript 配置
|
|
92
110
|
├── package.json # 依赖与脚本
|
|
93
|
-
├── pnpm-workspace.yaml # pnpm 工作区配置
|
|
94
111
|
└── README.md # 项目说明
|
|
95
112
|
```
|
|
96
113
|
|
|
97
114
|
### Monorepo 结构
|
|
98
115
|
|
|
99
|
-
|
|
116
|
+
本仓库采用 monorepo 结构:
|
|
100
117
|
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
|
|
104
|
-
|
|
118
|
+
```bash
|
|
119
|
+
movk-nuxt-docs/
|
|
120
|
+
├── docs/ # 官方文档站点
|
|
121
|
+
├── layer/ # @movk/nuxt-docs layer 包
|
|
122
|
+
├── templates/
|
|
123
|
+
│ ├── default/ # 完整文档站点模板
|
|
124
|
+
│ └── module/ # 模块文档站点模板(精简)
|
|
125
|
+
└── scripts/ # 构建脚本
|
|
126
|
+
```
|
|
105
127
|
|
|
106
128
|
## 📝 内容编写
|
|
107
129
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { camelCase, upperFirst } from '@movk/core'
|
|
3
|
+
|
|
4
|
+
interface Commit {
|
|
5
|
+
sha: string
|
|
6
|
+
message: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const props = defineProps<{
|
|
10
|
+
/**
|
|
11
|
+
* The path to the file in the repository.
|
|
12
|
+
* @defaultValue 'src'
|
|
13
|
+
*/
|
|
14
|
+
commitPath?: string
|
|
15
|
+
/**
|
|
16
|
+
* The prefix for the file path.
|
|
17
|
+
*/
|
|
18
|
+
prefix?: string
|
|
19
|
+
/**
|
|
20
|
+
* The file extension.
|
|
21
|
+
* @defaultValue 'vue'
|
|
22
|
+
*/
|
|
23
|
+
suffix?: string
|
|
24
|
+
/**
|
|
25
|
+
* The name of the component or file to get the changelog for.
|
|
26
|
+
*/
|
|
27
|
+
name?: string
|
|
28
|
+
}>()
|
|
29
|
+
|
|
30
|
+
const SHA_SHORT_LENGTH = 5
|
|
31
|
+
|
|
32
|
+
const { github } = useAppConfig()
|
|
33
|
+
const route = useRoute()
|
|
34
|
+
|
|
35
|
+
// 计算文件路径相关的值
|
|
36
|
+
const routeName = computed(() => route.path.split('/').pop() ?? '')
|
|
37
|
+
const githubUrl = computed(() => (github && typeof github === 'object' ? github.url : ''))
|
|
38
|
+
|
|
39
|
+
const filePath = computed(() => {
|
|
40
|
+
const basePath = props.commitPath ?? (github && typeof github === 'object' ? github.commitPath : 'src')
|
|
41
|
+
const filePrefix = props.prefix ? `${props.prefix}/` : ''
|
|
42
|
+
const fileExtension = props.suffix ?? (github && typeof github === 'object' ? github.suffix : 'vue')
|
|
43
|
+
const fileName = props.name ?? routeName.value
|
|
44
|
+
|
|
45
|
+
const camelName = fileExtension === 'vue'
|
|
46
|
+
? upperFirst(camelCase(fileName))
|
|
47
|
+
: camelCase(fileName)
|
|
48
|
+
|
|
49
|
+
return `${basePath}/${filePrefix}${camelName}.${fileExtension}`
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const { data: commits } = await useLazyFetch<Commit[]>('/api/github/commits', {
|
|
53
|
+
key: `commit-changelog-${props.name ?? routeName.value}`,
|
|
54
|
+
query: { path: filePath.value }
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// 格式化提交消息
|
|
58
|
+
const formattedCommits = computed(() => {
|
|
59
|
+
if (!commits.value?.length) return []
|
|
60
|
+
|
|
61
|
+
return commits.value.map((commit) => {
|
|
62
|
+
const shortSha = commit.sha.slice(0, SHA_SHORT_LENGTH)
|
|
63
|
+
const commitLink = `[\`${shortSha}\`](${githubUrl.value}/commit/${commit.sha})`
|
|
64
|
+
|
|
65
|
+
const content = commit.message
|
|
66
|
+
.replace(/\(.*?\)/, '')
|
|
67
|
+
.replace(/#(\d+)/g, `<a href='${githubUrl.value}/issues/$1'>#$1</a>`)
|
|
68
|
+
.replace(/`(.*?)`/g, '<code class="text-xs">$1</code>')
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
sha: commit.sha,
|
|
72
|
+
formatted: `${commitLink} — ${content}`
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<template>
|
|
79
|
+
<div v-if="!formattedCommits.length">
|
|
80
|
+
No recent changes
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div v-else class="flex flex-col gap-1.5 relative">
|
|
84
|
+
<div class="bg-accented w-px h-full absolute left-[11px] z-[-1]" />
|
|
85
|
+
|
|
86
|
+
<div
|
|
87
|
+
v-for="commit of formattedCommits"
|
|
88
|
+
:key="commit.sha"
|
|
89
|
+
class="flex gap-1.5 items-center"
|
|
90
|
+
>
|
|
91
|
+
<div class="bg-accented ring-2 ring-bg size-1.5 mx-[8.5px] rounded-full" />
|
|
92
|
+
<MDC :value="commit.formatted" class="text-sm *:py-0 *:my-0 [&_code]:text-xs" tag="div" />
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</template>
|
|
@@ -5,7 +5,7 @@ import { hash } from 'ohash'
|
|
|
5
5
|
import { useElementSize } from '@vueuse/core'
|
|
6
6
|
import { get, set } from '#ui/utils'
|
|
7
7
|
|
|
8
|
-
const { preview = true, source = true, prettier =
|
|
8
|
+
const { preview = true, source = true, prettier = false, ...props } = defineProps<{
|
|
9
9
|
name: string
|
|
10
10
|
class?: any
|
|
11
11
|
/**
|
package/app/types/index.d.ts
CHANGED
package/modules/config.ts
CHANGED
|
@@ -49,6 +49,9 @@ export default defineNuxtModule({
|
|
|
49
49
|
owner: gitInfo?.owner,
|
|
50
50
|
name: gitInfo?.name,
|
|
51
51
|
url: gitInfo?.url,
|
|
52
|
+
commitPath: 'src',
|
|
53
|
+
suffix: 'vue',
|
|
54
|
+
since: '2025-01-31T04:00:00Z',
|
|
52
55
|
branch: getGitBranch()
|
|
53
56
|
})
|
|
54
57
|
|
|
@@ -65,7 +68,7 @@ export default defineNuxtModule({
|
|
|
65
68
|
'nuxt-og-image',
|
|
66
69
|
'@nuxtjs/plausible',
|
|
67
70
|
'@nuxt/ui',
|
|
68
|
-
new RegExp(`${componentsPath.replace(/[/\\]/g, '[/\\\\]')}/(?!content/(ComponentEmits|ComponentProps|ComponentSlots|ComponentExample)\\.vue$)`)
|
|
71
|
+
new RegExp(`${componentsPath.replace(/[/\\]/g, '[/\\\\]')}/(?!content/(ComponentEmits|ComponentProps|ComponentSlots|ComponentExample|CommitChangelog)\\.vue$)`)
|
|
69
72
|
],
|
|
70
73
|
metaFields: {
|
|
71
74
|
type: false,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@movk/nuxt-docs",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.8",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "An elegant documentation theme for Nuxt, powered by Nuxt UI and Nuxt Content.",
|
|
7
7
|
"author": "YiXuan <mhaibaraai@gmail.com>",
|
|
@@ -30,12 +30,13 @@
|
|
|
30
30
|
"@iconify-json/lucide": "^1.2.75",
|
|
31
31
|
"@iconify-json/simple-icons": "^1.2.60",
|
|
32
32
|
"@iconify-json/vscode-icons": "^1.2.36",
|
|
33
|
-
"@movk/core": "^1.0.
|
|
33
|
+
"@movk/core": "^1.0.2",
|
|
34
34
|
"@nuxt/content": "^3.8.2",
|
|
35
35
|
"@nuxt/image": "^2.0.0",
|
|
36
36
|
"@nuxt/kit": "^4.2.1",
|
|
37
37
|
"@nuxt/ui": "^4.2.1",
|
|
38
38
|
"@nuxtjs/seo": "^3.2.2",
|
|
39
|
+
"@octokit/rest": "^22.0.1",
|
|
39
40
|
"@vueuse/core": "^14.0.0",
|
|
40
41
|
"@vueuse/nuxt": "^14.0.0",
|
|
41
42
|
"defu": "^6.1.4",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Octokit } from '@octokit/rest'
|
|
2
|
+
|
|
3
|
+
export default defineCachedEventHandler(async (event) => {
|
|
4
|
+
if (!process.env.NUXT_GITHUB_TOKEN) {
|
|
5
|
+
return []
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { path } = getQuery(event) as { path: string }
|
|
9
|
+
if (!path) {
|
|
10
|
+
throw createError({
|
|
11
|
+
statusCode: 400,
|
|
12
|
+
statusMessage: 'Path is required'
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { github } = useAppConfig()
|
|
17
|
+
console.log(github)
|
|
18
|
+
const octokit = new Octokit({ auth: process.env.NUXT_GITHUB_TOKEN })
|
|
19
|
+
const commits = await octokit.paginate(octokit.rest.repos.listCommits, {
|
|
20
|
+
owner: github.owner,
|
|
21
|
+
repo: github.name,
|
|
22
|
+
path,
|
|
23
|
+
since: github.since
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
return commits.map(commit => ({
|
|
27
|
+
sha: commit.sha,
|
|
28
|
+
date: commit.commit.author?.date ?? '',
|
|
29
|
+
message: (commit.commit.message?.split('\n')[0] ?? '')
|
|
30
|
+
}))
|
|
31
|
+
}, {
|
|
32
|
+
maxAge: 60 * 60,
|
|
33
|
+
getKey: event => `commits-${getQuery(event).path}`
|
|
34
|
+
})
|