@jet-w/astro-blog 0.2.5 → 0.2.6
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/package.json +1 -1
- package/src/components/blog/Hero.astro +9 -6
- package/src/components/blog/PostCard.astro +4 -8
- package/src/components/home/FeaturedPostsSection.astro +9 -4
- package/src/components/home/QuickNavSection.astro +9 -4
- package/src/components/home/RecentPostsSection.astro +9 -4
- package/src/components/home/StatsSection.astro +9 -3
- package/src/components/layout/Footer.astro +16 -7
- package/src/components/layout/Header.astro +15 -12
- package/src/components/layout/Sidebar.astro +11 -6
- package/src/components/media/Slides.astro +22 -6
- package/src/components/ui/LanguageSwitcher.vue +24 -12
- package/src/components/ui/MobileMenu.vue +20 -3
- package/src/layouts/BaseLayout.astro +14 -7
- package/src/layouts/PageLayout.astro +9 -3
- package/src/layouts/SlidesLayout.astro +34 -16
- package/src/pages/archives/[year]/[month]/page/[page].astro +42 -18
- package/src/pages/archives/[year]/[month].astro +7 -2
- package/src/pages/archives/index.astro +7 -3
- package/src/pages/categories/[category]/page/[page].astro +40 -18
- package/src/pages/categories/[category].astro +7 -2
- package/src/pages/categories/index.astro +7 -3
- package/src/pages/posts/[...slug].astro +7 -3
- package/src/pages/posts/index.astro +7 -3
- package/src/pages/posts/page/[page].astro +7 -2
- package/src/pages/search.astro +9 -3
- package/src/pages/slides/index.astro +7 -3
- package/src/pages/tags/[tag]/page/[page].astro +39 -17
- package/src/pages/tags/[tag].astro +7 -2
- package/src/pages/tags/index.astro +7 -3
- package/src/plugins/rehype-relative-links.mjs +90 -14
- package/templates/default/.claude/ralph-loop.local.md +2 -32
- package/templates/default/Makefile +37 -0
- package/templates/default/astro.config.mjs +7 -3
- package/templates/default/package.prod.json +31 -0
|
@@ -3,6 +3,9 @@ import { getCollection } from 'astro:content';
|
|
|
3
3
|
import PageLayout from '@jet-w/astro-blog/layouts/PageLayout.astro';
|
|
4
4
|
import PostCard from '@jet-w/astro-blog/components/blog/PostCard.astro';
|
|
5
5
|
import Pagination from '@jet-w/astro-blog/components/ui/Pagination.astro';
|
|
6
|
+
import { i18nConfig as virtualI18nConfig } from 'virtual:astro-blog-i18n';
|
|
7
|
+
import { defaultI18nConfig } from '../../../../config/i18n';
|
|
8
|
+
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale, removeBase } from '../../../../utils/i18n';
|
|
6
9
|
|
|
7
10
|
export async function getStaticPaths() {
|
|
8
11
|
const postsPerPage = 10;
|
|
@@ -53,8 +56,23 @@ export async function getStaticPaths() {
|
|
|
53
56
|
const { tagSlug, tagName, page: currentPage, totalPages } = Astro.props;
|
|
54
57
|
const postsPerPage = 10;
|
|
55
58
|
|
|
59
|
+
// Get i18n config
|
|
60
|
+
const i18nConfig = virtualI18nConfig || defaultI18nConfig;
|
|
61
|
+
const base = import.meta.env.BASE_URL;
|
|
62
|
+
|
|
63
|
+
// Remove base URL from current path for locale detection
|
|
64
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
65
|
+
|
|
66
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
67
|
+
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
68
|
+
const ui = localeConfig.ui;
|
|
69
|
+
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
70
|
+
|
|
56
71
|
// 获取所有文章并筛选包含该标签的文章
|
|
57
|
-
const
|
|
72
|
+
const allPostsCollection = await getCollection('posts', ({ data }) => !data.draft);
|
|
73
|
+
|
|
74
|
+
// Filter posts by current locale
|
|
75
|
+
const allPosts = filterPostsByLocale(allPostsCollection, currentLocale, i18nConfig);
|
|
58
76
|
|
|
59
77
|
// 筛选包含该标签的文章
|
|
60
78
|
const filteredPosts = allPosts
|
|
@@ -95,25 +113,26 @@ const relatedTags = Array.from(relatedTagMap.entries())
|
|
|
95
113
|
---
|
|
96
114
|
|
|
97
115
|
<PageLayout
|
|
98
|
-
title={
|
|
99
|
-
description={
|
|
116
|
+
title={`${ui.taggedWith}: ${tagName} - ${ui.page} ${currentPage}`}
|
|
117
|
+
description={`${ui.taggedWith} ${tagName} - ${ui.page} ${currentPage}`}
|
|
100
118
|
showSidebar={true}
|
|
119
|
+
i18nConfig={i18nConfig}
|
|
101
120
|
>
|
|
102
121
|
<!-- 面包屑导航 -->
|
|
103
122
|
<nav class="flex items-center space-x-2 text-sm text-slate-600 dark:text-slate-400 mb-8">
|
|
104
|
-
<a href=
|
|
123
|
+
<a href={`${localePrefix}/`} class="hover:text-primary-500 transition-colors">{ui.home}</a>
|
|
105
124
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
106
125
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
107
126
|
</svg>
|
|
108
|
-
<a href=
|
|
127
|
+
<a href={`${localePrefix}/tags`} class="hover:text-primary-500 transition-colors">{ui.allTags}</a>
|
|
109
128
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
110
129
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
111
130
|
</svg>
|
|
112
|
-
<a href={
|
|
131
|
+
<a href={`${localePrefix}/tags/${tagSlug}`} class="hover:text-primary-500 transition-colors">{tagName}</a>
|
|
113
132
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
114
133
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
115
134
|
</svg>
|
|
116
|
-
<span class="text-slate-900 dark:text-slate-100"
|
|
135
|
+
<span class="text-slate-900 dark:text-slate-100">{ui.page} {currentPage}</span>
|
|
117
136
|
</nav>
|
|
118
137
|
|
|
119
138
|
<!-- 页面头部 -->
|
|
@@ -129,16 +148,16 @@ const relatedTags = Array.from(relatedTagMap.entries())
|
|
|
129
148
|
</h1>
|
|
130
149
|
|
|
131
150
|
<p class="text-xl text-slate-600 dark:text-slate-400 mb-8">
|
|
132
|
-
|
|
151
|
+
{totalPosts} {ui.posts}
|
|
133
152
|
</p>
|
|
134
153
|
|
|
135
154
|
<!-- 标签统计 -->
|
|
136
155
|
<div class="inline-flex items-center space-x-6 text-sm text-slate-500 dark:text-slate-400 bg-slate-50 dark:bg-slate-800 px-6 py-3 rounded-lg">
|
|
137
156
|
<span>#{tagName}</span>
|
|
138
157
|
<span>•</span>
|
|
139
|
-
<span>{totalPosts}
|
|
158
|
+
<span>{totalPosts} {ui.posts}</span>
|
|
140
159
|
<span>•</span>
|
|
141
|
-
<span
|
|
160
|
+
<span>{ui.page} {currentPage} / {totalPages}</span>
|
|
142
161
|
</div>
|
|
143
162
|
</div>
|
|
144
163
|
|
|
@@ -158,6 +177,9 @@ const relatedTags = Array.from(relatedTagMap.entries())
|
|
|
158
177
|
image: post.data.image
|
|
159
178
|
}}
|
|
160
179
|
layout="horizontal"
|
|
180
|
+
localePrefix={localePrefix}
|
|
181
|
+
locale={localeConfig.locale.dateLocale}
|
|
182
|
+
ui={ui}
|
|
161
183
|
/>
|
|
162
184
|
))}
|
|
163
185
|
</div>
|
|
@@ -165,13 +187,13 @@ const relatedTags = Array.from(relatedTagMap.entries())
|
|
|
165
187
|
<div class="text-center py-16">
|
|
166
188
|
<div class="text-6xl mb-4">📝</div>
|
|
167
189
|
<h3 class="text-xl font-semibold text-slate-900 dark:text-slate-100 mb-2">
|
|
168
|
-
|
|
190
|
+
{ui.noPostsFound}
|
|
169
191
|
</h3>
|
|
170
192
|
<p class="text-slate-600 dark:text-slate-400 mb-6">
|
|
171
|
-
|
|
193
|
+
{ui.noPostsFound}
|
|
172
194
|
</p>
|
|
173
|
-
<a href=
|
|
174
|
-
|
|
195
|
+
<a href={`${localePrefix}/tags`} class="btn-secondary">
|
|
196
|
+
{ui.allTags}
|
|
175
197
|
</a>
|
|
176
198
|
</div>
|
|
177
199
|
)}
|
|
@@ -181,7 +203,7 @@ const relatedTags = Array.from(relatedTagMap.entries())
|
|
|
181
203
|
<Pagination
|
|
182
204
|
currentPage={currentPage}
|
|
183
205
|
totalPages={totalPages}
|
|
184
|
-
baseUrl={
|
|
206
|
+
baseUrl={`${localePrefix}/tags/${tagSlug}`}
|
|
185
207
|
/>
|
|
186
208
|
)}
|
|
187
209
|
|
|
@@ -189,12 +211,12 @@ const relatedTags = Array.from(relatedTagMap.entries())
|
|
|
189
211
|
{relatedTags.length > 0 && (
|
|
190
212
|
<section class="mt-16 pt-8 border-t border-slate-200 dark:border-slate-700">
|
|
191
213
|
<h2 class="text-2xl font-bold text-slate-900 dark:text-slate-100 mb-6">
|
|
192
|
-
|
|
214
|
+
{ui.popularTags}
|
|
193
215
|
</h2>
|
|
194
216
|
<div class="flex flex-wrap gap-3">
|
|
195
217
|
{relatedTags.map((relatedTag) => (
|
|
196
218
|
<a
|
|
197
|
-
href={
|
|
219
|
+
href={`${localePrefix}/tags/${relatedTag.slug}`}
|
|
198
220
|
class="inline-flex items-center px-4 py-2 bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-600 rounded-lg hover:border-primary-300 dark:hover:border-primary-600 hover:shadow-md transition-all duration-200 group"
|
|
199
221
|
>
|
|
200
222
|
<span class="font-medium text-slate-900 dark:text-slate-100 group-hover:text-primary-500 transition-colors">
|
|
@@ -35,10 +35,15 @@ const { tagSlug, tagName, tagCount } = Astro.props;
|
|
|
35
35
|
|
|
36
36
|
// Get i18n config
|
|
37
37
|
const i18nConfig = virtualI18nConfig || defaultI18nConfig;
|
|
38
|
-
const
|
|
38
|
+
const base = import.meta.env.BASE_URL;
|
|
39
|
+
|
|
40
|
+
// Remove base URL from current path for locale detection
|
|
41
|
+
const { removeBase } = await import('../../utils/i18n');
|
|
42
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
43
|
+
|
|
44
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
39
45
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
40
46
|
const ui = localeConfig.ui;
|
|
41
|
-
const base = import.meta.env.BASE_URL;
|
|
42
47
|
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
43
48
|
|
|
44
49
|
// 获取所有文章并筛选包含该标签的文章
|
|
@@ -4,14 +4,18 @@ import PageLayout from '@jet-w/astro-blog/layouts/PageLayout.astro';
|
|
|
4
4
|
import TagCloud from '@jet-w/astro-blog/components/blog/TagCloud.astro';
|
|
5
5
|
import { i18nConfig as virtualI18nConfig } from 'virtual:astro-blog-i18n';
|
|
6
6
|
import { defaultI18nConfig } from '../../config/i18n';
|
|
7
|
-
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale } from '../../utils/i18n';
|
|
7
|
+
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale, removeBase } from '../../utils/i18n';
|
|
8
8
|
|
|
9
9
|
// Get i18n config
|
|
10
10
|
const i18nConfig = virtualI18nConfig || defaultI18nConfig;
|
|
11
|
-
const
|
|
11
|
+
const base = import.meta.env.BASE_URL;
|
|
12
|
+
|
|
13
|
+
// Remove base URL from current path for locale detection
|
|
14
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
15
|
+
|
|
16
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
12
17
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
13
18
|
const ui = localeConfig.ui;
|
|
14
|
-
const base = import.meta.env.BASE_URL;
|
|
15
19
|
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
16
20
|
|
|
17
21
|
// 从文章集合动态获取所有标签
|
|
@@ -1,10 +1,63 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Rehype 插件:修复 Markdown
|
|
3
|
-
*
|
|
2
|
+
* Rehype 插件:修复 Markdown 中的相对链接和图片链接
|
|
3
|
+
* 将相对链接转换为正确的绝对路径,支持 base URL
|
|
4
|
+
* 同时处理绝对路径链接,添加 base URL 前缀
|
|
4
5
|
*/
|
|
5
6
|
import { visit } from 'unist-util-visit';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Helper function to check if a path is a relative link
|
|
10
|
+
* @param {string} path - The path to check
|
|
11
|
+
* @returns {boolean} - True if the path is relative
|
|
12
|
+
*/
|
|
13
|
+
function isRelativePath(path) {
|
|
14
|
+
return (
|
|
15
|
+
path.startsWith('./') ||
|
|
16
|
+
path.startsWith('../') ||
|
|
17
|
+
(!path.startsWith('/') &&
|
|
18
|
+
!path.startsWith('#') &&
|
|
19
|
+
!path.startsWith('http://') &&
|
|
20
|
+
!path.startsWith('https://') &&
|
|
21
|
+
!path.startsWith('mailto:') &&
|
|
22
|
+
!path.startsWith('data:'))
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Helper function to check if a path is an internal absolute path
|
|
28
|
+
* (starts with / but not an external URL or special protocol)
|
|
29
|
+
* @param {string} path - The path to check
|
|
30
|
+
* @returns {boolean} - True if the path is an internal absolute path
|
|
31
|
+
*/
|
|
32
|
+
function isInternalAbsolutePath(path) {
|
|
33
|
+
return (
|
|
34
|
+
path.startsWith('/') &&
|
|
35
|
+
!path.startsWith('//') // Exclude protocol-relative URLs like //example.com
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Helper function to normalize the base URL
|
|
41
|
+
* @param {string} base - The base URL
|
|
42
|
+
* @returns {string} - Normalized base URL (with leading slash, without trailing slash)
|
|
43
|
+
*/
|
|
44
|
+
function normalizeBase(base) {
|
|
45
|
+
if (!base || base === '/') return '';
|
|
46
|
+
// Ensure leading slash, remove trailing slash
|
|
47
|
+
let normalized = base.startsWith('/') ? base : `/${base}`;
|
|
48
|
+
normalized = normalized.endsWith('/') ? normalized.slice(0, -1) : normalized;
|
|
49
|
+
return normalized;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Rehype plugin to fix relative links in Markdown
|
|
54
|
+
* @param {Object} options - Plugin options
|
|
55
|
+
* @param {string} options.base - The base URL path (e.g., '/blog')
|
|
56
|
+
* @returns {Function} - The plugin function
|
|
57
|
+
*/
|
|
7
58
|
export function rehypeRelativeLinks(options = {}) {
|
|
59
|
+
const base = normalizeBase(options.base || process.env.BASE_PATH || '');
|
|
60
|
+
|
|
8
61
|
return (tree, file) => {
|
|
9
62
|
// 获取当前文件的路径信息
|
|
10
63
|
const filePath = file.history[0] || '';
|
|
@@ -12,28 +65,51 @@ export function rehypeRelativeLinks(options = {}) {
|
|
|
12
65
|
// 从文件路径中提取目录信息
|
|
13
66
|
// 例如:/path/to/content/posts/blog_docs/README.md -> blog_docs
|
|
14
67
|
const match = filePath.match(/content\/posts\/(.+?)\/[^/]+\.(md|mdx)$/i);
|
|
15
|
-
if (!match) return;
|
|
16
68
|
|
|
17
|
-
|
|
69
|
+
// dirPath 用于相对链接的解析
|
|
70
|
+
const dirPath = match ? match[1] : ''; // 例如:blog_docs 或 tech/subfolder
|
|
18
71
|
|
|
19
72
|
visit(tree, 'element', (node) => {
|
|
73
|
+
// Handle anchor links
|
|
20
74
|
if (node.tagName === 'a' && node.properties?.href) {
|
|
21
75
|
const href = node.properties.href;
|
|
22
76
|
|
|
23
|
-
|
|
24
|
-
if (href.startsWith('./') ||
|
|
25
|
-
(!href.startsWith('/') &&
|
|
26
|
-
!href.startsWith('#') &&
|
|
27
|
-
!href.startsWith('http://') &&
|
|
28
|
-
!href.startsWith('https://') &&
|
|
29
|
-
!href.startsWith('mailto:'))) {
|
|
30
|
-
|
|
77
|
+
if (isRelativePath(href) && dirPath) {
|
|
31
78
|
// 移除 ./ 前缀
|
|
32
79
|
const cleanHref = href.replace(/^\.\//, '');
|
|
33
80
|
|
|
34
|
-
//
|
|
35
|
-
const newHref =
|
|
81
|
+
// 构建新的绝对路径(包含 base URL)
|
|
82
|
+
const newHref = `${base}/posts/${dirPath}/${cleanHref}`;
|
|
36
83
|
node.properties.href = newHref;
|
|
84
|
+
} else if (isInternalAbsolutePath(href) && base) {
|
|
85
|
+
// 处理内部绝对路径:添加 base URL 前缀
|
|
86
|
+
// 例如:/posts/xxx -> /blog/posts/xxx
|
|
87
|
+
// 避免重复添加 base(如果已经包含)
|
|
88
|
+
if (!href.startsWith(base + '/') && href !== base) {
|
|
89
|
+
node.properties.href = base + href;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Handle image links
|
|
95
|
+
if (node.tagName === 'img' && node.properties?.src) {
|
|
96
|
+
const src = node.properties.src;
|
|
97
|
+
|
|
98
|
+
if (isRelativePath(src) && dirPath) {
|
|
99
|
+
// 移除 ./ 前缀
|
|
100
|
+
const cleanSrc = src.replace(/^\.\//, '');
|
|
101
|
+
|
|
102
|
+
// 构建新的绝对路径(包含 base URL)
|
|
103
|
+
// 图片通常相对于当前文档,保持目录结构
|
|
104
|
+
const newSrc = `${base}/posts/${dirPath}/${cleanSrc}`;
|
|
105
|
+
node.properties.src = newSrc;
|
|
106
|
+
} else if (isInternalAbsolutePath(src) && base) {
|
|
107
|
+
// 处理内部绝对路径图片:添加 base URL 前缀
|
|
108
|
+
// 例如:/images/xxx.png -> /blog/images/xxx.png
|
|
109
|
+
// 避免重复添加 base(如果已经包含)
|
|
110
|
+
if (!src.startsWith(base + '/') && src !== base) {
|
|
111
|
+
node.properties.src = base + src;
|
|
112
|
+
}
|
|
37
113
|
}
|
|
38
114
|
}
|
|
39
115
|
});
|
|
@@ -3,37 +3,7 @@ active: true
|
|
|
3
3
|
iteration: 1
|
|
4
4
|
max_iterations: 20
|
|
5
5
|
completion_promise: "DONE"
|
|
6
|
-
started_at: "2026-01-
|
|
6
|
+
started_at: "2026-01-29T23:41:34Z"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
8:27:27 AM [vite] (ssr) Error when evaluating SSR module /home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/astro.config.mjs: Failed to resolve entry for package @jet-w/astro-blog. The package may have incorrect main/module/exports specified in its package.json.
|
|
11
|
-
Plugin: vite:import-analysis
|
|
12
|
-
File: /home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/astro.config.mjs:11:46
|
|
13
|
-
9 |
|
|
14
|
-
10 | // Import plugins and integration from @jet-w/astro-blog
|
|
15
|
-
11 | import { astroBlog, defineI18nConfig } from '@jet-w/astro-blog';
|
|
16
|
-
| ^
|
|
17
|
-
12 | import { remarkProtectCode, rehypeRestoreCode } from '@jet-w/astro-blog/plugins/remark-protect-code.mjs';
|
|
18
|
-
13 | import { remarkContainers } from '@jet-w/astro-blog/plugins/remark-containers.mjs';
|
|
19
|
-
at packageEntryFailure (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:16198:15)
|
|
20
|
-
at resolvePackageEntry (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:16195:3)
|
|
21
|
-
at tryNodeResolve (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:16060:18)
|
|
22
|
-
at ResolveIdContext.resolveId (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:15831:19)
|
|
23
|
-
at EnvironmentPluginContainer.resolveId (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:42242:17)
|
|
24
|
-
at async TransformPluginContext.resolve (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:42449:15)
|
|
25
|
-
at async normalizeUrl (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:40492:26)
|
|
26
|
-
at async file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:40623:37
|
|
27
|
-
at async Promise.all (index 8)
|
|
28
|
-
at async TransformPluginContext.transform (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:40550:7)
|
|
29
|
-
[astro] Unable to load your Astro config
|
|
30
|
-
Failed to resolve entry for package @jet-w/astro-blog. The package may have incorrect main/module/exports specified in its package.json.
|
|
31
|
-
Location:
|
|
32
|
-
/home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/astro.config.mjs:11:46
|
|
33
|
-
Stack trace:
|
|
34
|
-
at packageEntryFailure (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:16198:15)
|
|
35
|
-
at tryNodeResolve (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:16060:18)
|
|
36
|
-
at EnvironmentPluginContainer.resolveId (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:42242:17)
|
|
37
|
-
at async normalizeUrl (file:///home/runner/work/jet-w.astro-blog/jet-w.astro-blog/templates/default/node_modules/vite/dist/node/chunks/dep-D4NMHUTW.js:40492:26)
|
|
38
|
-
at async Promise.all (index 8)
|
|
39
|
-
Error: Process completed with exit code 1.
|
|
9
|
+
When the base url was set up, the hyper link in markdown, such as [/xxx/fse](text) and image link cannot change accordingly, please help to check similar link at the same time. please help to fix it
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
.PHONY: dev prod install clean help
|
|
2
|
+
|
|
3
|
+
# Default target
|
|
4
|
+
help:
|
|
5
|
+
@echo "Usage:"
|
|
6
|
+
@echo " make dev - Switch to development mode (uses local @jet-w/astro-blog)"
|
|
7
|
+
@echo " make prod - Switch to production mode (uses npm package @jet-w/astro-blog)"
|
|
8
|
+
@echo " make install - Run npm install after switching modes"
|
|
9
|
+
@echo " make clean - Remove node_modules and package-lock.json"
|
|
10
|
+
|
|
11
|
+
# Switch to development mode (local package)
|
|
12
|
+
dev:
|
|
13
|
+
@echo "Switching to development mode..."
|
|
14
|
+
@cp package.dev.json package.json
|
|
15
|
+
@echo "Done! Run 'make install' or 'npm install' to install dependencies."
|
|
16
|
+
|
|
17
|
+
# Switch to production mode (npm package)
|
|
18
|
+
prod:
|
|
19
|
+
@echo "Switching to production mode..."
|
|
20
|
+
@cp package.prod.json package.json
|
|
21
|
+
@echo "Done! Run 'make install' or 'npm install' to install dependencies."
|
|
22
|
+
|
|
23
|
+
# Install dependencies
|
|
24
|
+
install:
|
|
25
|
+
npm install
|
|
26
|
+
|
|
27
|
+
# Clean node_modules and package-lock.json
|
|
28
|
+
clean:
|
|
29
|
+
@echo "Cleaning..."
|
|
30
|
+
@rm -rf node_modules package-lock.json
|
|
31
|
+
@echo "Done!"
|
|
32
|
+
|
|
33
|
+
# Switch to dev and install
|
|
34
|
+
dev-install: dev install
|
|
35
|
+
|
|
36
|
+
# Switch to prod and install
|
|
37
|
+
prod-install: prod install
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineConfig } from 'astro/config';
|
|
2
|
+
import { loadEnv } from 'vite';
|
|
2
3
|
import vue from '@astrojs/vue';
|
|
3
4
|
import tailwind from '@astrojs/tailwind';
|
|
4
5
|
import mdx from '@astrojs/mdx';
|
|
@@ -7,6 +8,9 @@ import remarkMath from 'remark-math';
|
|
|
7
8
|
import rehypeKatex from 'rehype-katex';
|
|
8
9
|
import rehypeRaw from 'rehype-raw';
|
|
9
10
|
|
|
11
|
+
// Load environment variables from .env file
|
|
12
|
+
const { SITE_URL, BASE_PATH } = loadEnv(process.env.NODE_ENV || 'production', process.cwd(), '');
|
|
13
|
+
|
|
10
14
|
// Import plugins and integration from @jet-w/astro-blog
|
|
11
15
|
import { astroBlog, defineI18nConfig } from '@jet-w/astro-blog';
|
|
12
16
|
import { remarkProtectCode, rehypeRestoreCode } from '@jet-w/astro-blog/plugins/remark-protect-code.mjs';
|
|
@@ -59,7 +63,7 @@ export default defineConfig({
|
|
|
59
63
|
rehypeKatex,
|
|
60
64
|
rehypeCleanContainers,
|
|
61
65
|
rehypeTabs,
|
|
62
|
-
rehypeRelativeLinks,
|
|
66
|
+
[rehypeRelativeLinks, { base: BASE_PATH || process.env.BASE_PATH || '/' }],
|
|
63
67
|
rehypeRestoreCode, // Must run LAST to restore ::: in code blocks
|
|
64
68
|
],
|
|
65
69
|
shikiConfig: {
|
|
@@ -68,8 +72,8 @@ export default defineConfig({
|
|
|
68
72
|
wrap: true
|
|
69
73
|
}
|
|
70
74
|
},
|
|
71
|
-
site: process.env.SITE_URL || 'https://example.com',
|
|
72
|
-
base: process.env.BASE_PATH || '/',
|
|
75
|
+
site: SITE_URL || process.env.SITE_URL || 'https://example.com',
|
|
76
|
+
base: BASE_PATH || process.env.BASE_PATH || '/',
|
|
73
77
|
build: {
|
|
74
78
|
assets: 'assets'
|
|
75
79
|
},
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-astro-blog",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "astro dev",
|
|
7
|
+
"start": "astro dev",
|
|
8
|
+
"build": "astro build",
|
|
9
|
+
"preview": "astro preview",
|
|
10
|
+
"astro": "astro"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@astrojs/mdx": "^4.3.12",
|
|
14
|
+
"@astrojs/rss": "^4.0.14",
|
|
15
|
+
"@astrojs/tailwind": "^5.1.3",
|
|
16
|
+
"@astrojs/vue": "^5.0.6",
|
|
17
|
+
"@jet-w/astro-blog": "^0.2.1",
|
|
18
|
+
"@tailwindcss/typography": "^0.5.15",
|
|
19
|
+
"astro": "^5.14.1",
|
|
20
|
+
"echarts": "^6.0.0",
|
|
21
|
+
"fuse.js": "^7.0.0",
|
|
22
|
+
"mermaid": "^11.12.2",
|
|
23
|
+
"rehype-katex": "^7.0.1",
|
|
24
|
+
"rehype-raw": "^7.0.0",
|
|
25
|
+
"remark-directive": "^4.0.0",
|
|
26
|
+
"remark-math": "^6.0.0",
|
|
27
|
+
"tailwindcss": "^3.4.17",
|
|
28
|
+
"typescript": "^5.7.2",
|
|
29
|
+
"vue": "^3.5.13"
|
|
30
|
+
}
|
|
31
|
+
}
|